Designing for testability in the real world

Writing tests offers a significant advantage during development: if you pay attention to them (or listen to them, as many developers say), they may give you hints about the design of the code you are testing. Achieving good class design is a challenge in complex object-oriented systems. The more help we get, the better.

The buzz about tests giving feedback about the design of the code comes from the fact that all your test code does is exercise the production class:

  1. It instantiates the class under test. It can be as simple as a new A() or as complicated as A(dependency1, dependency2, ...). If a class needs dependencies, the test should also instantiate them.
  2. It invokes the method under test. It can be as simple as a.method() or as complicated as a.precall1(); a.precall2(); a.method(param1, param2, ...);. If a method has pre-conditions before being invoked and/or receiving parameters, the test should also be responsible for those.
  3. It asserts that the method behaves as expected. It can be as simple as assertThat(return).isEqualTo(42); or as complicated as dozens of lines to observe what has happened in the system. Again, your test code is responsible for all the assertions.

You should constantly monitor how hard it is to perform each of these steps. Is it difficult to instantiate the class under test? Maybe there is a way to design it with fewer dependencies. Is it hard to invoke the method under test? Maybe there is a way to design it so its pre-conditions are easier to handle. Is it difficult to assert the outcome of the method? Maybe there is a way to design it so it is easier to observe what the method does.

Next, I will describe some things I pay attention to when writing tests. They give me feedback about the design and testability of the class I am testing.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *