Sergio Sergio - 29 days ago 7
Java Question

Discovering test with JUnit 5 doesn't execute LoggingListener (implementation of TestExecutionListeners)

I'm using JUnit Jupiter version 5.0.0 (Release version) and I'm trying to use the test discovery feature.
The documentation of Junit can be found in 7.1.1. Discovering Tests from http://junit.org/junit5/docs/5.0.0/user-guide/#launcher-api-discovery

My implementation is:

import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;

import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.LoggingListener;

public class MainPrueba {

public static void main(String[] args) throws InterruptedException {

Runnable task = () -> {
System.out.println("Runing thread INI");

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(
selectPackage("org.package.qabootfx.test.ping")
//,selectClass(QabootfxApplicationTests.class)
)
.filters(
//includeClassNamePatterns(".*Test")
includeClassNamePatterns(".*")
)
.build();

Launcher launcher = LauncherFactory.create();

TestPlan testPlan = launcher.discover(request);

for (TestIdentifier root : testPlan.getRoots()) {
System.out.println("Root: " + root.toString());

for (TestIdentifier test : testPlan.getChildren(root)) {
System.out.println("Found test: " + test.toString());
}
}

// Register a listener of your choice
//TestExecutionListener listener = new SummaryGeneratingListener();
TestExecutionListener listener = LoggingListener.forJavaUtilLogging(); //new LoggingListener();
launcher.registerTestExecutionListeners(listener);


launcher.execute(request);

System.out.println("Runing thread END");

};
new Thread(task).start();

Thread.sleep(5000);
System.out.println("END");
}

}


Examining LoggingListener class implementation we can see that this must print to the console the results. For example:

package org.junit.platform.launcher.listeners;

@API(status = MAINTAINED, since = "1.0")
public class LoggingListener implements TestExecutionListener {

....

@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
log("TestPlan Execution Started: %s", testPlan);
}

@Override
public void testPlanExecutionFinished(TestPlan testPlan) {
log("TestPlan Execution Finished: %s", testPlan);
}

...

}


and my Test class is:

public class QabootfxApplicationTest {

@Test
public void testAbout() {
System.out.println("TEST Execution.... QabootfxApplicationTests.testAbout()");

assertEquals(4, 5, "The optional assertion message is now the last parameter.");
}
}


I'm expecting see in the console something similar to:

2017-09-20 10:53:48.041 INFO 11596 --- TestPlan Execution Started: ....
2017-09-20 10:53:48.041 INFO 11596 --- TestPlan Execution Finished: ....


but I can't see nothing similar to "... TestPlan Execution Started...".

The console output is:

Runing thread INI
Root: TestIdentifier [uniqueId = '[engine:junit-jupiter]', parentId = null, displayName = 'JUnit Jupiter', legacyReportingName = 'JUnit Jupiter', source = null, tags = [], type = CONTAINER]
Found test: TestIdentifier [uniqueId = '[engine:junit-jupiter]/[class:org.package.qabootfx.test.ping.QabootfxApplicationTest]', parentId = '[engine:junit-jupiter]', displayName = 'QabootfxApplicationTest', legacyReportingName = 'org.package.qabootfx.test.ping.QabootfxApplicationTest', source = ClassSource [className = 'org.package.qabootfx.test.ping.QabootfxApplicationTest', filePosition = null], tags = [], type = CONTAINER]
TEST Executon.... QabootfxApplicationTests.testAbout()
Runing thread END
END


Could be a bug? or I'm implementing something wrong?

Answer Source

Why would you expect the listener created by LoggingListener.forJavaUtilLogging() to log anything at log level INFO... when the documentation explicitly states the following?

Create a LoggingListener which delegates to a java.util.logging.Logger using a log level of FINE.

If you want the LoggingListener to log messages at level INFO, you'll have to create it using the other factory method which accepts a log level like this LoggingListener.forJavaUtilLogging(Level.INFO).