It is easy to become overwhelmed when you start writing unit tests. The best way to start is to create unit tests for new
code. (It is difficult to start by creating unit tests for existing
code, but it is possible.) Start with new code, get used to the
process, and then revisit the existing code to create a test suite for
it. As mentioned earlier, you should write unit tests before you
write the code they will test. How can you write a test for something
that doesn't exist yet? Very good question, Grasshopper. Mastering this
practice is ninety percent mental and ten percent technical. What I
mean is that you simply pretend that the class you are writing the test
for exists. Then write the test. Initially you will get a lot of syntax
errors, but stay with it. What you are doing through this exercise is
defining the interface that the class will implement. The next step is
to run your unit tests, fix the syntax errors (that is, implement the
class with the interfaces just defined by your test), and run the tests
again. Repeat this process, each time writing just enough code to fix
the failures. Run the tests until they pass. The code is "done" when
all of the unit tests pass. In general, there should be a unit
test for every public method of your class. However, methods with very
straightforward functionality, for example, getter and setter methods,
don't need unit tests unless they do their getting and setting in some
"interesting" way. A good guideline to follow is to write a unit test
whenever you feel the need to comment some behavior in the code. If
you're like many programmers who aren't fond of commenting code, unit
tests are a way of documenting your code behavior. Put the unit
tests in the same package as the associated classes being tested. This
type of organization allows each unit test to call methods and
reference variables that have access modifiers of package or protected in the class being tested. Avoid
using domain objects in unit tests. Domain objects are objects specific
to an application. For example, a spreadsheet application might have a
register object; this object would be a domain object. If you have a
class that already knows about the domain objects, it is fine to use
these objects in your tests. But if you have a class that isn't using
these objects, do not tie these objects to the class through the tests.
The reason this practice should be avoided is all wrapped up with code
reuse. Very often the classes created for a project apply to other
projects. Reusing these classes may be straightforward. But if the
tests for the reused classes use another project's domain objects,
getting the tests to work can become a very time-consuming activity.
Usually the test will either be dropped or rewritten. These
mechanics will serve you well, but a comprehensive suite of unit tests
will not be worth anything if you don't run the tests. Running the
tests early and often gives you absolute confidence in your code all
the time. As the project proceeds, you will add features. Running the
tests will tell you if the new features you've just implemented have
broken something. Revisit your existing code after you have
mastered the mechanics of writing unit tests. Writing tests for
existing code can be a challenge. Don't test for testing sake. Write
tests in a "just-in-time" fashion, when you find the need to modify a
class that doesn't have good (or any) tests. That is the time to add
the tests. As always, the unit tests for that class should capture the
functionality for each of its methods. One of the easiest ways to find
out what the test should be testing is to look at the comments in the
existing code. Any comment should be captured in a unit test. Translate
block comments at the beginning of methods describing what the method
does into unit tests.
|