Agile / Software-Entwicklung

10 häufige Probleme mit Unit Tests in Real-World Projekten

Unit Tests werden geschrieben, meistens zumindests ;-). Und meistens funktioniert dieser Prozess in Visual Studio auch ganz gut, aber eben nur meistens. Dieser Erfahrungsbericht mit .NET Projekten soll helfen: 10 häufige Probleme mit Unit Tests in Real-World Projekten.

Probleme mit Unit Tests

1.   100% Testabdeckung

Code Coverage dient als Metrik der Qualitätssicherung, aber nicht um jeden Preis und von jeder Zeile Code. Die allgemeine Regel 80% entspricht schon eher der Realität, manche Assemblies oder Namespaces müssen getrennt betrachtet werden. Und nicht alles muss getestet werden:

  • Code-behind von WPF Views
    In Zeiten von MVVM besteht diese Klassen nur mehr aus einem Konstruktor mit this.Initialize(), daher bietet sich das Klassenattribut ExcludeFromCodeCoverage an.
  • Auto-implemented Properties
    Bei diesen „dummen“ Eigenschaften einer Klasse ohne eigenen Code, steigt die Qualität des Produkts nicht, wenn es dazu einen Unit Test gibt, auch wenn die Code Coverage bei einer Klasse mit mehreren Properties von 60% auf 85% steigt. Allerdings ist dies auch ein Hinweis darauf, dass diese Klasse zu viele Properties beinhaltet, die nicht in diese Klasse gehören. Properties mit viel Code im Setter sind außerdem ein weiterer „Code Smell“.

 

2.   Mocking: Nicht verwendete Mocks im Test erzeugen (Performance!)

Schreibt man viele Unit Tests, gibt es irgendwann den Punkt der Performance Optimierung, und ein Learning aus der Praxis zeigte: Das Framework „Moq“ ist zwar ein leichtgewichtiges und sehr zu empfehlendes Framework, aber jeder Mock kostet Zeit. Daher nur den Mock eines Interfaces instanziieren, den ein Test auch benötigt.

 

3.   Integrationstests

Wird vor jedem Test eine Datenbank erzeugt, ist leider die Ausführungszeit von Integrationstests enorm. Hier hilft die Erstellung einer Transaktion vor dem Start eines Tests. Hier eine kleine Anleitung:

  • Eine  Basisklasse für alle Integrationstests schreiben.
  • Im TestInitialize: Die Transaktion erzeugen.
  • Im TestCleanup: Die Transaktion disposen.
  • Im ClassInitialize: AppDomain.CurrentDomain.DomainUnload handeln und ebenso disposen.

 

4.   Untestbarer Code

Problematisch sind Drittkomponenten, Legacy Code, etc … Dafür gibt es Stubs&Fakes, passende Frameworks wie MS Fakes, TypeMock & Co. Aber es geht auch anders, wenn man den Code in der Hand hat bzw. das Problem von einer anderen Seite betrachtet: Separation of Concerns (SoC) bedeutet ganz einfach, dass eine Klasse nur eine Aufgabe hat. In einem ViewModel können statische Properties (Dispatcher, Cache, etc..) ganz einfach mittels Interface und einem eigenen Service aufgelöst werden. Damit wird die Klasse testbar. Siehe auch Interface Segregation Principle (ISP) und Dependency Inversion Principle (DIP).

 

5.   Motivation der Entwickler

„Ich hatte keine Zeit mehr, die Story musste doch fertig werden.“ Besonders der Scrum Master ist gefordert das Bewusstsein für den Nutzen im gesamten Team (auch beim Productowner) zu schaffen.

 

6.   DateTime: Formatierung geht von einer bestimmten Culture aus

Eigentlich offensichtlich, aber es passiert doch in jedem Projekt mindestens 1x

 

7.   Best of: MessageBox statt Assert 🙂

 

8.   Zu viele Asserts in einem Unit Test

Ein Unit Test soll 1, oder vielleicht 2 Asserts beinhalten, nicht mehr.

 

9.   Business Logik in Partial Klassen der Entitäten des Entity Frameworks.

Entitäten in Partial Klassen zu erweitern, ist generell die präferierte Lösung. Da der autogenerierte Code des Designers aber zu recht nicht getestet wird, ist die Code Coverage dieses Namespaces normalerweise bei 0%. Die eigene Business Logik muss in einem eigenen Domain-Layer in einem anderen Projekt oder zumindest einem anderen Namespace implementiert werden.

 

10. [Ignore]

„… es war 19:00, keiner war mehr da und ich musste aber einchecken …“ Die Kollegin/der Kollege hat andere Unit Tests mit dem Attribut „Ignore“ versehen, damit der Gated Checkin durchläuft. 3 Wochen später bemerkt man es…

 

Sind Sie noch mit anderen Problemen häufig konfrontiert?
In meinen nächsten Beiträgen werde ich Ihnen Tipps & Tricks aus der Praxis rund um Unit Testing im .NET Bereich verraten.

 

Weiterführende Informationen und Links:

SoC, ISP, IoC, LSP
http://www.clean-code-developer.de

Buch „The Art of Unit Testing“
http://manning.com/osherove/

Moq
https://github.com/Moq/moq4

Microsoft Fakes
http://msdn.microsoft.com/en-us/library/hh549175.aspx

Passende Artikel

Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*