This page created after MikeDuffy?
asked for best practices on using JavaUnit
Don't forget: http://www.javaworld.com/javaworld/jw-12-2000/jw-1221-junit.html
Please pick a topic and add comments. As usual, feel free to create links
Please keep things simple! It is not a newsgroup discussion but a help for people trying to avoid making mistakes. So don't enumerate every mistake possible and explain why it's a mistake! For each chapter, propose a general point of view and say why it is commonly accepted. Don't go into the details like "if you are using X, you may prefer to place your tests..." because it will be endless. (VladimirBossicard
If there's no link, then you need to add one!
Do I catch or throw exceptions when testing a method?
Neither. If you are expecting the exception, obviously you're going to catch it, as per CodingJavaUnitExceptionTests
. If you're not expecting it, it's an error. Simply declare that the test method throws Exception (thus avoiding the compile-time issues), and let the framework handle it. The framework will report it as an error, and note that the test failed.
You may not like declaring "throws Exception", because you would never write production code that way. (Right?!) Rather than think, "tests are not production code; therefore, I can slack off," think of this: you specify the exceptions to throw in your production code to communicate to the client. Your goal is to give your client a chance to handle the errors in a meaningful way. JavaUnit
doesn't care, it has never cared and it will likely never care, so don't waste your effort. -- JbRainsberger
What naming conventions should I use for test classes and test methods?
What I (RobertWatkins
) use is the following:
- Name the TestCase class after the class that is mostly being tested. A test for SomeClass becomes SomeClassTest
- Because a test should only test one aspect of the component under test, if there is a few things about a method that I want to test (particularly error handling), I write variant test methods. An example would be testDoSomethingNoSpoon(), if I wanted to see what happens if ThereIsNoSpoon.
) If you are writing tests for existing, untested code, then do as Robert suggested:
- Name the test method after the method in the class that is being tested. The method doSomething() gets a test method called testDoSomething()
If, however, you are writing tests for new features, name the test method for the feature you are trying to test, even if there is no such method. If you are testing how your Searcher behaves when it tries to find Documents in an empty Library, add a test case to class Searcher
Test named testEmptyLibrary(). In this method, test that your Searcher does not blow up and that no matter what document you search for, none is found.
Distinguish the names of test classes from the names of production classes in a way that can never
be ambiguous. For example, it is conceivable that a class ending with "Test" might be defined in a third-party package. However, it is against the Java coding conventions to use underscores in class names. Therefore test classes that end with "_Test" can be unambiguously distinguished from functional classes. This allows you to do all sorts of clever things with reflection. (see OrganizeJavaUnitTests
What about documenting test methods? Full-blown method-level JavaDoc
s? (Including @throws?) Or just a one-liner? -- DavidPlass
Depends what do you use it for. For unit tests, a class Javadoc comment and good, self-explanative names for test methods is usually enough.
How about assertXXX message strings? Is it always best to use them? If used, should they describe the correct behavior or the failed behavior? i.e. assertTrue("something is true", something) vs assertTrue("something isn't true", something)?
Of course punting is also common e.g. assertTrue( "something should be true", something)
. -- GregWiley?
I recommend this option, as it's not ambiguous. -- GeorgeDinwiddie
I agree if there isn't a convention otherwise. For the first question, I'd say that the decision to use an informative message should be similar to the decision to include a comment. If it adds no value (restates the obvious), then forget it. So assertEquals("objects should be equal", o1, o2)
is a waste of time. But if the context isn't obvious, the assertion is in a loop, say, then assertEquals( o1.toString() + "should equal" + o2.toString(), o1, o2 )
could be useful. -- GregWiley?
for Java. CategoryJava