NUnit 테스트 실행 순서


110

기본적으로 nunit 테스트는 알파벳순으로 실행됩니다. 실행 순서를 설정하는 방법을 아는 사람이 있습니까? 이에 대한 속성이 있습니까?


7
왜 이렇게 하시겠습니까? 실행 순서에 의존하는 것처럼 들리는데, 이는 나쁜 일입니다. 왜 이것을 원하는지 재고해야합니다. 단위 테스트는 독립적으로 실행되어야하며 다른 테스트와 완전히 독립적이어야합니다. 테스트 냄새 Erratic Tests에 대한 후보를 만드는 것 같습니다 .
RichardOD

이것은 중복 된 것처럼 보이지만 여기에
Johnno Nolan

12
@RichardOD-해야! =해야합니다. 실제로 거의 모든 통합 테스트가 순서대로 실행되기 때문에 실제로는 이벤트가 아닙니다. QA 팀이 테스트 순서를 무작위로 지정하는지 물어보십시오.
tymtam 2013

4
나는 현재 순서가 중요하지 않아도 중요한 것으로 보이는 몇 가지 테스트를 가지고 있습니다. 개인적으로, 나는 내 테스트가 순서에 따라 달라지지 않도록 특별히 테스트 순서를 무작위로 지정하는 방법을 원합니다. 물론, 제가 정말로 원하는 것은 문제를 찾을 때까지 모든 테스트를 무작위 순서로 실행하는 테스트 러너이거나 중지라고 말합니다. 밤새 달리고 아침에도 모든 것이 여전히 녹색이면 의도하지 않은 마지막 부작용을 제거했다고 확신 할 수 있습니다.
Mel

1
여기서 통합 테스트에 대해 이야기하고 있음을 지정하도록 질문이 업데이트 된 경우이 질문은 더 관련성이 있습니다. 적어도 XUnit 테스트 패턴을 읽고 밥 삼촌을 따랐다면 우리 모두는 단위 테스트에 대한 규칙을 알고 있습니다. 하지만 NUnit과 같은 프레임 워크는 통합 테스트를 신속하게 시작하고 실행하는 데에도 정말 유용합니다. 특히 값 비싼 데이터베이스 설정이 포함 된 경우 이러한 프레임 워크가 무작위로되는 것을 원하지는 않습니다.
nrjohnstone

답변:


51

단위 테스트는 각각 독립적으로 실행될 수 있어야합니다. 이 기준을 충족하면 순서는 중요하지 않습니다.

그러나 특정 테스트를 먼저 실행하고 싶은 경우가 있습니다. 일반적인 예는 일부 테스트가 다른 테스트보다 오래 실행되는 지속적 통합 상황입니다. 우리는 데이터베이스를 사용하는 테스트보다 먼저 조롱을 사용하는 테스트를 실행할 수 있도록 category 속성을 사용합니다.

즉, 빠른 테스트를 시작할 때 이것을 넣으십시오.

[Category("QuickTests")]

특정 환경 조건에 의존하는 테스트가있는 경우 테스트 전후에 실행할 메서드를 표시 할 수 있는 TestFixtureSetUpTestFixtureTearDown 속성을 고려하십시오 .


2
@Chris, 나는 이러한 속성을 사용하지 않는 경향이 있습니다. 이것은 흥미로운 블로그 포스트 jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html 입니다. 그래도 카테고리 테스트에 대한 좋은 점.
RichardOD

29
당신은 통합 테스트 ... 실행되도록 NUNIT 프레임 워크를 사용하고자 할 때 순서에 의존 테스트의 또 다른 예이다
바이런 로스

1
@ByronRoss : 나는 그렇게 할 때 테스트를 더 크게 만드는 경향이 있으며, 가능한 한 기존 단위 테스트에 의지하여 적은 수의 테스트를 작성할 수 있습니다. 그러면 각 전체 실행이 개별적으로 실패 할 수 있습니다. 또한 기존 데이터에 의존 하지 않고 기존 데이터와 별도로 살 수 있도록 데이터를 설계하려고합니다 .
Merlyn Morgan-Graham

1
무작위 순서로 테스트를 실행하지 않는 경우, 순서가 맞지 않을 때 실제로 작동하는지 어떻게 확인할 수 있습니까? 당신이 말하는 것은 "당신의 소프트웨어에 버그가 없다면, 테스트는 불필요하다"는 것과 유사합니다.
jforberg

@jforberg : 무작위로 발생하는 오류가있는 경우이를 수정했을 때 어떻게 말합니까?
NeedHack 2014-06-16

175

나는 대부분의 응답자들이 이것이 단위 테스트라고 가정했지만, 질문은 그것들이 있다고 명시하지 않았다는 점을 지적하고 싶습니다.

nUnit은 다양한 테스트 상황에 사용할 수있는 훌륭한 도구입니다. 테스트 순서를 제어하려는 적절한 이유를 알 수 있습니다.

이러한 상황에서 나는 실행 순서를 테스트 이름에 통합해야했습니다. 속성을 사용하여 실행 순서를 지정할 수 있으면 좋을 것입니다.


예를 들어 테스트에 전화를 걸었다는 뜻 001_first_test 002_second_test입니까?
ashes999

예, 맞습니다. 일반적으로 필요한 경우 테스트를 쉽게 삽입 할 수있는 패턴을 사용하므로 010_first_test, 020_second_test 등이 될 수 있습니다.
Les

83
여기에 올바른 대답을 해주셔서 감사합니다. 이것은 구체적인 질문이지만 어쩐지 모호한 현명한 답변이 찬성되고 있습니다. 예, 우리 모두는 단위 테스트가 무엇인지 알고 있지만 문제는 아닙니다.
Egor Pavlikhin 2012-07-05

1
실행 순서가 알파벳 인 것에 의존 해서는 안됩니다 . 많은 테스트 실행기는 여러 스레드 또는 프로세스에서 동시에 테스트를 실행하며 반드시 알파벳 순서는 아닙니다. 예를 들어, NCrunch는 변경 한 코드 (영향을받는 테스트)를 기준으로 테스트의 우선 순위를 지정하고, 마지막으로 실패했는지 여부, 그리고 빠르게 실행되는지 느리게 실행되는지에 따라 우선 순위를 지정합니다. 정의 된 순서 를 원하면 해당 테스트에 대한 메타 러너를 만들고 일반 실행에서 제외하면됩니다.
Abel

3
순서를 지정하는 또 다른 좋은 이유는 나머지 테스트 스위트를 계속하기 전에 먼저 특정 문제를 포착하는 것입니다. 즉, 사용자 생성 테스트가 실패하면이 결과를 찾기 전에 다른 모든 작업을 실행할 필요가 없습니다. 내 다른 테스트에서는 아마도 사용자를 조롱하지만 이것이 실패하는 첫 번째 테스트라는 것이 중요합니다. 특히 테스트 스위트가 클 때 그렇습니다.
Bron Davies

125

NUnit 3.2.0은를 추가했습니다 OrderAttribute.

https://github.com/nunit/docs/wiki/Order-Attribute

예:

public class MyFixture
{
    [Test, Order(1)]
    public void TestA() { ... }


    [Test, Order(2)]
    public void TestB() { ... }

    [Test]
    public void TestC() { ... }
}

5
고맙습니다, 내가 찾던 바로 그 지점에-그리고 토론이 없는데 왜 그것이 좋은지 나쁜지 :)
aknoepfel

1
그런 다음 십진수 대신 정수로 만들므로 테스트를 삽입해야하는 경우 모든 테스트의 번호를 다시 매겨 야합니다.
epitka

그런 식으로 중간 항목을 소개하려면 항상 수백만과 같은 매우 큰 숫자로 시작할 수 있습니다. Imo는 메소드 의존성 트리처럼 우선 순위를 위해 숫자를 사용하는 것보다 순서를 쉽게 정할 수있는 방법이 있어야하지만 각각의 단점 / 장점이 있습니다.
Răzvan Flavius ​​Panda

9
좋은 대답이지만 문서에 따르면 테스트는 이전 테스트가 완료 될 때까지 기다리지 않습니다.
ROX

흥미롭게도 내 경험상 Test 및 Order 속성을 별도로 추가하면 테스트 순서가 보장되지 않습니다.
AT

22

테스트가 특정 순서로 실행되기를 원한다고해서 테스트가 서로 의존한다는 의미는 아닙니다. 저는 현재 TDD 프로젝트를 진행하고 있으며, 좋은 TDDer가되어 모든 것을 조롱 / 스텁했습니다. 테스트 결과가 표시 되는 순서를 알파벳순 대신 주제별로 지정할 수 있다면 더 읽기 쉽습니다. 지금까지 내가 생각할 수있는 유일한 것은 클래스, 네임 스페이스 및 메서드의 클래스 앞에 a_ b_ c_를 추가하는 것입니다. (좋지 않음) [TestOrderAttribute] 속성이 좋을 것이라고 생각합니다. 프레임 워크가 엄격하게 따르는 것은 아니지만이를 달성 할 수있는 힌트입니다.


10

테스트가 질서에 의존하는지 여부에 관계없이 우리 중 일부는 모든 것을 질서 정연한 방식으로 제어하기를 원합니다.

단위 테스트는 일반적으로 복잡한 순서대로 생성됩니다. 그렇다면 복잡성이나 생성 된 순서대로 실행하면 안되는 이유는 무엇입니까?

개인적으로 테스트를 만든 순서대로 실행되는 것을보고 싶습니다. TDD에서 각 연속 테스트는 자연스럽게 더 복잡해지고 실행하는 데 더 많은 시간이 걸립니다. 더 간단한 테스트가 실패의 원인에 대한 더 나은 지표가 될 것이기 때문에 먼저 실패하는 것을보고 싶습니다.

그러나 특히 테스트가 다른 테스트에 대한 종속성이 없는지 테스트하려는 경우 무작위 순서로 실행하는 이점도 확인할 수 있습니다. "중지 될 때까지 무작위로 테스트 실행"옵션을 테스트 러너에 추가하는 것은 어떻습니까?


9

나는 상당히 복잡한 웹 사이트에서 Selenium으로 테스트하고 있으며 전체 테스트 스위트는 30 분 이상 실행할 수 있으며 아직 전체 애플리케이션을 다루지는 않습니다. 각 테스트에 대해 이전 양식을 모두 올바르게 작성해야한다면 전체 테스트에 약간의 시간이 아니라 많은 시간이 추가됩니다. 테스트를 실행하는 데 너무 많은 오버 헤드가 있으면 사람들은 필요한만큼 자주 실행하지 않을 것입니다.

그래서 나는 그것들을 순서대로 정리하고 이전 테스트에 의존하여 텍스트 상자를 완성했습니다. 전제 조건이 유효하지 않을 때 Assert.Ignore ()를 사용하지만 순서대로 실행해야합니다.


1
전적으로. 나는 여기서 같은 배에 있습니다.
Sleeper Smith

나도! 정확히 내가이 질문에 착수 한 이유!
Niklas Wulff

@NiklasRingdahl nunit과 함께 Visual Studio를 사용하는 경우 nunit을 덤프하고 MS 테스트를 사용합니다. 당신은 당신이 그 (것)들을 실행 원하는 순서대로 테스트 케이스를 준비하는 비주얼 스튜디오의 orderedtest 파일을 이용할 수있다
라훌 Lodha을

@RahulLodha 감사합니다! 나는 그것을 조사 할 것이다.
Niklas Wulff

9

이전 답변이 정말 마음에 듭니다.

주문 범위를 설정하는 속성을 사용할 수 있도록 약간 변경했습니다.

namespace SmiMobile.Web.Selenium.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using NUnit.Framework;

    public class OrderedTestAttribute : Attribute
    {
        public int Order { get; set; }


        public OrderedTestAttribute(int order)
        {
            Order = order;
        }
    }

    public class TestStructure
    {
        public Action Test;
    }

    class Int
    {
        public int I;
    }

    [TestFixture]
    public class ControllingTestOrder
    {
        private static readonly Int MyInt = new Int();

        [TestFixtureSetUp]
        public void SetUp()
        {
            MyInt.I = 0;
        }

        [OrderedTest(0)]
        public void Test0()
        {
            Console.WriteLine("This is test zero");
            Assert.That(MyInt.I, Is.EqualTo(0));
        }

        [OrderedTest(2)]
        public void ATest0()
        {
            Console.WriteLine("This is test two");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
        }


        [OrderedTest(1)]
        public void BTest0()
        {
            Console.WriteLine("This is test one");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
        }

        [OrderedTest(3)]
        public void AAA()
        {
            Console.WriteLine("This is test three");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
        }


        [TestCaseSource(sourceName: "TestSource")]
        public void MyTest(TestStructure test)
        {
            test.Test();
        }

        public IEnumerable<TestCaseData> TestSource
        {
            get
            {
                var assembly =Assembly.GetExecutingAssembly();
                Dictionary<int, List<MethodInfo>> methods = assembly
                    .GetTypes()
                    .SelectMany(x => x.GetMethods())
                    .Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any())
                    .GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order)
                    .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

                foreach (var order in methods.Keys.OrderBy(x => x))
                {
                    foreach (var methodInfo in methods[order])
                    {
                        MethodInfo info = methodInfo;
                        yield return new TestCaseData(
                            new TestStructure
                                {
                                    Test = () =>
                                        {
                                            object classInstance = Activator.CreateInstance(info.DeclaringType, null);
                                            info.Invoke(classInstance, null);
                                        }
                                }).SetName(methodInfo.Name);
                    }
                }

            }
        }
    }
}

이 접근 방식이 훌륭하다고 생각합니다. 리플렉션 코드는 속성이있는 모든 메서드를 가져올 것이므로 특정 테스트 픽스처를 실행하려는 경우 생각보다 더 많이 실행된다는 사실에 놀랄 수 있습니다. 원하는 동작이 아닌 경우 LINQ 쿼리를 쉽게 수정할 수 있습니다. 자세한 내용은 내 답변의 링크를 참조하십시오.
Chrispy 2014

OrderedTestNUnit 3에서는 더 이상 지원되지 않습니다.
Conrad

7

나는 이것이 상대적으로 오래된 게시물이라는 것을 알고 있지만 여기에 테스트 이름을 어색하게 만들지 않고 테스트를 유지하는 또 다른 방법이 있습니다. TestCaseSource 특성을 사용하고 전달하는 개체에 대리자 (Action)가 있으면 순서를 완전히 제어 할 수있을뿐만 아니라 테스트 이름을 지정할 수도 있습니다.

문서에 따르면 테스트 소스에서 반환 된 컬렉션의 항목은 항상 나열된 순서대로 실행되기 때문에 작동합니다.

다음은 내일 발표 할 프레젠테이션의 데모입니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace NUnitTest
{
    public class TestStructure
    {
        public Action Test;
    }

    class Int
    {
        public int I;
    }

    [TestFixture]
    public class ControllingTestOrder
    {
        private static readonly Int MyInt= new Int();

        [TestFixtureSetUp]
        public void SetUp()
        {
            MyInt.I = 0;
        }

        [TestCaseSource(sourceName: "TestSource")]
        public void MyTest(TestStructure test)
        {
            test.Test();
        }

        public IEnumerable<TestCaseData> TestSource
        {
            get
            {
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test one");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
                        }
                    }).SetName(@"Test One");
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test two");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
                        }
                    }).SetName(@"Test Two");
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test three");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
                        }
                    }).SetName(@"Test Three");
            }
        }
    }
}

선형 적으로 실행하기에는 너무 많은 시간이 소요되는 병렬 통합 테스트에이 패턴을 사용합니다. 모든 테스트는 하나의 유형에 있으므로 Action <T in>을 사용하고 모든 Action에는 "ShouldBeFoo"가 무엇인지 알려주는 키가 있습니다. 이렇게하면 테스트가 수행하는 작업이 테스트 이름에 표시되고 TestCaseSource를 필터링하여 여러 유형의 테스트를 함께 그룹화 할 수 있습니다. 아이러니하게도, 나는 실행 순서에 관심이 없지만 그것이 효과가있을 것이라는 데 동의합니다.
Novaterata 2014 년

TestCaseSource주문 테스트를 실행하는 방법 으로을 사용하는 것은 천재적인 일입니다. 잘 했어. 이 접근 방식을 아래 방법과 함께 사용하고 사용하기 쉽도록 몇 가지 추가 수정 사항을 추가했습니다. 추가 정보는 내 답변의 링크를 참조하십시오.하지만 근본적인 아이디어는이 훌륭한 답변에서 나왔습니다!
Chrispy

슬프게도 NUnit 3에서는의 소스 TestCaseSource가 정적이어야하므로 패턴을 사용할 수 없습니다. Bummer.
Conrad

@Conrad. 나는 방법을 정적으로 만드는 것이 어떤 차이를 만드는지 알지 못한다. 테스트는 여전히 순서대로 반환됩니다.
Dave Bush

정적이어야하는 메서드는 아닙니다. 소스 (변수 또는 속성)는 TestCaseSourceNUnit 3의 정적 개체 여야합니다. 그렇지 않으면 테스트가 실행되지 않습니다. 그리고 정적 개체 내에 동적 개체를 만들 수 없습니다. 그것이 v. 3에서 작동하지 않는 이유입니다.
Conrad

5

저는 NUnit 프레임 워크를 사용하여 실행되는 C #으로 작성된 Selenium WebDriver 종단 간 UI 테스트 케이스를 사용하고 있습니다. (단위 케이스가 아닙니다)

다른 테스트에서는 일부 데이터를 전제 조건으로 추가해야하므로 이러한 UI 테스트는 실행 순서에 따라 달라집니다. (모든 테스트에서 단계를 수행하는 것은 불가능합니다)

이제 10 번째 테스트 케이스를 추가 한 후 NUnit이 다음 순서로 실행하려고합니다. Test_1 Test_10 Test_2 Test_3 ..

그래서 지금은 테스트 케이스 이름을 너무 알파벳순으로 만들어야한다고 생각하지만 실행 순서를 제어하는이 작은 기능을 NUnit에 추가하면 좋을 것입니다.


9
Arran에 동의하지 않음 : UI 테스트는 본질적으로 작은 단계의 시퀀스입니다. 각 단계는 테스트가되어야합니다 (이유-실패하면 어느 단계인지 알아야합니다). 시퀀스는 독립적 일 수 있지만 시퀀스 내에서 주문이 중요하며 실패시 중지해야합니다.
Zasz

3

일반적으로 단위 테스트는 독립적이어야하지만 필요한 경우 다음과 같이 사전 순으로 메서드 이름을 지정할 수 있습니다.

[Test]
public void Add_Users(){}

[Test]
public void Add_UsersB(){}

[Test]
public void Process_Users(){}

아니면 할 수 있습니다 ..

        private void Add_Users(){}

        private void Add_UsersB(){}

        [Test]
        public void Process_Users()
        {
           Add_Users();
           Add_UsersB();
           // more code
        }

2
지금을 제외하고는 이름을 알파벳순으로 만들어야하는데 이는 끔찍한 해결책입니다. :(

@ user166390-끔찍하지 않습니다. 작동하며 NUnit의 문서화 된 동작에 따라 다릅니다.
tymtam 2013

➕1 충분한 나를 위해, 훨씬 더 쉽게 당신과 함께 테스트를 시작하는 경우 a_ b_ t1_, t2_후행 문자를 그리워 대신 또는 쉬운에 의존
크리스 Marisic

3

테스트 주문 메커니즘을 사용하는 데에는 매우 좋은 이유가 있습니다. 내 테스트의 대부분은 설정 / 해체와 같은 좋은 방법을 사용합니다. 다른 것들은 방대한 양의 데이터 설정을 필요로하므로 다양한 기능을 테스트하는 데 사용할 수 있습니다. 지금까지 이러한 (Selenium Webdriver) 통합 테스트를 처리하기 위해 대규모 테스트를 사용했습니다. 하지만 https://github.com/nunit/docs/wiki/Order-Attribute 에 대한 위의 제안 된 게시물 이 많은 장점이 있다고 생각합니다 . 다음은 주문이 매우 중요한 이유에 대한 예입니다.

  • Selenium Webdriver를 사용하여 보고서 다운로드를위한 테스트 실행
  • 보고서 상태 (다운로드 가능 여부)는 10 분 동안 캐시됩니다.
  • 즉, 모든 테스트 전에 보고서 상태를 재설정 한 다음 최대 10 분 동안 기다려야합니다. 상태가 변경된 것으로 확인되기 다음 보고서가 올바르게 다운로드되는지 확인해야합니다.
  • 보고서는 복잡성으로 인해 테스트 프레임 워크 내에서 모의 ​​또는 기타 메커니즘을 통해 실용적 /시의 적절하게 생성 될 수 없습니다.

이 10 분의 대기 시간은 테스트 스위트의 속도를 늦 춥니 다. 여러 테스트에서 유사한 캐싱 지연을 곱하면 많은 시간이 소요됩니다. 테스트 순서 지정을 통해 테스트 스위트의 시작 부분에서 바로 "테스트"로 데이터 설정을 수행 할 수 있으며, 테스트 실행이 끝날 때 실행되는 캐시에 의존하는 테스트가 실행됩니다.


2

이 질문은 지금은 정말 오래되었지만 검색을 통해이 질문에 도달 할 수있는 사람들을 위해 user3275462 및 PvtVandals / Rico의 훌륭한 답변을 가져 와서 일부 업데이트와 함께 GitHub 저장소에 추가했습니다 . 관련 블로그 게시물 도 작성 했습니다. 더 많은 정보를 볼 수있는 몇 가지 추가 정보와 함께 을 .

이것이 여러분 모두에게 도움이되기를 바랍니다. 또한, 통합 테스트 또는 기타 종단 간 테스트를 실제 단위 테스트와 구별하기 위해 Category 속성을 자주 사용합니다. 다른 사람들은 단위 테스트에 순서 종속성이 없어야한다고 지적했지만 다른 테스트 유형은 종종 그렇기 때문에 원하는 테스트 범주 만 실행하고 이러한 엔드-투-엔드 테스트를 주문하는 좋은 방법을 제공합니다.


내가 가진 문제에 대해 도와 줄 수 있습니까? 링크는 다음과 같습니다. stackoverflow.com/questions/31281395/...
모건 소렌

1

NUnit 커뮤니티가 아무 것도 생각해 내지 못한 것 같아서 제가 직접 이런 것을 만들어 보았습니다.

저는 현재 오픈 소스 라이브러리를 개발 중입니다. NUnit으로 테스트를 주문할 수 를 입니다. 테스트 픽스처를 주문하고 "주문 된 테스트 사양"을 주문할 수 있습니다.

라이브러리는 다음 기능을 제공합니다.

  • 복잡한 테스트 순서 계층 구조 구축
  • 주문 테스트가 실패하면 후속 테스트 건너 뛰기
  • 정수 순서 대신 종속성에 따라 테스트 메서드를 정렬하십시오.
  • 정렬되지 않은 테스트로 나란히 사용을 지원합니다. 순서가 지정되지 않은 테스트가 먼저 실행됩니다.

라이브러리는 실제로 MSTest가 .orderedtest파일로 테스트 순서를 지정하는 방법에서 영감을 받았습니다 . 아래의 예를보십시오.

[OrderedTestFixture]
public sealed class MyOrderedTestFixture : TestOrderingSpecification {
    protected override void DefineTestOrdering() {
        TestFixture<Fixture1>();

        OrderedTestSpecification<MyOtherOrderedTestFixture>();

        TestFixture<Fixture2>();
        TestFixture<Fixture3>();
    }

    protected override bool ContinueOnError => false; // Or true, if you want to continue even if a child test fails
}

1

을 사용하는 경우 [TestCase]인수TestName 는 테스트의 이름을 제공합니다.

지정하지 않으면 제공된 메소드 이름과 인수를 기반으로 이름이 생성됩니다.

아래와 같이 테스트 실행 순서를 제어 할 수 있습니다.

                    [Test]
            [TestCase("value1", TestName = "ExpressionTest_1")]
            [TestCase("value2", TestName = "ExpressionTest_2")]
            [TestCase("value3", TestName = "ExpressionTest_3")]
            public void ExpressionTest(string  v)
            {
                //do your stuff
            }

여기에서는 메서드 이름을 사용했습니다. "ExpressionTest" 에서는 번호와 함께 접미사를 사용했습니다.

알파벳순으로 정렬 된 이름을 사용할 수 있습니다. TestCase 속성을 참조하십시오.


0

테스트 프레임 워크가 실행할 테스트를 선택하는 순서에 의존해서는 안됩니다.테스트는 격리되고 독립적이어야합니다. 그들은 그들을 위해 무대를 설정하거나 그 후에 정리하는 다른 테스트에 의존해서는 안됩니다. 또한 테스트 실행 순서에 관계없이 동일한 결과를 생성해야합니다 (주어진 SUT 스냅 샷에 대해).

나는 약간의 인터넷 검색을했다. 평소와 같이 일부 사람들은 기본 테스트 가능성 / 설계 문제를 해결하는 대신 은밀한 트릭에 의존했습니다.

  • 테스트가 실행되는 데 '필요한'순서대로 나타나도록 사전 순으로 테스트 이름을 지정합니다. 그러나 NUnit은 이후 릴리스에서이 동작을 변경하도록 선택할 수 있으며 그러면 테스트가 중단됩니다. 현재 NUnit 바이너리를 소스 제어에 더 잘 확인합니다.
  • VS ( '민첩한 도구'로 잘못된 동작을 장려하는 IMHO)는 MS 테스트 프레임 워크에서 "순서화 된 테스트"라는 것을 가지고 있습니다. 시간을 낭비하지 않았지만 같은 청중을 겨냥한 것 같습니다

참조 : 좋은 테스트의 특성


특히 통합 및 승인 테스트에서 장기 실행 테스트 전에 실행 속도를 높이고 싶은 경우가 있습니다. 예를 들어 블로깅 앱에서 로그인을 먼저 테스트합니다. 해당 기능이 작동하지 않으면 게시도 작동하지 않으므로 해당 테스트를 실행할 필요가 없습니다 (수동으로 실행기를 중지 할 수 있음). 그러나 테스트를 계속 실행하려고하면 더 많은 시간이 소요됩니다.
Marcel Valdez Orozco

@MarcelValdezOrozco-다른 물리적 dll을 통해 또는 태그 / 카테고리를 사용하여 테스트를 분할하여 목표를 달성 할 수 있습니다. 빌드 스크립트를 만들어 dll / 카테고리를 순서대로 실행할 수 있습니다. 일반적으로 테스트 순서를 허용하면 일반적으로 인접한 테스트에 대한 종속성을 개발하는 결합 테스트로 이어집니다 (물론 시간이 지남에 따라). AFAIR는 NUnit의 다음 큰 릴리스에서 무작위 등 다른 테스트 순서를 지원할 예정입니다.
Gishu

2
동일한 유형의 테스트 (예 : 수용 테스트)를 더 분할하는 것은 의미가 없으며이를 다른 DLL로 분리하면 소스 코드, 빌드 스크립트, 테스트 스크립트, 프로젝트 구조 등 모든 곳에서 불필요하게 복잡성이 증가합니다. 테스트.
Marcel Valdez Orozco 2012 년

방출 (기본적으로 모든 라이브러리 모의)은 순서가 중요한 이유입니다. 앱 도메인을 언로드 할 수 없으며 nunit 러너 (어셈블리에서 모든 테스트를 실행하는 경우)는 최소한 해당 '수정'에서 모든 테스트에 대해 해당 도메인을 유지합니다. 하나의 테스트가 무언가를 테스트하기 위해 유형을 생성하고 다른 테스트가 생성 된 유형과 충돌하는 경우 순서 때문에 잘못된 테스트가 아닙니다. 논리적으로 격리되어 있습니다. nUnit이 각 '테스트'자체간에 적절한 격리를 제공하지 않기 때문입니다.
Kelly Elton

6
이것은 꽤 애용하는 대답이며 실제로는 단위 테스트에만 적용되고 실용적인 것을 완전히 무시하기 때문에 재미있게 만듭니다.
tymtam 2013

0

TestCaseSource키 를 사용 하는 경우 override string ToString방법은 작동 방식 :

TestCase 클래스가 있다고 가정하십시오.

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }
}

그리고 TestCases 목록 :

private static IEnumerable<TestCase> TestSource()
{
    return new List<TestCase>
    {
        new TestCase()
        {
           Name = "Test 1",
           Input = 2,
           Expected = 4
        },
        new TestCase()
        {
            Name = "Test 2",
            Input = 4,
            Expected = 16
        },
        new TestCase()
        {
            Name = "Test 3",
            Input = 10,
            Expected = 100
        }
    };
}

이제 Test 메서드와 함께 사용하고 어떤 일이 발생하는지 확인하십시오.

[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
    var x = Power(testCase.Input);
    x.ShouldBe(testCase.Expected);
}

이것은 순서대로 테스트되지 않으며 출력은 다음과 같습니다.

여기에 이미지 설명 입력

따라서 override string ToString다음과 같이 클래스에 추가 하면

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

결과가 변경되고 다음과 같은 테스트의 순서와 이름이 표시됩니다.

여기에 이미지 설명 입력

노트 :

  1. 이것은 테스트에서 이름과 순서를 얻는 방법을 설명하는 예일뿐입니다. 순서는 숫자 / 알파벳순으로 처리되므로 테스트가 10 개 이상이면 테스트 01, 테스트 02 .... 테스트 10, 테스트 11 등을 만드는 것이 좋습니다. 당신은 Test 1을 만들고 어느 시점에서 Test 10을 순서보다 Test 1, Test 10, Test 2 .. 등등이 될 것입니다.
  2. 입력 및 예상은 모든 유형, 문자열, 객체 또는 사용자 정의 클래스 일 수 있습니다.
  3. 질서 외에도 여기서 좋은 점은 더 중요한 테스트 이름을 볼 수 있다는 것입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.