The Art of Test Driven Development: Per-Test Logging

Log4j logoAll applications complex enough have a logging subsystem. When writing tests, it is often useful to enable a specific logging configuration for a given test case. In this article, I will show how to use Apache Log4j and JUnit to achieve this goal.

Log4j is the granddaddy of logging framework and yes, I am partial to it as one of its developers and member of its Project Management Committee. I find it far superior, as we are about to release version 2.4, to all of its cousins. JUnit and the best practice of Test Driven Development should need no introduction; if you use neither, then I welcome you to the 21st century and its ‘extreme’ or ‘agile’ development practices.

When you are running a larger build with thousands of tests or even a small build with dozens, you do not want to set the logging level to debug or trace for the whole build. A small subsystem can end up generating a large amount of log events, leaving you with the task equivalent to finding a needle in a haystack in order to locate the few logging events relevant to your development session.

What I want, is to tell JUnit that a given test case should run with a specific Log4j configuration and then forget this configuration when the test finishes. To accomplish this, we will use a JUnit Rule and Log4j’s LoggerContextRule (This class is located in Log4j’s test jar. Log4j 2.3 named this class InitialContextRule).

Here is our test boilerplate:

public class MyTest {

  public LoggerContextRule ctx = 
    new LoggerContextRule("resources/MyConfig.xml");

  public void testSomething() throws Exception {
    // testing…


In JUnit, a @Rule annotates a field that points to a rule or a method that returns a rule. In our case, we store our rule in an instance variable, which must be public and non-static. A rule will run methods annotated with @Before, then @Test methods, and finally @After methods. JUnit throws an exception when any of these fail. The code for the rule itself runs before each @Before method. This means we get a fresh logging configuration for each @Test method.

The LoggerContextRule argument is a URI or path to a configuration file on your classpath.

If you want the rule to run only once for the whole test class, then use a class rule instead:

public static LoggerContextRule ctx = 
  new LoggerContextRule("resources/MyConfig.xml");

Note that the variable is now static (and still public).

Whether you should use a rule or a class rule depends on how much isolation you want between test methods. In the case of logging, it should not matter and using a class rule should be preferred since your build be faster.

You can find the Log4j rule class in the Core’s test jar here.

Happy Coding,
Gary Gregory

2 thoughts on “The Art of Test Driven Development: Per-Test Logging

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s