2009-06-07 1 views
0

Ich habe eine Reihe von C# Integrationstests geschrieben mit dem Given/When/Then-Stil von Gurke popularisiert. Ich benutze ein Framework, das im Prinzip genauso funktioniert wie NBehave.Best Practices/Ideen zum Einrichten des Systemstatus beim Testen der Integration?

Ein wiederkehrendes Problem, mit dem ich konfrontiert bin, ist das Problem der Einrichtung und Verkabelung aller für den Integrationstest erforderlichen Anwendungszustände. Die meisten meiner Tests in etwa so aussehen:

 
Given an empty system 
    And a new NetworkServer 
    And a new ServerDatabase 
    And a new Eventlogger 
    And a new Networkconnection 
    And a new LoggingClient 
When the client logs a new event 
Then it should appear in the server database 

Wie Sie die Aktion und Behauptung sind einzelne Linien zu sehen, aber ich habe 6 Zeilen ‚Verdrahtung‘. Fast jeder Test, den ich habe, wiederholt diese 6 Zeilen.

Das scheint mir ein Code-Geruch, aber ich bin mir nicht sicher, wie ich damit umgehen soll. Ich könnte die 6 Zeilen zu einem einzigen umstrukturieren (Given "a valid system..." oder so), aber das scheint zu weit zu gehen und ich würde zu viele Informationen verstecken.

Ich würde mich über alle Gedanken von anderen mit mehr Erfahrung auf diesem Gebiet freuen. Danke vielmals.

Antwort

1

Für mich riecht es so, als ob Sie eine Basisklasse haben möchten, die das Setup durchführt, und dann Ihre Testklassen von dieser Basis erben lassen und nur die neue Testfunktionalität hinzufügen.

Base(): 
    constructor(): 
    do your wiring 
    test if everything's ok 


TestClass : Base 
    constructor(): 
    Base.constructor() 
    additional setup? 

    test_functions() 
    .. 
+0

Hrm ... Vielen Dank für die Eingabe. Ich muss zugeben, dass ich das Basisklassenmodell nicht mag, da es bedeutet, dass die Hälfte des Setup-Codes im Basiskonstruktor in einer komplett anderen Datei versteckt ist ... immer gut, um verschiedene Blickwinkel zu sehen. +1 –

1

Wir haben so etwas wie dieses

public abstract class ContextSpecification 
{ 
    [FixtureSetUp] 
    public void SetUp() 
    { 
     EstablishContext(); 
     Act(); 
    } 

    protected abstract void Act(); 

    protected abstract void EstablishContext(); 

    [FixtureTearDown] 
    public void TidyUpCore() 
    { 
     TidyUp(); 
    } 

    protected virtual void TidyUp() 
    { 

    } 
} 

dann für jede Gruppe ähnlicher Tests, die wir eine BaseContext wie folgt zu erstellen:

internal class TestClassTests 
{ 
    internal abstract class BaseContext : ContextSpecification 
    { 
     protected TestClass _sut; 

     protected override void Act() 
     { 

     } 

     protected override void EstablishContext() 
     { 
      _sut = new TestClass(); 
      // common wiring 
     } 
    } 

    internal class Given_this_situation : BaseContext 
    { 
     protected override void EstablishContext() 
     { 
      base.EstablishContext(); 
      // test specific wiring 
     } 

     protected override void Act() 
     { 
      // carry out the test actions 
     } 

     [UnitTest] 
     public void ThisShouldBeTrue() 
     { 
      Assert.IsTrue(); 
     } 
    } 
} 
+0

Es ist interessant, eine einzelne "Act" -Methode zu sehen und danach alle Behauptungen separat zu behandeln. Wie finden Sie das in der Praxis? Ich dachte, eines der Ziele von Unit Testing war, jede Testmethode autonom zu machen (nicht davon abhängig, dass "Act" davor ausgeführt wurde) ... –

+0

Es funktioniert sehr gut - wir neigen dazu, jede Behauptung in ihre eigene Testmethode zu setzen, und das vermittelt mehr Informationen, wenn ein Test bricht: Wir müssen nicht nach der Behauptung suchen, die fehlgeschlagen ist. Mit dieser Technik haben wir das Prinzip einfach um eine Ebene in der Hierarchie verschoben - jede Testklasse ist autonom. –

Verwandte Themen