xUnit BDD Extensions

Wednesday, October 22, 2008 6:24:03 PM (W. Europe Daylight Time, UTC+02:00)

Auf dem .NET Open Space hat Björn Rochel seine xUnit BDD Extensions vorgestellt und wir haben uns in einer Session auch länger darüber unterhalten.

Heute habe ich seine Extensions das erste Mal ausprobiert und einen neuen Unit Test nach BDD Art geschrieben.

Dieser spezielle Test war besonders kompliziert, da ich hier Code in einem Windows Service testen wollte und dafür die OnStart Methode aufrufen musste, die protected ist. Außerdem startet der Code der getestet wird mehrere neue Threads, und der Test sollte prüfen, ob diese Threads auch wirklich gestartet wurden.

Der Test sieht dann folgendermaßen aus:

public class 
When_the_Service_Starts_And_There_Are_three_Tasks : 
TaskRunnerServiceSpecification
   {
       #region Arrange

       protected override void EstablishContext()
       {
           base.EstablishContext();

           newThreads = new List<Thread>();

           // add some tasks
           tasks.Add(new TestTask(this));
           tasks.Add(new TestTask(this));
           tasks.Add(new TestTask(this));
       }

       internal IList<Thread> newThreads;



       #endregion

       #region Act

       protected override void Because()
       {
           // because OnStart was called...
           taskRunnerService.InvokeNonPublicMethod(
              "OnStart", new object[] {
                 new string[0]});

           // ... wait a second to give the other 
           // threads a chance to execute
           Thread.Sleep(1000);
       }

       #endregion

       #region Assert

       [Observation]
       public void should_create_three_new_threads()
       {
           newThreads.Distinct().Count().
           ShouldBeEqualTo(3);
       }

       [Observation]
       public void should_execute_all_tasks()
       {
           tasks[0].wasExecuted.ShouldBeTrue();
           tasks[1].wasExecuted.ShouldBeTrue();
           tasks[2].wasExecuted.ShouldBeTrue();
       }


       #endregion

       #region Cleanup


       protected override void AfterEachObservation()
       {
           base.AfterEachObservation();

           foreach (var thread in newThreads)
           {
               if (thread.IsAlive)
                   thread.Abort();
           }
       }

       #endregion
   }

Im Prinzip verbirgt sich dahinter ein “ganz normaler” Unit Test mit xUnit und Rhino Mocks (wobei ich in diesem speziellen Test zufällig gerade keine Mocks nutze), allerdings besser strukturiert und mit lesbareren Methodennamen (z.B. ShouldBeTrue statt Assert.True).

Durch die Bennenung der Tests und Methoden nach BDD-Art ist die Ausgabe im ReSharper Testrunner richtig gut lesbar:

image

In dem Beispielcode oben fehlt noch eine Hilfsklasse für diesen Test, TestTask. Diese setzt nur ihre “wasExecuted”-Eigenschaft auf true, falls die Execute-Methode aufgerufen wurde, und fügt ihren Thread zur newThreads-Liste hinzu.

Wir werden das in der Praxis weiter ausprobieren (ein anderer Kollege hat sich vorhin auch schon an BDD versucht), und diesen Ansatz wenn er sich bewährt für alle unsere Unit Tests übernehmen.

Kick it on dotnet-kicks.de
Page 1 of 1 in the SoftwareTestsBDDTDD category