Specific
Measurable
Attainable
Reasonable
Timely
After some thought, I realized that this also applies to tests.
- Specific - A test should target one specific feature or behavior. The name of the test should be representative of what that behavior or feature is. When I name my tests in this way, as soon as the test failure is seen, I know what's broken. By looking at a few lines of code, I should know where the cause of the failure is. If I can't tell by looking at the code, my test is not specific enough. This also relates to the one (conceptual) assert per test idea. Like the high-contrast target above, you want to be able to tell, instantly, what went wrong.
- Measurable - If you can't measure what you're attempting to test, it's pointless. For example, I don't test that the screen is drawn pixel perfect. It's not easily measurable. To attempt to test it would be a waste of my time. Manual tests are still tests; use them. TDD isn't a panacea.
- Accurate - I consider a test accurate if it meets two requirements. First, it's name must represent the behavior being tested. Second, I must be able to look at the test and very quickly ascertain that it does what it says it does. Uncle Bob Martin's book, Clean Code, describes a good function as one that has a single abstraction -- one that can't be refactored any further.
- Responsible - I shouldn't have to say this, but tests should NOT have side-effects. Tests with side-effects destroy any confidence that a later test may, or may not, be correct. Don't write tests with side effects.
- Timely - Long-running tests are less-run tests. If a test isn't fast, I'm not going to run it as often. And, when I do run it, I'm likely to get distracted and start answering lots of Stack Overflow questions while I'm waiting for it to run.
[Image from: http://www.ctc.com.pt/fotos_20061007.html]
No comments:
Post a Comment