2014-06-09 9 views
5

Mam kilka klas z pakietami testów.Jak uruchomić ClassCleanup (MSTest) po każdej klasie z testem?

Każda klasa testowa zaczyna się od ClassInitialize i kończy klasą ClassCleanup. Moim problemem jest to, że ClassCleanup nie jest wywoływana na końcu każdej klasy, jest wywoływana tylko po wszystkich testach w trzech klasach. Czy mogę rozwiązać ten problem? Dzięki!

[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(); 
} 

Odpowiedz

1

Normalne unittest są "nieuporządkowane", co oznacza, że ​​mogą być uruchamiane w dowolnej kolejności. Prawdopodobnie szukasz czegoś podobnego do zamówionego testu (zobacz swój komentarz na temat dominic). Zamówiony test jest specjalnym projektem, który jest niepotwierdzony. Podczas uruchamiania zamówionych testów, test przeprowadzi konfigurację i wyleczy testy podczas ich ukończenia. Jeśli test jednostkowy musi przebiegać w kolejności, jest to zapach, który zakłóca test. Test interferujący jest niewiarygodny, ponieważ się nie powiódł, ponieważ wcześniejszy test pozostawił jakieś złe dane lub test sam się nie powiódł. Nie masz możliwości dowiedzenia się, co jest naprawdę nie tak z twoim kodem.

+0

Dziękujemy za pomysł zamówienia testu! W moim przypadku wystarczy zrestartować przeglądarkę po każdej klasie z autotestami, nie ma zależności w kolejności testowania. – Ellina

1

Istnieje inny atrybut o nazwie TestCleanupAttribute, który będzie uruchamiany po każdym teście.

Istnieje również atrybut uruchamiany przed każdym testem o nazwie TestInitializeAttribute.

Oto ich przykład.

[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"); } 
} 

To spowoduje

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

Uwaga: 'TestMethod1' i' TestMethod2' mogą być niekompletne. –

+0

Nie muszę używać TestCleanup. Muszę wywołać ClassCleanup po wszystkich testach w jednej klasie. Przykład: Class1 -> ClassInitialize -> Test1 -> Test2 -> Test3 -> ClassCleanup -> Class2 -> ClassInitialize -> Test4 -> Test5 -> Test6 -> ClassCleanup -> Class3 ... – Ellina

+0

Wygląda na to, że framework doesn ' t wspierać go po wyjęciu z pudełka. Będziesz musiał śledzić wszystkie testy indywidualnie, a następnie w "TestCleanup", wykonaj kontrolę i oczyść, gdy wszystkie mają bieg. –

10

Testy prowadzone są nieuporządkowane, w tym testów w całej klasy. Zobacz ten post na blogu:

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

Cytując:

W każdym razie, oto wynik z mojego okna wyjściowe:

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

... to nie znaczy, TestClass1's ClassCleanup jest wykonywany natychmiast po ostatnim przypadku testowym w klasie! W rzeczywistości czeka, aż wszystkie przypadki testowe zostaną wykonane, a następnie wykona wraz z ClassCleanup TestClass2.

Zdziwiło mnie na początku, ale to oczywiście tylko dlatego, że tak naprawdę nie myślał go poprzez: Ponieważ testy są w zasadzie nieuporządkowana, tam nie gwarantujemy, że wszystkie testy w TestClass1 są wykonywane w bezpośrednim rzędu . Teoretycznie silnik wykonawczy może wybrać testową obudowę z TestClass1, następnie jedną z TestClass2, następnie inną z TestClass1, itd. Ponieważ tak jest, nie ma gwarancji, że wszystkie testy z jednej klasy testów zostały wykonane przed nowa klasa testowa jest inicjowana, a zatem wszystkie metody ClassCleanup mogą być również odroczone do momentu wykonania wszystkich przypadków testowych.

Niestety, trzeba spojrzeć na zamówionych badań lub w innym ramach testów jednostkowych, jeśli to nie działa dla Ciebie.

+0

Nie zdawałem sobie sprawy, że ClassCleanup TestClass1 nie zostanie wykonany, dopóki wszystkie przypadki testowe nie zostaną wykonane. Myślę, że być może dlatego widzę błąd w TestClass2 tylko wtedy, gdy uruchamiam go z TestClass1, ale nie, jeśli uruchomię go sam. Dobrze wiedzieć. Dzięki. – Rich

1

Zrobiłem kilka testów i przy użyciu statycznego pola w klasie "tell" metody TestCleanup, że wszystkie metody działają, wydaje się działać. Następnie można upuścić ClassCleanup i zrobić coś takiego:

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(); 
    } 
} 

zatrzymałbym bardzo daleko od tego rozwiązania chociaż, ale jeśli nie masz innego wyjścia, i nie można byłaby swój projekt do użyj podanego cyklu życia, może to być opcja. Prawdopodobnie możesz być tutaj bardziej doświadczonym i napisać własną klasę bazową, która zlicza egzekucje i pobiera całkowitą ilość metod testowych za pomocą refleksji, aby zautomatyzować te rzeczy.

+0

Możesz nieco uprościć swój kod, przenosząc 'runs ++' do metody '[TestInitialize]'. Następnie, jeśli usuniesz 'runs' w' [TestCleanup] 'i sprawdzisz czy to' 0', to będzie obsługiwać podzbiór testów. – Grinn

Powiązane problemy