Growing Object-Oriented Software, Guided By Tests (chapter 12)

Feb 15, 22

Now that we have a full end-to-end test, going forward we can use acceptance tests hanging off the ‘walking skeleton’ to validate our design. This will also help us to build incrementally, one feature at a time.

For each acceptance test, we should attempt to add just enough new requirements to force a manageable increase in functionality.

Be careful to clean up any resources between test runs


The authors refer to ‘outside-in development’ - as we have mentioned before, we should write a test for the feature we want, and then fill in the details with ever more granular tests + code.

We should strive to keep the quality of our components high and should refactor aggressively to make our system as simple as possible.

Tip: Put the test files in a separate package. This will help to maintain boundaries between your test code and project code.

Tip: Use null when arguments don’t matter in a test but name the null primitive as a constant. This helps to keep things consistent, especially when mocking/stubbing.

Remember, we should be passing dependencies into the constructor of the peer object. Please, use dependency injection for this if available.

Extract behaviour into separate classes where possible. This will make the system easier to test and will highlight the relationships between objects/components.

Make a note of error handling behaviour and implement it and test it once we have the happy path tested.

Once we have completed a feature test, we will need to refactor it. The ‘first cut’ is unlikely to use the most refined approach.

Again, this chapter used a lot of Java so I am intentionally leaving out the implementation details, and focusing on the higher-level concepts.