Inspired by Matt Wynne's podcast
"BDD as it's meant to be done" I reproduced his sample application with usage of Robot Framework and Java (in place of Cucumber and Ruby). This post is intented to give an overview of a possible setup for Java-based BDD (
source code).
According to Gojko Adzic, 90% of teams that fail with ATDD don't structure they tests properly which results in so called scripts (dozens of test code lines which mix up specification, workflow, user interface) that are a extremly difficult to mantain. The tests should answer the question 'what' to test as opposed to 'how' to do it.
Matt suggests to structure acceptance tests in a layered stack (I rephrased the layer names):
- Examples - table-based set of input values introduced to the system and expected output values upon performing some action
- Scenario - Given-When-Then style of describing the action from Examples step-by-step
- Steps - detailed definition of Scenario steps kept in an technology-independent manner
- Glue - glue code connecting tests with the app itself (uses domain or interface classes in order to manipulate the Application)
- Application - the application itself (should work according to the Examples)
- Examples & Scenario layers clearly communicate the specification to Anybody (Customers could even modify it themselves)
- Steps layer is actually a DSL (Domain-Specific Language) of the application. Exploring it creates a common domain-based language for Team Members and Customers. Further, it allows to execute the same set of tests via different interfaces implemented in the Glue layer
- Glue layer drives us to create testeable classes and methods in the Application
- Turns test (a.k.a. specification) writing into a creative and useful activity
Sample application driven by Robot Framework
Building:
mvn clean install
Testing
cd atdd/cashdispenser-robot/target/
test.bat
Test logs will be created in:
atdd/cashdispenser-robot/target/output
Nice-to-haves and what-nots
In Java EE it would be nice to create two Glue layer implementations. First, that manipulates directly Java classes and uses test doubles to be separated from external services (this could be run after every single build). Second, that uses Jython to execute EJB public methods directly in the container (this is much slower, but permits a more end-to-end testing).