user-icon Stefan Ludwig
27. March 2017
timer-icon 1 min

Suppressing Logs in Successful Tests

Application logs are very useful when trying to understand why an application did what it did. This is also true when you debug a failing test. They are less useful while your tests are succeeding. Then they are just irritating and unnecessary clutter. Especially when they contain expected exceptions of those tests.

I recently got so fed up with these kinds of logs, that I wrote a small library for suppressing them. What it does is quite simple:

  1. It stores all existing loggers and their configured appenders.
  2. Before executing a test, it replaces all appenders with a RecordingAppender.
  3. While the tests are executed, this appender remembers all logging events.
  4. After the test was executed, it restores the original logger configuration.
  5. Only if the test failed, the collected log events are sent to their corresponding original appenders.

The library is licensed under Apache 2.0 and available on Maven Central:


You can check out the source code on GitHub. Included in this library is a JUnit 4 Rule and a JUnit 5 Extension. Additionally it is assumed, that logging is done with Logback.

Examples

Class Under Test


In JUnit 5


In JUnit 4

Comment article

Comments

  1. Rusty Phillips

    This is a pretty good idea!

    Choosing to implement this as a rule is perhaps not as good a choice as you could have since you’d probably want it to be defined on every single test, and that means having to add a rule to every single class, or having every single class inherit from a single class – both of which seem like bad ideas.

    Have you considered setting it up as a runlistener instead?

    Then you need only add it to your surefire/failsafe config (both of which can take runlisteners as arguments) and it’ll run for each test.

    • Stefan Ludwig

      Thanks!

      Yeah, if used at scale, it should probably be implemented on a more global level. Either as a lifecycle listener, like you mentioned, for Maven or Gradle, or as a globally registered extension for JUnit 5. I would prefer a JUnit 5 based solution because it would apply the suppression even if tests are executed outside a regular build (e.g. explicitly in your IDE).