← Back to the contribution section index
A unit test is a small piece of code which is used to verify the correctness of another piece of code. Typically, unit tests are written by developers before or while they are writing new methods and classes. Using these tests, the developer can prove that his code works in the way he intended.
Unit tests for a project are generally executed at regular intervals and/or when CVS commits occur. All tests should succeed at all times. Whenever a test detects broken code, this should be fixed first.
Consistently using unit testing has several advantages:
You can depend on your code, since the tests prove it to be correct
When a code change in one method causes a problem in other parts of the code, it will immediately be detected by failing tests instead of when someone accidentally uses the now failing feature (which can be weeks later).
Unit tests can be regarded at as extra free method documentation, since they provide examples of how the code should react in certain scenarios. Unlike written documentation, this executable documentation will not drift away from the code with time.
Even though writing tests takes time, you'll spend much less time debugging and reworking existing code.
Writing tests leads to a better code design: when it appears difficult to write a test for a method, there's usually something wrong with the code itself. Often, code can be refactored into a better design.
Are the results right?
Are all the boundary conditions CORRECT?
Conformance: Does the value conform to an expected format?
Ordering: Is the set of values ordered or unordered as appropriate?
Range: Is the value within reasonable minimum and maximum values?
Reference: Does the code reference anything external that isn’t under direct control of the code itself?
Existence: Does the value exist? (e.g., is non-null, non-zero, present in a set, etc.)
Cardinality: Are there exactly enough values?
Time (absolute and relative): Is everything happening in order? At the right time? In time?
Can you check inverse relationships?
Can you cross-check results using other means?
Can you force error conditions to happen?
Are performance characteristics within bounds?
Note: these guidelines were taken from the summary card for the Pragmatic Unit Testing book. More details can be found in there.
Automatic: No user interaction is required to run the tests or verify the results.
Thorough: Test anything that's likely to break.
Repeatable: The tests should be able to run over and over again, in any order, and produce the same results.
Independent: Tests should be independent from the environment and from each other. Only one thing should be tested at a time.
Professional: Test code should be written using the same high standards as “real” code. All the usual
Coding and
Design Guidelines must be followed for test code as well.