Growing Object-Oriented Software, Guided by Tests

Growing Object-Oriented Software, Guided by Tests

Afgelopen weekend heb ik twee hoofdstukken van het boek Growing Object-Oriented Software, Guided by Tests gelezen. (Rechts is meer informatie te vinden over dit boek.) In een van deze hoofdstukken staat dat het een goede gewoonte is om je testcode in een ander package te zetten dan je productiecode. En daarvoor worden twee redenen gegeven:

  1. Navigeren in je IDE is makkelijker als je testcode gescheiden wordt van je productiecode.
  2. Je wilt eigenlijk alleen de public methoden / interface van je code testen. Door het in een ander package te zetten test je niet per ongeluk op package level.

Allereerst wil ik het over de eerste reden hebben. In principe ben ik het eens met de reden. Ik denk alleen dat er een andere manier is om dit te bereiken. Ik heb altijd de gewoonte om mijn test code in een andere “source folder” te zetten dan mijn productie code waardoor deze scheiding dus gemaakt wordt.

De tweede reden is wat mij betreft niet waar. Ja je wilt zeker de public interface testen. Maar ik vind het handig om ook de packages als “encapsulation” methode te gebruiken. Laat ik dit proberen uit te leggen met een voorbeeld. Het is gebaseerd op hetzelfde voorbeeld als mijn vorige post: het importeren van transacties in mijn administratie. In dit geval gaat het over het importeren van transacties van een specifieke bank.

Ik wil niet dat er in de rest van de code enige kennis heeft van de interne structuur van de code die verantwoordelijk is voor de import. Om deze abstractie apart te houden heb ik een interface gemaakt die de import voor een willekeurige bank kan aanbieden in termen van mijn domein. Met andere woorden gegeven deze bank en deze import file geef me alle transacties.

Wat dat betreft zou je zeggen maak een class en implementeer deze interface. Problem solved. Nu heb ik in mijn vorige post aangegeven dat ik meerdere classes gemaakt heb omdat dit het (import) probleemdomein beter omschrijft. Ik wil niet dat de rest van mijn code toegang heeft tot deze classes. Alleen de publieke interface moet gebruikt worden. Ik gebruik een package om deze classes te omsluiten.

Als ik dan de testcode in een apart package zou zetten kan ik de code alleen via de public interface testen. Dit zou inhouden dat ik testen kan schrijven die lijken op een integratietest. Mijn design zou dan veel minder beïnvloed zijn door de unittesten. Door de unittestcode echter in hetzelfde package (in de test source folder) te zetten was het mogelijk om de code voor de import te testen in veel kleinere stappen. Integratie en/of acceptatietesten kunnen dan de public interface testen om te zien of de eigenlijke public interface een goede “API” is. Dus unittestcode moet wat mij betreft niet in een ander package zitten dan de productiecode, wel in een andere “source folder”.