My Wednesday at JavaOne 2010 began with John Ferguson Smart‘s standing-room-only presentation “JUnit Kung Fu: Getting More Out of Your Unit Tests.” Most of the overcapacity audience responded in the affirmative when Smart asked who uses JUnit. While the majority of the audience uses JUnit 4, some do use JUnit 3. Only a small number of individuals raised their hands when asked who uses Test-Driven Development (TDD).
Smart stated that appropriate naming of tests is a significant tool in getting the most out of JUnit-based unit tests. He mentioned that JUnit 4 enables this by allowing for annotations to specify the types of tests rather than having to use the same method name conventions that earlier versions of JUnit requires. In the slide, “What’s in a name,” Smart pointed out that naming tests appropriately helps express the behavior of the application being tested. Smart likes to say he doesn’t write tests for his classes. Instead, classes get tested “as a side effect” for his testing of desired behaviors. Smart recommended that you don’t test “how it happens,” but test “what it does.” If your implementation changes, your test doesn’t necessarily need to change because you’re only worried about outcomes and not how the outcomes are achieved. Smart talked about how appropriately named tests are more readable for people new to the tests and also provide the benefit of helping test the appropriate things (behaviors).
Smart outlined many naming tips in his slide “What’s in a name” (only a subset it listed here):
- Don’t use the word “test” in your tests (use “should” instead)
- Write your tests consistently
- Consider tests as production code
Smart demonstrated using parameterized tests in web application testing using Selenium 2. The purpose of this demonstration was to show that parameterized tests are not limited solely to numeric calculations.
Smart next covered JUnit Rules. He specifically discussed TemporaryFolder Rule, ErrorCollector Rule, Timeout Rule, Verifier Rule, and Watchman Rule. The post JUnit 4.7 Per-Test Rules also provides useful coverage of these rules.
Smart believes that recently added JUnit Categories will be production-ready once adequate tooling is available. You currently have to run JUnit Categories using JUnit test suites (the other work-around involves “mucking around with the classpath”). Smart’s Grouping Tests Using JUnit Categories talks about JUnit Categories in significantly more detail.
Parallel tests can lead to faster running of tests, especially when multiple CPUs are available (common today). Smart showed a slide that indicated how to set up parallel tests in JUnit with Maven. This requires JUnit 4.8.1 and Surefire 2.5 (Maven).
Smart recommended that those not using a mocking framework should start using a mocking framework to make unit testing easier. He suggested that those using a mocking framework other than Mockito might look at Mockito for making their testing even easier. He stated that Mockito’s mocking functionality is achieved with very little code or formality. The JUnit page on Mockito has this to say about Mockito:
Java mocking is dominated by expect-run-verify libraries like EasyMock or jMock. Mockito offers simpler and more intuitive approach: you ask questions about interactions after execution. Using mockito, you can verify what you want. Using expect-run-verify libraries you often look after irrelevant interactions.
Mockito has similar syntax to EasyMock, therefore you can refactor safely. Mockito doesn’t understand the notion of ‘expectation’. There is only stubbing or verifications.
Smart stated in his presentation and then reaffirmed in the questions and answers portion that private methods should not be unit tested. His position is that if a developer is uncomfortable with them enough to unit test them individually, that developer should consider refactoring them into their own testable class. For me, this fits with his overall philosophy of testing behaviors rather than testing “how.” See the StackOverflow thread What’s the best way of unit testing private methods? for interesting discussion that basically summarizes common arguments for and against testing private methods directly.
Smart had significant substance to cover and ran out of time (Smart quipped that we had “approximately minus 20 seconds for questions”). This is my kind of presentation! In many ways, it was like trying to drink from a fire hose, but I loved it! There are numerous ideas and frameworks he mentioned that I plan to go spend quality time investigating further. I’m especially interested in the things that both he and Neal Ford talked about.
DISCLAIMER: As with all my reviews of JavaOne 2010 sessions, this post is clearly my interpretation of what I thought was said (or what I thought I heard). Any errors or misstatements are likely mine and not the speaker’s and I recommend assuming that until proven otherwise. If anyone is aware of a misquote or misstatement in this or any of my JavaOne 2010 sessions reviews, please let me know so that I can fix it.