From c8d1c6d5711d956a40cf617cc32491d0650c98cb Mon Sep 17 00:00:00 2001 From: "dmitrii.naumenko" Date: Thu, 20 May 2021 18:41:24 +0300 Subject: [PATCH 1/2] support multiple junit --run-listener #86 --- .../java/com/novocode/junit/JUnitRunner.java | 12 +++-- .../java/com/novocode/junit/JUnitTask.java | 3 +- .../simple/test-listener-multiple/build.sbt | 47 +++++++++++++++++++ .../src/test/java/test/JUnitListener1.java | 7 +++ .../src/test/java/test/JUnitListener2.java | 7 +++ .../src/test/java/test/JUnitListenerBase.java | 46 ++++++++++++++++++ .../src/test/scala/test.scala | 18 +++++++ .../simple/test-listener-multiple/test | 7 +++ 8 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 src/sbt-test/simple/test-listener-multiple/build.sbt create mode 100644 src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener1.java create mode 100644 src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener2.java create mode 100644 src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListenerBase.java create mode 100644 src/sbt-test/simple/test-listener-multiple/src/test/scala/test.scala create mode 100644 src/sbt-test/simple/test-listener-multiple/test diff --git a/src/main/java/com/novocode/junit/JUnitRunner.java b/src/main/java/com/novocode/junit/JUnitRunner.java index aaa63c5..92f66239 100644 --- a/src/main/java/com/novocode/junit/JUnitRunner.java +++ b/src/main/java/com/novocode/junit/JUnitRunner.java @@ -6,7 +6,7 @@ import sbt.testing.TaskDef; import java.util.*; - +import java.util.stream.Collectors; final class JUnitRunner implements Runner { private final String[] args; @@ -16,7 +16,7 @@ final class JUnitRunner implements Runner { private volatile boolean used = false; final ClassLoader testClassLoader; - final RunListener runListener; + final List runListeners; final RunStatistics runStatistics; JUnitRunner(String[] args, String[] remoteArgs, ClassLoader testClassLoader) { @@ -35,7 +35,7 @@ final class JUnitRunner implements Runner { String testFilter = ""; String ignoreRunners = "org.junit.runners.Suite"; - String runListener = null; + final List runListeners = new ArrayList<>(); for(String s : args) { if("-q".equals(s)) quiet = true; else if("-v".equals(s)) verbosity = RunSettings.Verbosity.STARTED; @@ -48,7 +48,7 @@ final class JUnitRunner implements Runner { else if("-c".equals(s)) logExceptionClass = false; else if(s.startsWith("--tests=")) testFilter = s.substring(8); else if(s.startsWith("--ignore-runners=")) ignoreRunners = s.substring(17); - else if(s.startsWith("--run-listener=")) runListener = s.substring(15); + else if(s.startsWith("--run-listener=")) runListeners.add(s.substring(15)); else if(s.startsWith("--include-categories=")) includeCategories.addAll(Arrays.asList(s.substring(21).split(","))); else if(s.startsWith("--exclude-categories=")) excludeCategories.addAll(Arrays.asList(s.substring(21).split(","))); else if(s.startsWith("-D") && s.contains("=")) { @@ -68,7 +68,9 @@ else if(s.startsWith("-D") && s.contains("=")) { new RunSettings(!nocolor, decodeScalaNames, quiet, verbosity, summary, logAssert, ignoreRunners, logExceptionClass, sysprops, globPatterns, includeCategories, excludeCategories, testFilter); - this.runListener = createRunListener(runListener); + this.runListeners = runListeners.stream() + .map(this::createRunListener) + .collect(Collectors.toList()); this.runStatistics = new RunStatistics(settings); } diff --git a/src/main/java/com/novocode/junit/JUnitTask.java b/src/main/java/com/novocode/junit/JUnitTask.java index c9b02c8..ef4b65d 100644 --- a/src/main/java/com/novocode/junit/JUnitTask.java +++ b/src/main/java/com/novocode/junit/JUnitTask.java @@ -41,7 +41,8 @@ public Task[] execute(EventHandler eventHandler, Logger[] loggers) { EventDispatcher ed = new EventDispatcher(logger, eventHandler, settings, fingerprint, taskDescription, runner.runStatistics); JUnitCore ju = new JUnitCore(); ju.addListener(ed); - if (runner.runListener != null) ju.addListener(runner.runListener); + + runner.runListeners.forEach(ju::addListener); Map oldprops = settings.overrideSystemProperties(); try { diff --git a/src/sbt-test/simple/test-listener-multiple/build.sbt b/src/sbt-test/simple/test-listener-multiple/build.sbt new file mode 100644 index 0000000..216886d --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/build.sbt @@ -0,0 +1,47 @@ +name := "test-project" + +scalaVersion := "2.10.7" + +libraryDependencies += "com.novocode" % "junit-interface" % sys.props("plugin.version") % "test" + +testOptions += Tests.Argument( + TestFrameworks.JUnit, + "-v", "-n", + "--run-listener=test.JUnitListener1", + "--run-listener=test.JUnitListener2" +) + +val listenerFile = settingKey[File]("location of the listener output") + +listenerFile := target.value / "listener.txt" + +javaOptions in Test += "-Djunit.output.file=" + listenerFile.value.getAbsolutePath + +fork in Test := true + +val checkRunListenerFile = taskKey[Unit]("Tests that the file is correct") + +checkRunListenerFile := { + val expectedContent = + """testStarted_1 testFail(TestFoo) + |testStarted_2 testFail(TestFoo) + |testFailure_1 testFail(TestFoo) + |testFailure_2 testFail(TestFoo) + |testFinished_1 testFail(TestFoo) + |testFinished_2 testFail(TestFoo) + |testStarted_1 testPass(TestFoo) + |testStarted_2 testPass(TestFoo) + |testFinished_1 testPass(TestFoo) + |testFinished_2 testPass(TestFoo) + |testRunFinished_1 + |testRunFinished_2""".stripMargin.replace("\r", "") + + val actualContent = sbt.IO.readLines(listenerFile.value).mkString("\n") + assert( + expectedContent == actualContent, + s"""Expecting content: + |$expectedContent + |Actual content: + |$actualContent""".stripMargin + ) +} diff --git a/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener1.java b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener1.java new file mode 100644 index 0000000..313de91 --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener1.java @@ -0,0 +1,7 @@ +package test; + +public class JUnitListener1 extends JUnitListenerBase { + public JUnitListener1() { + super("1"); + } +} \ No newline at end of file diff --git a/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener2.java b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener2.java new file mode 100644 index 0000000..6912df4 --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListener2.java @@ -0,0 +1,7 @@ +package test; + +public class JUnitListener2 extends JUnitListenerBase { + public JUnitListener2() { + super("2"); + } +} \ No newline at end of file diff --git a/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListenerBase.java b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListenerBase.java new file mode 100644 index 0000000..90e6251 --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/src/test/java/test/JUnitListenerBase.java @@ -0,0 +1,46 @@ +package test; + +import org.junit.*; +import java.io.*; +import org.junit.runner.*; +import org.junit.runner.notification.*; + +public abstract class JUnitListenerBase extends RunListener { + private PrintWriter pw; + private String outputFile = System.getProperty("junit.output.file"); + + private final String id; + + public JUnitListenerBase(String id) { + this.id = id; + } + + public void testRunStarted(Description description) throws Exception { + File file = new File(outputFile); + pw = new PrintWriter(new FileWriter(outputFile, /*append=*/true)); + } + public void testRunFinished(Result result) throws Exception { + pw.println("testRunFinished_" + id); + pw.close(); + } + public void testStarted(Description description) throws Exception { + pw.println("testStarted_" + id + " " + description.getDisplayName()); + pw.flush(); + } + public void testFinished(Description description) throws Exception { + pw.println("testFinished_" + id + " " + description.getDisplayName()); + pw.flush(); + } + public void testFailure(Failure failure) throws Exception { + pw.println("testFailure_" + id + " " + failure.getDescription().getDisplayName()); + pw.flush(); + } + public void testAssumptionFailure(Failure failure) { + pw.print("ASSUMPTION FAILURE"); + pw.flush(); + } + public void testIgnored(Description description) throws Exception { + pw.println("testIgnored_" + id + " " + description.getDisplayName()); + pw.flush(); + } +} \ No newline at end of file diff --git a/src/sbt-test/simple/test-listener-multiple/src/test/scala/test.scala b/src/sbt-test/simple/test-listener-multiple/src/test/scala/test.scala new file mode 100644 index 0000000..19bf246 --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/src/test/scala/test.scala @@ -0,0 +1,18 @@ +import org.junit._ + +class TestFoo { + + @Test + def testPass(): Unit = { + Thread.sleep(2000) + import Assert._ + assertEquals("Test should pass", true, true) + } + + @Test + def testFail(): Unit = { + Thread.sleep(2000) + import Assert._ + assertEquals("Test should fail", fail, true) + } +} diff --git a/src/sbt-test/simple/test-listener-multiple/test b/src/sbt-test/simple/test-listener-multiple/test new file mode 100644 index 0000000..78b6c12 --- /dev/null +++ b/src/sbt-test/simple/test-listener-multiple/test @@ -0,0 +1,7 @@ +# test that the run listener option works. +# one test passes, other fails +-> test +# Check that file has been created and is correct +> checkRunListenerFile +# Debugging. +> show definedTests From 40703e9b51e5e37724ae4d92b4b9ef294eddc319 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Sun, 23 May 2021 03:06:36 -0400 Subject: [PATCH 2/2] Update src/sbt-test/simple/test-listener-multiple/build.sbt --- src/sbt-test/simple/test-listener-multiple/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/simple/test-listener-multiple/build.sbt b/src/sbt-test/simple/test-listener-multiple/build.sbt index 216886d..781b1b0 100644 --- a/src/sbt-test/simple/test-listener-multiple/build.sbt +++ b/src/sbt-test/simple/test-listener-multiple/build.sbt @@ -2,7 +2,7 @@ name := "test-project" scalaVersion := "2.10.7" -libraryDependencies += "com.novocode" % "junit-interface" % sys.props("plugin.version") % "test" +libraryDependencies += "com.github.sbt" % "junit-interface" % sys.props("plugin.version") % Test testOptions += Tests.Argument( TestFrameworks.JUnit,