Java Unit Best Practices

This page created after MikeDuffy? asked for best practices on using JavaUnit.

Don't forget:

Please pick a topic and add comments. As usual, feel free to create links as required.

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: (JbRainsberger) If you are writing tests for existing, untested code, then do as Robert suggested:

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 SearcherTest 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 JavaDocs? (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. -- AlexeyVerkhovsky
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?
CategoryTesting: TestingFramework for Java. CategoryJava

View edit of May 26, 2013 or FindPage with title or text search