2014-06-09 1 views
5

테스트 스위트가있는 여러 클래스가 있습니다.테스트를 통해 각 클래스를 종료 한 후 ClassCleanup (MSTest)을 실행하는 방법은 무엇입니까?

각 테스트 클래스는 ClassInitialize에서 시작하여 ClassCleanup에 의해 완료됩니다. 제 문제는 ClassCleanup이 각 클래스의 끝에서 호출되지 않는다는 것입니다.이 클래스는 세 클래스의 모든 테스트 후에 만 ​​호출됩니다. 이 문제를 해결할 수 있습니까? 감사!

[ClassInitialize] 
public static void SetUpBrowser(TestContext context) 
{ 
    pageObjectBase.SetBrowser("chrome"); 
    pagesManager.GetPageObjectBase(); 
} 

[TestMethod] 
public void FindCriticalBug() 
{ 
    bla-bla-bla(); 
} 

[ClassCleanup] 
public static void CloseBrowser() 
{ 
    pageObjectBase.Stop(); 
    pagesManager.GeneralClearing(); 
} 

답변

1

정상적인 unittest는 '순서가 없습니다'즉 임의의 순서로 실행될 수 있음을 의미합니다. 아마도 주문 테스트와 같은 것을 찾고있을 것입니다 (dominic에 대한 귀하의 의견을보십시오). 주문 테스트는 특별한 단위 테스트 프로젝트입니다. 정렬 된 테스트를 실행할 때 테스트는 구성 방법을 실행하고 완료되면 테스트 클래스를 분리합니다. 단위 테스트가 순서대로 실행되어야한다면, 테스트가 서로 간섭하는 냄새가 날 것입니다. 간섭 테스트는 초기 테스트가 나쁜 데이터를 남기거나 테스트 자체가 실패하기 때문에 실패하기 때문에 신뢰할 수 없습니다. 코드에 실제로 잘못된 점을 알 수있는 방법이 없습니다.

+0

테스트 주문에 대한 아이디어 감사합니다. 필자의 경우 autotests로 각 클래스를 실행 한 후 브라우저를 다시 시작해야하는데 테스트 순서에 의존하지 않는다. – Ellina

1

모든 테스트 후에 실행되는 TestCleanupAttribute이라는 다른 속성이 있습니다.

TestInitializeAttribute이라는 테스트가 있기 전에 실행해야 할 속성이 있습니다.

다음은 함께 실행되는 예입니다.

[TestClass] 
public class MyTests 
{ 
    [ClassInitialize] 
    public void ClassInitialize() { Debug.Print("Running ClassInitialize"); } 

    [TestInitialize] 
    public void TestInitialize() { Debug.Print("Running TestInitialize"); } 

    [TestMethod] 
    public void TestMethod1() { Debug.Print("Running  TestMethod1....."); } 

    [TestMethod] 
    public void TestMethod2() { Debug.Print("Running  TestMethod2....."); } 

    [TestCleanup] 
    public void TestCleanup() { Debug.Print("Running TestCleanup"); } 

    [ClassCleanup] 
    public void ClassCleanup() { Debug.Print("Running ClassCleanup"); } 
} 

Running ClassInitialize 
Running TestInitialize 
Running  TestMethod1..... 
Running TestCleanup 
Running TestInitialize 
Running  TestMethod2..... 
Running TestCleanup 
Running ClassCleanup 
+0

참고'TestMethod1'과'TestMethod2'는 순서가 맞지 않을 수 있습니다. –

+0

TestCleanup을 사용할 필요가 없습니다. 한 클래스에서 모든 테스트를 마친 후에 ClassCleanup을 호출해야합니다. 예 : Class1 -> ClassInitialize -> Test1 -> Test2 -> Test3 -> ClassCleanup -> Class2 -> ClassInitialize -> Test4 -> Test5 -> Test6 -> ClassCleanup -> Class3 ... – Ellina

+0

프레임 워크가 ' 상자 밖에서 그것을 지원하지 마십시오. 모든 테스트를 개별적으로 추적해야하고,'TestCleanup'에서 모든 것이 실행되면 점검 및 정리를 수행하십시오. –

10

테스트 클래스에서 테스트를 포함하여, 정렬되지 않은 실행에 발생합니다. 이 블로그 게시물을 참조 :

http://blogs.msdn.com/b/ploeh/archive/2007/01/06/classcleanupmayrunlaterthanyouthink.aspx

인용하기 :

어떤 경우

가 여기 내 출력 창에서 결과입니다 :

AssemblyInitialize 
TestClass1: ClassInitialize 
TestClass1: TestInitialize 
TestClass1: MyTestCase1 
TestClass1: TestCleanup 
TestClass2: ClassInitialize 
TestClass2: TestInitialize 
TestClass2: MyTestCase2 
TestClass2: TestCleanup 
TestClass1: ClassCleanup 
TestClass2: ClassCleanup 
AssemblyCleanup 

...이 의미하지 않는다 TestClass1의 ClassCleanup은 클래스의 마지막 테스트 케이스 바로 다음에 실행됩니다! 실제로 모든 테스트 케이스가 실행될 때까지 기다리고 을 TestClass2의 ClassCleanup과 함께 실행합니다.

처음에 나를 놀라게하지만 정말 그것을 통해 생각하지 않았다 때문이 분명했다 : 시험이기 때문에, 원칙적으로 정렬되지 않은, TestClass1에서 모든 테스트가 즉시 연속적으로 실행된다는이 보장 아니에요 . 이론적으로 실행 엔진 은 TestClass1에서 테스트 사례를 선택한 다음 TestClass2에서 하나를 선택한 다음 TestClass1에서 다른 하나를 등으로 가져올 수 있습니다. 따라서이 경우 전에 하나의 테스트 클래스에서 모든 테스트가 실행되었음을 보장하는 보증이 없습니다. 새로운 테스트 클래스가 초기화되고, 따라서 모든 ClassCleanup 메소드 은 모든 테스트 케이스가 실행될 때까지 지연 될 수있다.

불행히도 주문형 테스트 나 다른 단위 테스트 프레임 워크에서 살펴볼 수 있습니다.

+0

모든 테스트 케이스가 실행될 때까지 TestClass1의 ClassCleanup이 실행되지 않는다는 것을 알지 못했습니다. 나는 이것이 내가 TestClass1을 가지고 실행한다면 TestClass2에서 에러를 볼 수있는 이유일지도 모른다라고 생각한다. 알아 둘만한. 감사. – Rich

1

몇 가지 테스트를 수행하고 클래스의 정적 필드를 사용하여 TestCleanup 메소드에 모든 메소드가 실행되었다고 "알리는"방법을 사용합니다. 그런 다음 ClassCleanup을 삭제하고 같은 것을 할 수 있습니다 : 그래도 매우 멀리이 솔루션에서 머물 것

private static int runs = 0; 

[ClassInitialize] 
public static void SetUpBrowser(TestContext context) 
{ 
    pageObjectBase.SetBrowser("chrome"); 
    pagesManager.GetPageObjectBase(); 
} 

[TestMethod] 
public void FindCriticalBug() 
{ 
    runs++; 
    bla-bla-bla(); 
} 

[TestMethod] 
public void FindCriticalBug2() 
{ 
    runs++; 
    ble-ble-ble(); 
} 

[TestCleanup] 
public static void CloseBrowser() 
{ 
    if (runs == 2) 
    { 
     pageObjectBase.Stop(); 
     pagesManager.GeneralClearing(); 
    } 
} 

을하지만 다른 대안이없고, 경우에 당신은 당신의 디자인을 리팩토링 할 수 제공된 라이프 사이클을 사용하면 옵션 일 수 있습니다. 아마도 여기에서 더 좋아질 수 있으며 실행을 계산하고 자신의 기본 클래스를 작성하고 리플렉션을 사용하여이 항목을 자동화하는 테스트 메소드의 총량을 가져올 수 있습니다.

+0

'runs ++ '을'[TestInitialize]'메소드로 옮김으로써 코드를 조금 단순화 할 수 있습니다. 그런 다음'[TestCleanup]'에서'running'을 감소시키고'0'인지 확인하기 위해 검사의 서브 세트를 실행하는 것을 지원합니다. – Grinn

관련 문제