Wednesday, January 11, 2012

Extending JUnit Rules






One of the common problems that I run into when trying to debug failed tests is visibility.  Specifically, which test failed, under what conditions.  One habit that makes this process simpler, for me, is logging test names at the start of each test executed.  The only problem with this practice is that it requires a lot of cut+pasting into each individual test... and that's a nuisance.



Fortunately, the JUnit TestWatcher class can be extended to handle this kind of routine task.  Here's a sample below, cut down from my MethodLogger project on github:

  1 package com.cegames; 
  2  
  3 import org.junit.rules.TestWatcher; 
  4 import org.junit.runner.Description; 
  5 import org.slf4j.Logger; 
  6 import org.slf4j.LoggerFactory; 
  7  
  8 public class MethodLogger extends TestWatcher
  9 { 
 10     private Logger log = null;
 11  
 12     public MethodLogger() { 
 13     } 
 14  
 15     /** 
 16      * Whenever a test starts, this method logs the name of the test. 
 17      * @param description Provided by TestWatcher, used to get  
 18      *                    method name 
 19      */ 
 20     @Override 
 21     protected void starting(Description description) {
 22         prepareLogger(description); 
 23         log.info("Starting test [{}]", description.getMethodName()); 
 24     } 
 25  
 26     /** 
 27      * If logger is not initialized, initialize it with the name of the 
 28      *   test class. 
 29      * @param description   Description provided by TestWatcher, used to  
 30      *                      get test class. 
 31      */ 
 32     private void prepareLogger(Description description) {
 33         if (log == null) {
 34             log = LoggerFactory.getLogger(description.getClassName()); 
 35         } 
 36     } 
 37      
 38 }

This can then be added to a test class with this one-liner:

@Rule MethodLogger methodLogger = new MethodLogger();

Whenever the test class is run, at the start of each test method the method name will be logged out using logback.  The github version has a few more bells and whistles (configurable logger and logging messages).  Take a look and tell me what you think... or if you've found any other keen uses for the JUnit api.

No comments:

Post a Comment