You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by js...@apache.org on 2021/05/19 12:09:20 UTC
[sling-org-apache-sling-junit-core] branch master updated:
SLING-10394 - JUnit Core's HtmlReporter does not correctly report failed
assumptions
This is an automated email from the ASF dual-hosted git repository.
jsedding pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-junit-core.git
The following commit(s) were added to refs/heads/master by this push:
new 6be67ce SLING-10394 - JUnit Core's HtmlReporter does not correctly report failed assumptions
6be67ce is described below
commit 6be67ce6ff4ad7674596cfb9045501a89e132cc9
Author: Julian Sedding <js...@apache.org>
AuthorDate: Wed May 19 14:03:15 2021 +0200
SLING-10394 - JUnit Core's HtmlReporter does not correctly report failed assumptions
---
pom.xml | 31 ++++-
.../sling/junit/impl/servlet/HtmlRenderer.java | 20 ++-
.../junit5/JUnit5TestExecutionStrategy.java | 25 ++--
.../junit/impl/servlet/junit5/ResultAdapter.java | 2 +-
.../impl/servlet/junit5/RunListenerAdapter.java | 17 ++-
.../sling/junit/impl/servlet/HtmlRendererTest.java | 139 +++++++++++++++++++++
6 files changed, 216 insertions(+), 18 deletions(-)
diff --git a/pom.xml b/pom.xml
index 689c83b..9e68ab1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,14 +37,17 @@
<junit.version>4.13</junit.version>
<hamcrest.version>1.3</hamcrest.version>
<jacoco.version>0.6.2.201302030002</jacoco.version>
+ <junit-jupiter.version>5.7.1</junit-jupiter.version>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
</properties>
<scm>
<connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-junit-core.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-junit-core.git</developerConnection>
<url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-junit-core.git</url>
- <tag>HEAD</tag>
- </scm>
+ <tag>HEAD</tag>
+ </scm>
<build>
<plugins>
@@ -313,11 +316,33 @@
</dependency>
<dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>${junit-jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <version>${junit-jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>${junit-jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
- <version>5.6.2</version>
+ <version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
diff --git a/src/main/java/org/apache/sling/junit/impl/servlet/HtmlRenderer.java b/src/main/java/org/apache/sling/junit/impl/servlet/HtmlRenderer.java
index fc00239..4120128 100644
--- a/src/main/java/org/apache/sling/junit/impl/servlet/HtmlRenderer.java
+++ b/src/main/java/org/apache/sling/junit/impl/servlet/HtmlRenderer.java
@@ -103,7 +103,7 @@ public class HtmlRenderer extends RunListener implements Renderer,RendererFactor
}
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
- output = response.getWriter();
+ setWriter(response.getWriter());
output.println("<html><head>");
output.println("<link rel='stylesheet' type='text/css' href='" + ServletProcessor.CSS + "'/>");
output.print("<title>");
@@ -114,6 +114,10 @@ public class HtmlRenderer extends RunListener implements Renderer,RendererFactor
output.println("</h1>");
}
+ public void setWriter(PrintWriter writer) {
+ output = writer;
+ }
+
public void cleanup() {
output.println("</body>");
output.println("</html>");
@@ -125,6 +129,18 @@ public class HtmlRenderer extends RunListener implements Renderer,RendererFactor
}
@Override
+ public void testAssumptionFailure(Failure failure) {
+ super.testAssumptionFailure(failure);
+ output.print("<p class='ignored'><h3>TEST ABORTED</h3><b>");
+ String message = failure.getMessage();
+ if (!message.startsWith("Assumption failed: ")) {
+ message = "Assumption failed: " + message;
+ }
+ HtmlFilter.escape(output, message);
+ output.println("</b></p>");
+ }
+
+ @Override
public void testFailure(Failure failure) throws Exception {
super.testFailure(failure);
output.print("<div class='failure'><h3>");
@@ -176,6 +192,8 @@ public class HtmlRenderer extends RunListener implements Renderer,RendererFactor
counter("failures", "failureCount", result.getFailureCount());
output.print(", ");
counter("ignored", "ignoredCount", result.getIgnoreCount());
+ output.print(", ");
+ counter("aborted", "abortedCount", result.getAssumptionFailureCount());
output.println("</p>");
}
diff --git a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/JUnit5TestExecutionStrategy.java b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/JUnit5TestExecutionStrategy.java
index 52c4c00..7363374 100644
--- a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/JUnit5TestExecutionStrategy.java
+++ b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/JUnit5TestExecutionStrategy.java
@@ -21,7 +21,9 @@ package org.apache.sling.junit.impl.servlet.junit5;
import org.apache.sling.junit.TestSelector;
import org.apache.sling.junit.impl.TestExecutionStrategy;
import org.apache.sling.junit.impl.TestsManagerImpl;
+import org.jetbrains.annotations.NotNull;
import org.junit.platform.engine.DiscoverySelector;
+import org.junit.platform.engine.TestEngine;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
@@ -71,27 +73,34 @@ public class JUnit5TestExecutionStrategy implements TestExecutionStrategy {
@Override
public void execute(TestSelector selector, RunListener runListener) throws Exception {
- Launcher launcher = LauncherFactory.create(
+ Launcher launcher = createLauncher(runListener, testEngineTracker.getAvailableTestEngines());
+ final LauncherDiscoveryRequest request = testsManager.createTestRequest(selector,
+ JUnit5TestExecutionStrategy::methodRequest,
+ JUnit5TestExecutionStrategy::classesRequest);
+ launcher.execute(request);
+ }
+
+ @NotNull
+ public static Launcher createLauncher(RunListener runListener, TestEngine... availableTestEngines) {
+ return LauncherFactory.create(
LauncherConfig.builder()
- .addTestEngines(testEngineTracker.getAvailableTestEngines())
+ .addTestEngines(availableTestEngines)
.addTestExecutionListeners(new RunListenerAdapter(runListener))
.enableTestEngineAutoRegistration(false)
.enableTestExecutionListenerAutoRegistration(false)
.build()
);
-
- final LauncherDiscoveryRequest request =
- testsManager.createTestRequest(selector, this::methodRequest, this::classesRequest);
- launcher.execute(request);
}
- private LauncherDiscoveryRequest methodRequest(Class<?> testClass, String testMethodName) {
+ @NotNull
+ public static LauncherDiscoveryRequest methodRequest(Class<?> testClass, String testMethodName) {
return LauncherDiscoveryRequestBuilder.request()
.selectors(selectMethod(testClass, testMethodName))
.build();
}
- private LauncherDiscoveryRequest classesRequest(Class<?>[] testClasses) {
+ @NotNull
+ public static LauncherDiscoveryRequest classesRequest(Class<?>... testClasses) {
final DiscoverySelector[] selectors = Stream.of(testClasses)
.map(DiscoverySelectors::selectClass)
.toArray(DiscoverySelector[]::new);
diff --git a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/ResultAdapter.java b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/ResultAdapter.java
index 8119527..3241aa7 100644
--- a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/ResultAdapter.java
+++ b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/ResultAdapter.java
@@ -65,7 +65,7 @@ public class ResultAdapter extends Result {
@Override
public int getAssumptionFailureCount() {
- return 0;
+ return (int) summary.getTestsAbortedCount();
}
@Override
diff --git a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/RunListenerAdapter.java b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/RunListenerAdapter.java
index 67c73fc..d598ade 100644
--- a/src/main/java/org/apache/sling/junit/impl/servlet/junit5/RunListenerAdapter.java
+++ b/src/main/java/org/apache/sling/junit/impl/servlet/junit5/RunListenerAdapter.java
@@ -91,12 +91,19 @@ public class RunListenerAdapter implements TestExecutionListener {
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
summarizer.executionFinished(testIdentifier, testExecutionResult);
if (testIdentifier.isTest()) {
- if (testExecutionResult.getStatus() != TestExecutionResult.Status.SUCCESSFUL) {
- try {
- runListener.testFailure(FailureHelper.convert(testIdentifier, testExecutionResult.getThrowable().orElse(null)));
- } catch (Exception exception) {
- throw new RuntimeException(exception);
+ try {
+ switch (testExecutionResult.getStatus()) {
+ case FAILED:
+ runListener.testFailure(FailureHelper.convert(testIdentifier, testExecutionResult.getThrowable().orElse(null)));
+ break;
+ case ABORTED:
+ runListener.testAssumptionFailure(FailureHelper.convert(testIdentifier, testExecutionResult.getThrowable().orElse(null)));
+ break;
+ case SUCCESSFUL:
+ break;
}
+ } catch (Exception exception) {
+ throw new RuntimeException(exception);
}
withDescription(testIdentifier, runListener::testFinished);
} else {
diff --git a/src/test/java/org/apache/sling/junit/impl/servlet/HtmlRendererTest.java b/src/test/java/org/apache/sling/junit/impl/servlet/HtmlRendererTest.java
new file mode 100644
index 0000000..dd86d3d
--- /dev/null
+++ b/src/test/java/org/apache/sling/junit/impl/servlet/HtmlRendererTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.junit.impl.servlet;
+
+import org.apache.sling.junit.impl.servlet.junit5.JUnit5TestExecutionStrategy;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.engine.JupiterTestEngine;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.platform.engine.TestEngine;
+import org.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.LauncherDiscoveryRequest;
+import org.junit.runner.notification.RunListener;
+import org.junit.vintage.engine.VintageTestEngine;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.stream.Stream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class HtmlRendererTest {
+
+ @SuppressWarnings("unused")
+ private static Stream<Arguments> testEngines() {
+ return Stream.of(
+ Arguments.of("junit4", new VintageTestEngine()),
+ Arguments.of("jupiter", new JupiterTestEngine())
+ );
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("testEngines")
+ public void testInvalidAssumption(String prefix, TestEngine testEngine) {
+ String html = renderHtmlOutput(testEngine, ExampleTestCases.class, prefix + "FailedAssumption");
+ assertThat(html, Matchers.containsString(
+ String.format("<p class='ignored'><h3>TEST ABORTED</h3><b>Assumption failed: %s</b></p>",
+ ExampleTestCases.ASSUMPTION_IS_ALWAYS_INVALID)));
+ assertThat(html, Matchers.containsString("<span class='testCountNonZero'>tests:1</span>"));
+ assertThat(html, Matchers.containsString("<span class='abortedCountNonZero'>aborted:1</span>"));
+ }
+
+ @ParameterizedTest
+ @MethodSource("testEngines")
+ public void testFailure(String prefix, TestEngine testEngine) {
+ final String failedAssertion = "FailedAssertion";
+ String html = renderHtmlOutput(testEngine, ExampleTestCases.class, prefix + failedAssertion);
+ assertThat(html, Matchers.containsString("class='failure'"));
+ assertThat(html, Matchers.containsString("class='failureDetails'"));
+ assertThat(html, Matchers.containsString(String.format("<h3>TEST FAILED: %s%s(%s)</h3>", prefix, failedAssertion, ExampleTestCases.class.getName())));
+ assertThat(html, Matchers.containsString(ExampleTestCases.ASSERTION_ALWAYS_FAILS));
+ assertThat(html, Matchers.containsString("<span class='testCountNonZero'>tests:1</span>"));
+ assertThat(html, Matchers.containsString("<span class='failureCountNonZero'>failures:1</span>"));
+ }
+
+ @ParameterizedTest
+ @MethodSource("testEngines")
+ public void testSuccess(String prefix, TestEngine testEngine) {
+ String html = renderHtmlOutput(testEngine, ExampleTestCases.class, prefix + "Success");
+ assertThat(html, Matchers.containsString("<span class='testCountNonZero'>tests:1</span>"));
+ assertThat(html, Matchers.containsString("<span class='failureCountZero'>failures:0</span>"));
+ }
+
+ private static String renderHtmlOutput(TestEngine testEngine, Class<ExampleTestCases> testClass, String methodName) {
+ final StringWriter out = new StringWriter();
+ final HtmlRenderer htmlRenderer = new HtmlRenderer();
+ htmlRenderer.setWriter(new PrintWriter(out));
+ runTest(testEngine, htmlRenderer, testClass, methodName);
+ return out.toString();
+ }
+
+ private static void runTest(TestEngine testEngine, RunListener runListener, Class<?> testClass, String methodName) {
+ final Launcher launcher = JUnit5TestExecutionStrategy.createLauncher(runListener, testEngine);
+ final LauncherDiscoveryRequest request = methodName != null
+ ? JUnit5TestExecutionStrategy.methodRequest(testClass, methodName)
+ : JUnit5TestExecutionStrategy.classesRequest(testClass);
+ launcher.execute(request);
+ }
+
+ public static class ExampleTestCases {
+
+ public static final String ASSUMPTION_IS_ALWAYS_INVALID = "Assumption is always invalid";
+
+ public static final String ASSERTION_ALWAYS_FAILS = "Assertion always fails";
+
+ public static final String ASSERTION_ALWAYS_SUCCEEDS = "Assertion always succeeds";
+
+ @org.junit.jupiter.api.Test
+ public void jupiterFailedAssumption() {
+ Assumptions.assumeFalse(true, ASSUMPTION_IS_ALWAYS_INVALID);
+ }
+
+ @org.junit.jupiter.api.Test
+ public void jupiterFailedAssertion() {
+ Assertions.fail(ASSERTION_ALWAYS_FAILS);
+ }
+
+ @org.junit.jupiter.api.Test
+ public void jupiterSuccess() {
+ Assertions.assertTrue(true, ASSERTION_ALWAYS_SUCCEEDS);
+ }
+
+ @org.junit.Test
+ public void junit4FailedAssumption() {
+ Assume.assumeFalse(ASSUMPTION_IS_ALWAYS_INVALID, true);
+ }
+
+ @org.junit.Test
+ public void junit4FailedAssertion() {
+ Assert.fail(ASSERTION_ALWAYS_FAILS);
+ }
+
+ @org.junit.Test
+ public void junit4Success() {
+ Assert.assertTrue(ASSERTION_ALWAYS_SUCCEEDS, true);
+ }
+ }
+}
\ No newline at end of file