How do you distinguish good from bad tests in your code?
Check these criteria. Good tests
- Nail down expectations
- Monitor assumptions
- Help to locate the cause of a failure
- Document usage patterns
- Allow to change code
- Allow to verify changes
- Are short (LOC + time)
- Waste development time
- Execute many, many lines of code
- Prevent code changes
- Need more time to write than the code they test
- Need a lot of code to set up
- Take ages to execute
- Are hard to run
There are a lot of checks in your compiler. Those help to catch mistakes you make. Do the same with your tests. There are a lot of things that compilers don’t check: File encodings, existence of files, existence of config options, types of config options.
Use tests to nail down your expectations. Read config files and validate the odd option.
Create a test which collects the whole configuration of your program and checks it against a known state. Check that each config option is set only once (or at least that it has the same value in all places).
When you need to translate your texts, add tests which make sure that you have all the texts that you need, that texts are unique, etc.
Convention over configuration only works when everyone agrees what the convention is. Conventions are assumptions. Your brain has to know them since they are no longer in the code. If this approach fails for you, write a test that validates your assumptions.
Check that code throws the exceptions that you expect.
If you have found a bug in a framework and added a workaround, add a test which fails when the bug is fixed. Add a comment “If this test fails, you can remove the workaround.”
The world speeds up. No one can afford slow tests, tests that are hard to understand, hard to maintain, tests that get in the way of Get-Things-Done™. Make sure you can run your tests at the touch of a button. Make sure they never fail unless they should. Make sure they fail when they should. Make sure they are small (= execute fast, few lines to understand, little code to write, easy to change, cheap to delete). Ten tests, each asserting a single fact, are better than one test that asserts ten facts. If your tests run for more than ten seconds, you lose.
There is code rot. But long before that, there is documentation rot. Who has time to update the comments and documentation after a code change?
Why not document code usage in tests? Tests tell you the Truth™. Why give someone 100 pages of words they can’t trust when you can give them 100 unit tests they can execute?
Make your life easier. Stop wasting time in your debugger, begging for production log files, running code in your head. Write a good test today, it will watch your back for as long as the project lives. Write a thousand good tests and they will be like an army of angels, warding you from suffering, every time you press that button.