Application logging is important and occasionally important enough to make it worth creating automated tests to verify it. Enter Log Collectors, which captures log records for inspection or verification during testing.
The framework hooks into any logger it is provided and intercepts its messages, making it possible to inspect or verify them.
It is applicable in situations where you want to
- ensure that THE warning is emitted during an error
- verify that the audit logs gets populated correctly
Log Collectors currently has support for the following libraries
- Log4j2
- Logback
- java.util.logging
- slf4j (slf4j-simple, logback, log4j, java.util.logging)
It integrates directly with these testing frameworks:
The goals of the framework are
- No forced dependencies.
- Support for the most widespread logging frameworks
Feedback is appreciated. If you find the framework useful, or have suggestions for improving it, get in touch!
The following examples show how to add the framework to a test, provide it with the logger and inspect the log entries generated by testing a component.
Logger logger = LogManager.getLogger("acme.Gizmo");
@Rule
public JUnit4LogCollector collector = new JUnit4LogCollector(logger);
@Test
public void testGizmo() {
Gizmo gizmo = new Gizmo();
gizmo.run();
List<LogEvent> rawLogs = (List<LogEvent>) collector.getRawLogs();
assertTrue(rawLogs.stream().noneMatch(l -> l.getLevel() == Level.ERROR));
}
@LogCollectorExtension
public class GizmoTest {
Logger logger = LogManager.getLogger("acme.Gizmo");
JUnit5LogCollector collector = new JUnit5LogCollector(logger);
@Test
void testGizmo() {
Gizmo gizmo = new Gizmo();
gizmo.run();
List<LogEvent> rawLogs = (List<LogEvent>) collector.getRawLogs();
assertTrue(rawLogs.stream().noneMatch(l -> l.getLevel() == Level.ERROR));
}
}
To allow the extension to pick-up your Collector, the property must be annotated so reflection works correctly:
@JvmField
val collector = JUnit5LogCollector(logger)
See: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields
@Test
@Listeners(TestNGLogCollector.class)
public class GizmoTest {
final static Logger logger = LoggerFactory.getLogger("acme.Gizmo");
@BeforeTest
public void captureLogger() {
TestNGLogCollector.setLogSource(logger);
}
public void testGizmo() {
Gizmo gizmo = new Gizmo();
gizmo.run();
List<LogEvent> rawLogs = (List<LogEvent>) TestNGLogCollector.getRawLogs();
assertTrue(rawLogs.stream().noneMatch(l -> l.getLevel() == Level.ERROR));
}
}
Log Collectors is available from Maven Central.
Maven installation
<dependency>
<groupId>dk.bitcraft</groupId>
<artifactId>LogCollector</artifactId>
<version>0.9.0</version>
<scope>test</scope>
</dependency>
Gradle installation
testCompile 'dk.bitcraft:LogCollector:0.9.0'
- Come up with a better name for the framework.
- Improve Javadoc and documentation.
- Discover the intricacies of the various logging frameworks in real-world settings and adapt to them.
- Avoid the ugly cast in
getRawLogs
. - Detect SLF4j's
NOPLogger
and replace it withSimpleLogger
- Any ideas? Get in touch!