2013-08-29 17 views
5

Utilizzo di MSTEST in VS2012.3 .NET4.5 e R # per il test runner.Test multipliInizializza attributi in MSTEST

Il codice seguente funziona nell'ordine 1,2,3,4.

Tuttavia mi riguarda che non sempre eseguito in questo ordine come multiplo TestInitialize attributi non sono supportati MSDN

domanda: E 'questo domestici, e fare i documenti solo dire che più TestInitialize attributi non sono ammessi in la stessa classe?

Vorrei mantenere questa struttura come molti test di integrazione che ereditano da TransactedTestBase, ma richiedono diversi script SQL da configurare.

Stesso comportamento è stato trovato here

[TestClass] 
public class DelegationTest : TransactedTestBase 
{ 
    [TestInitialize] 
    public void Setup() 
    { 
     Console.WriteLine("2 Setup"); 
     //var script = "INSERT INTO blah..."; 
     //var sqlConnect = new SqlConnection(dbConnection.ConnectionString); 
     //sqlConnect.Open(); 
     //var server = new Server(sqlConnect); 
     //var database = server.Databases[sqlConnect.Database]; 
     //database.ExecuteNonQuery(script); 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     Console.WriteLine("3 Test Method"); 
    } 
} 

[TestClass] 
public class TransactedTestBase 
{ 
    //protected userEntities userEntities; 
    //private TransactionScope scope; 
    //public static SqlDatabase dbConnection; 

    //private const bool ShouldWriteToDB = true; 
    //private const bool ShouldWriteToDB = false; 

    [TestInitialize()] 
    public virtual void TestStart() 
    { 
     Console.WriteLine("1 TestStart"); 
     //if (ShouldWriteToDB) 
     //{ 
     // dbConnection = EnterpriseLibraryContainer.Current.GetInstance<SqlDatabase>("DBConnect"); 
     // return; 
     //} 

     //scope = new TransactionScope(TransactionScopeOption.RequiresNew); 
     //user = new userEntities(); 
     //dbConnection = EnterpriseLibraryContainer.Current.GetInstance<SqlDatabase>("DBConnect"); 
    } 

    [TestCleanup()] 
    public virtual void TestEnd() 
    { 
     Console.WriteLine("4 TestEnd"); 
     //if (ShouldWriteToDB) return; 

     //scope.Dispose(); 
    } 
} 
+0

È possibile evitare una sorpresa e chiamare direttamente i metodi della classe di base: [TestInitialize] public override vuoto TestStart() { base.TestStart(); Console.WriteLine ("2 Setup"); } – SlavaGu

risposta

5

Credo che i documenti si riferiscano all'utilizzo dello TestInitializeAttribute più volte con lo stesso metodo. Questo è controllato dal AttributeUsage(AllowMultiple=false). FWIW, ho una suite di test di medie dimensioni (~ 200 test) basata sul codice che hai mostrato funzionante come ti aspetti: TestStart viene chiamato prima dello Setup.

ci sono problemi con il metodo di fare TestInitialize virtuale e override (vedi here) e l'eredità di ClassInitialize metodi (MsTest ClassInitialize and Inheritance).

+0

Grazie Mike, Sunny e SlavaGu.Ora ho più senso, e mi piace davvero questo modo di eseguire i test. –

2

Credo che letto male l'articolo di MSDN. Esse sono:

Questo attributo può essere specificato su un metodo. Solo un'istanza di questo attributo può essere applicata a un metodo.

Il che significa che non si può avere codice come questo:

[TestInitialize] 
[TestInitialize] 
public void MyIntilialzer(){} 

Esso non significa che non è possibile avere più inizializzatori, anche nella stessa classe.

Non sono sicuro di MSTest, but in NUnit its well defined che nella situazione descritta, gli inizializzatori verranno eseguiti nell'ordine corretto, dalla classe base in su. E se hai pochi inizializzatori nella stessa classe, l'ordine non è garantito.

Suppongo che questo sia vero anche per MSTest (ma non ho un punto di riferimento).

2

Tenere presente che l'ordine di esecuzione dipende dal test runner. Il runner di test di Visual Studio e il runner di test R # potrebbero comportarsi diversamente. Ora credo che abbiano lo stesso comportamento, ma comunque dipende da R # come si comporterà.

Ricordo che una delle versioni precedenti di R # ha un bug e il metodo TestInitialize della sottoclasse è stato eseguito prima del metodo TestInitialize nella classe base. Naturalmente, è stato risolto rapidamente :)

Problemi correlati