DevOps Zone is brought to you in partnership with:

Applications should be robust and extremely well designed. Whatever the domain and the medium. I fight for that with the help of talented people. I want to help you in this mission too. Fervent supporter of unit testing, refactoring, agile approach and good user experience design. Love to learn through real projects. Invent new ones if necessary. * Specialties: iOS, Java client and server development. Unit Testing, Continuous Integration. Agile Approach. User Experience and Product Improvement. Eclipse RCP, JFreeChart, OpenGL, Data Visualizations. Jean-baptiste is a DZone MVB and is not an employee of DZone and has posted 7 posts at DZone. You can read more from them at their website. View Full User Profile

Unit Testing Checklist: Keep Your Tests Useful and Avoid Big Mistakes

06.16.2014
| 6431 views |
  • submit to reddit

A unit test is a set of methods launched frequently to validate your code. It is usually a good idea to write code in this order:

  1. Write a class API
  2. Write a method to test the API
  3. Implement the API
  4. Launch the unit tests

Why write unit tests? They validate current and future implementations. They measure code quality. They force you to write testable, loosely coupled code. They’re cheaper than manual regression testing. They build confidence in your code. They help teamwork.

Why use a checklist? Unit testing can be harder than actual implementation. Unit testing forces you to really think things through. But unit tests should be simple, direct, and easy to read and maintain. You also need to know when to stop writing tests and start writing the implementation.

Use this checklist to be sure your tests are really useful and to the point. Remember: the checklist helps you avoid big mistakes, but you need to make sure of the following:

  My test class is testing only one class.

  • o  You are testing a class API to be sure the public contract is respected.

  My methods are testing only one method at a time.

  • o  Be sure not to test private methods! They are hidden implementation details, not API.

  My variables and method names are explicit.

  • o  For example, store an expected value in an expectedFoo variable instead of just foo. If you test many combinations, use composed variable names like inputValue_NotNull, inputValue_ZeroData, inputValue_PastDate, etc. (according to your application’s coding convention).

  My test cases are easy to read by humans.

  • o  Future maintainers should be able to read your tests before reading the implementation. This will help them understand a class API before tweaking or debugging it.

  My tests respect the usual clean code standards.

  • o  There should be no flow control in a test method (switch, if, etc.). A good test is just a very straightforward sequence of setup/validate instructions. If necessary, use sub-methods to factorize and make your tests easier to read. In case of multiple scenarios, use multiple test methods (one for each case).

  • o  For example, a test method should fit on screen without scrolling – 1 to 20 lines long. If the method is longer, consider writing multiple test methods for each case instead of jamming them together.

  My tests are also testing expected exceptions.

  • o  In java, use @Test(expected=MyException.class).

  My tests don’t need access to a database.

  • o  Or if a test does need database access, then it must be a mocked, “fire and forget” temporary database that you fill with test cases for every new test method (use the Setup/Teardown methods to prepare it).

  My tests don’t need access to network resources.

  • o You can’t rely on third parties like network or device presence to validate a method (use mocks).

  My tests control side effects, limit values (max, min) and null variables (even when they throw exceptions).

  • o  You want to make sure these problem cases never occur, even when the test won’t be used during maintenance.

  My tests can be run at any time, at any place without needing configuration or human intervention.

  My tests pass for the current implementation and are easy to evolve.

  • o  Tests really exist to support code evolution. If they are too hard to maintain or too light to refine the code, then they are a useless burden. (Many developers avoid unit testing for this reason.)

  My tests are concrete.

  • o  In Java: don’t use Date() as input for a method you are testing, but build a concrete date out of Calendar (don’t forget to force the timezone). Other example: use name = “Smith”; instead of name = “name”; or name = “test”;

  My tests use a mock to simulate/stub complex class structure or methods.

  • o  Remember to test only one class API at a time.

    o  Never test third-party libraries through your own classes. Libraries should come with their own tests (this is actually a good way to choose a library).

  My tests are never @ignored or commented out. Never. Ever.

  My tests help me validate my architecture.

  • o  If you can’t test a method or a class, your design is not agile enough.

  My tests can run on any supported platform, not just the targeted platform.

  • o  Don’t expect a particular device or hardware configuration.  Otherwise, your tests will make migration tougher and you will be incentivized to disable them.

  My tests are lightning fast!

  • o  Slow tests shouldn’t drag you down. Speed encourages you to launch your tests often. It also helps to reduce building time on Continuous Integration systems.

  • o  Use a test runner that allows you to launch one test at a time while you are writing it. Use “delay” or “sleep” with caution – i.e., only in some edge cases, like waiting for notifications or clock-based methods.


Published at DZone with permission of Jean-baptiste Rieu, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Waldemar Biller replied on Mon, 2014/06/16 - 3:32pm

What's agile design?

Jean-baptiste Rieu replied on Tue, 2014/06/17 - 7:59am in response to: Waldemar Biller

The wording is ambiguous you are right. 

agile design ~= loosely coupled 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.