<<Clean Code>> Quotes: 9. Unit Tests
The Three Laws of TDD
First Law You may not write production code until you have written a failing unit test.
Second Law You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
Thid Law You may not write more production code than is sufficient to pass the currently failing test.
Keeping Tests Clean
What this team did not realize was that having dirty tests is equivalent to, if not worse than ,having no tests.
Test code is just as important as production code. It is not a second-class citizen, It requires thought, design and care. It must be kept as clean as production code.
Test Enable the -ilities
If you don’t keep your tests clean, you will lose them. And without them, you lose the very thing that keeps your production code flexible.
Clean Tests
What makes a clean test? Three things. Readability, readability, and readability.
What makes tests readable? The same thing that makes all code readable: clarity, simplicity, and density of expression.
The BUILD-OPERATE-CHECK pattern is made obvious by the structure of these tests. Each of the tests is clearly split into three parts.
Domain-Specific Testing Language
Rather than using the APIs that programmers use to manipulate the system, we build up a set of functions and utilities that makes use of those APIs and that make the tests more convenient to write and easier to read.
This testing API is not designed up front; rather it evolves from the continued refactoring of test code that has gotten too tainted by obfuscating detail.
A Dual Standard
The code within the testing API does have a diffrent set of engineering standard than production code. It must still be simple, succinct, and expressive, but it need not be as efficient as production code.
EnviromentControllerTest.java
@Test
public void turnOnLoTempAlarmAtThreashold() throws Exception {
hw.setTemp(WAY_TOO_COLD);
controller.tic();
assertTrue(hw.heaterState());
assertTrue(hw.blowerState());
assertFalse(hw.coolerState());
assertFalse(hw.hiTempAlarm());
assertTrue(hw.loTempAlarm());
}
After improve:
@Test
public void turnOnLoTempAlarmAtThreashold() throws Exception {
wayTooCOde();
assertEquals("HBchL", hw.getState());
}
One Asset per Test
There is a school of thought that says that every test function in a JUnit test should have one and only one asset statment. Those tests come to a single conclusion that is quick and easy to understand.
We can break the test into two separate tests, each with its own particular assertion.
Unfortunately, splitting the tests as shown results in a lot of duplicate code.
Single Concept per Test
Perhaps a better rule is that we want to test a single concept in each test function.
F.I.R.S.T.
Clean tests follow five other rules that form that above acronym
Fast Test should be fast. They should run quickly.
Independent Tests shoul not depend on each other.
Repeatable Tests should be repeatable in any environment.
Self-Validating The tests shoul have a boolean output. Either they pass or fail. You should not have to read through a log file to tell whether the tests pass.
Timely The tests need to be written in a timely fashion. Unit tests should be written just before the production code that makes them pass.