We would like to share our feelings and experiences about Test Driven Development. First of all we use TDD as a software design tool. How can it be? It is quite simple. We just need to change mindset from “testing” approach into “specification” one. We do not really test in TDD, we create micro specification for our code “unit”. Ok… but how to do that? We should remember about quite important stuff here - Object Oriented Programming is about messaging, so to create good OOP module we have to design communication in that module and open (or close) interface in this module to the world. TDD can help with public interface definition.
Plan of message flow
TDD is helping us to design message flow in our modules. Basically not TDD but something which is called Mockist TDD. Here we should tell about difference between Mockist and Classical TDD. Mockist TDD allows us to define object of given interface, and control behavior of this object in our “test”. We can have many kinds of such objects, and if we do not want to have fragile specification, we need to know that “Mocks Arent’s Stubs”. Phpspec is a great tool for such approach. Do you need some example? In our file archive project you can see how ArchiveListUseCase object is communicate with ArchiveRepository. We created specification which define that Archive array fechted from ArchiveRepository should be passed to responder (after conversion to Response DTO objects). Cool is that we can specify message flow based on abstraction (php interfaces) not on concrete implementation.
Classic TDD is focused on simply checking result or state - so it is not good tool to plan communication in our module but it is a great tool to plan concrete behavior or to plan effective computing based on some data (input). We can plan what output are expected for given input, and after few iterations with different output/input sets we will have quite fast computing algorithm. We are mixing both approaches in in our daily work.
How do we make sure that business criteria are met?
We are using TDD as design tool, to check integration of the system and/or acceptance criteria. We are working with other kind of automatic tests (yeah we have layers of tests) and we are using tools like BEHAT (for acceptance criteria) or even phpunit with some database integration (for adapters integration tests).
We hope that someone will be interested how do we treat TDD. It is really hepling us with software design and with some design patterns implementation. We write about it cause we too often hear “We do not have time for tests” mantra together with “We work in legacy code” statement. Really, if you want to improve your project, you should start treat TDD equally with production software development.