Montag, 11. Januar 2010

Positionierung von JUnit Tests innerhalb eines Projekts

Neulich ergab sich bei mir auf der Arbeit eine Diskussion über eine auf den ersten Blick relativ banale Angelegenheit. Die Unstimmigkeiten betrafen den Speicherort von JUnit Tests innerhalb eines Projekts. In diesem Fall war es ein Eclipse Java Projekt, doch sicherlich gelten die ähnliche Argumente für jede Projektstruktur mit einer Package basierten Sprache und einem Testframework.

Fragestellung


Folgende Frage stellt sich nun: Sollen die JUnit Tests in einem extra Source Ordner mit dem Namen "test", "JUnit" etc. abgelgegt werden oder sollen die Testklassen im gleichen Sourceordner liegen wie die zu testenden Klassen. Darüber das die Klassen und die Tests jeweils im gleichen Package liegen sollten waren wir uns aus verschiedensten Gründen einig. Die Fragestellung ist also welche Package Struktur die bessere Wahl ist:
1)

ODER
2)

Hier ist die Beschreibung der Problematik und eine Antwort die unter junit.sourceforge zu finden ist: link

Überlegungen


Für die Lösung 1) spricht, dass man auf einen Blick sieht welche Klassen einen Unittest haben und welche noch einen brauchen. Wird eine Klasse umbenannt oder verschoben ist es sehr schwer den dazugehörigen Unittest bei diesem Schritt zu übersehen. Die JUnit Tests sind darüber hinaus aus jeder Ansicht schnell zu öffnen und können per ANT relativ einfach aus dem build Prozess herausgenommen werden.

Für die Lösung 2) spricht die Tatsache, dass die große Anzahl an Tests den Inhalt der einzelnen Packages aufblähen und nicht zu Übersichtlichkeit der Projektansicht beitragen. Der Buildprozess wird vereinfacht. Mock Klassen, Infrastrukturklassen sowie Helper Klassen die nur für das Testen notwendig sind können hier gemeinsam mit den eigentlichen Testklassen relativ einfach untergebracht werden.

Im Netzt findet man unter dem Verweis auf "Best Practice of testing" in der Regel fast Ausschließlich die Anwendung der Lösung 2).
z.B. hier "It is considered a best practice in testing, to separate the test case code from the application code."

Nur selten trifft man auch auf die Argumente, die für die Lösung 1) sprechen.

Schlussfolgerungen


Will man in einem relativ kleinen Projekt das Testen enforcen so wird die Lösung 1) wohl die passendste sein.
In größeren Projekten wo mit Hilfe von Spring beim Testen ganze Architekturschichten ausgetauscht bzw. gemockt werden können und das Verständnis um die Notwendigkeit von Tests bereits vorhanden ist, wird die Lösung 2) wohl am effizientesten sein.