2014-06-09 3 views
5

Ho diverse classi con suite di test.Come eseguire ClassCleanup (MSTest) dopo ogni classe con test?

Ogni classe di test inizia da ClassInitialize e termina con ClassCleanup. Il mio problema è che ClassCleanup non viene chiamato alla fine di ogni classe, viene chiamato solo dopo tutti i test in tre classi. Posso risolvere questo problema? Grazie!

risposta

1

L'unittest normale è "non ordinato", il che significa che possono essere eseguiti in qualsiasi ordine. Probabilmente stai cercando qualcosa come test ordinato (vedi il tuo commento su dominic). Il test ordinato è un progetto speciale di unittest. Durante l'esecuzione di test ordinati, il test eseguirà il modo in cui li configurerai e le classi di test teardown al termine. Se il test dell'unità deve essere eseguito in ordine, è un odore che il test interferisca tra loro. I test interferenti sono inaffidabili perché non riescono perché un test precedente ha lasciato dei dati errati o il test fallisce da solo. Non hai modo di sapere cosa c'è di veramente sbagliato nel tuo codice.

+0

Grazie per l'idea dell'ordine di prova! Nel mio caso ho bisogno solo di riavviare il browser dopo ogni classe con gli autotest, non c'è dipendenza nell'ordine di test. – Ellina

1

C'è un attributo diverso chiamato TestCleanupAttribute, che verrà eseguito dopo ogni test.

C'è anche un attributo da eseguire prima di ogni test chiamato TestInitializeAttribute.

Ecco un esempio di loro in esecuzione insieme.

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

Ciò comporterà

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

Nota 'TestMethod1' e' TestMethod2' potrebbero non funzionare. –

+0

Non è necessario utilizzare TestCleanup. Devo chiamare ClassCleanup dopo tutti i test in una classe. Esempio: Class1 -> ClassInitialize -> Test1 -> Test2 -> Test3 -> ClassCleanup -> Class2 -> ClassInitialize -> Test4 -> Test5 -> Test6 -> ClassCleanup -> Class3 ... – Ellina

+0

Sembra che il framework non funzioni t supportarlo fuori dalla scatola. Dovresti tenere traccia di tutti i test individualmente, quindi in "TestCleanup", eseguire il controllo e la pulizia quando sono tutti eseguiti. –

10

test sono eseguiti ordinata, comprese le prove diverse classi. Vedi questo post del blog:

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

Per citare:

In ogni caso, ecco il risultato dalla mia finestra di uscita:

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

... questo non significa che ClassCleanup di TestClass1 viene eseguito immediatamente dopo l'ultimo test case della classe! In effetti, attende che tutti i casi di test siano eseguiti, e esegue insieme a ClassCleanup di TestClass2.

Questo mi ha sorpreso in un primo momento, ma che è stato, ovviamente, solo perché non avevo realmente pensato bene: Dal test sono, in linea di principio, non ordinata, non c'è garanzia che tutti i test in TestClass1 sono eseguiti in successione immediata . Teoricamente, il motore di esecuzione può scegliere un test da TestClass1, allora uno da TestClass2, quindi altro da TestClass1, ecc Poiché questo è il caso, non c'è garanzia che tutti i test da una classe di test sono stati eseguiti prima un la nuova classe di test viene inizializzata e, quindi, tutti i metodi ClassCleanup possono essere rinviati fino a quando tutti i casi di test sono stati eseguiti.

Sfortunatamente, dovrai controllare le prove ordinate o in un diverso quadro di prova dell'unità se questo non funziona per te.

+0

Non mi sono reso conto che ClassCleanup di TestClass1 non viene eseguito fino a quando non vengono eseguiti tutti i casi di test. Penso che questo possa essere il motivo per cui sto vedendo un errore in TestClass2 solo se lo eseguo con TestClass1, ma non se lo eseguo da solo. Buono a sapersi. Grazie. – Rich

1

Ho effettuato alcuni test e utilizzando un campo statico nella classe per "indicare" il metodo TestCleanup che tutti i metodi sono stati eseguiti sembra funzionare. È quindi possibile eliminare la ClassCleanup e fare qualcosa del genere:

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

mi piacerebbe rimanere molto lontani da questa soluzione, però, ma se non avete altra alternativa, e non si può refactoring il vostro disegno per utilizzare il ciclo di vita fornito, potrebbe essere un'opzione. Probabilmente potresti diventare più fanatico qui e scrivere la tua classe base che conta le esecuzioni e ottiene la quantità totale di metodi di test usando il reflection per automatizzare questa roba.

+0

Potresti semplificare un po 'il tuo codice spostando 'runs ++' in un metodo '[TestInitialize]'. Quindi se decrementate 'runs' in' [TestCleanup] 'e controllate se è' 0', supporterà l'esecuzione di un sottoinsieme dei test. – Grinn