diff --git a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java
index 8a4b14233..c6f637c37 100755
--- a/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java
+++ b/pitest-maven-verification/src/test/java/org/pitest/PitMojoIT.java
@@ -580,4 +580,15 @@ public void shouldNotNullPointerWhenEnumInitializerNotCalled() throws IOExceptio
assertThat(actual).isNotEmpty();
}
+ @Test
+ public void shouldFailCleanlyWhenTestPluginMissing() throws IOException, VerificationException {
+ File testDir = prepare("/pit-missing-test-plugin");
+ verifier.executeGoal("test");
+ verifier.executeGoal("org.pitest:pitest-maven:mutationCoverage");
+
+ String actual = readResults(testDir);
+ assertThat(actual).isNotEmpty();
+ }
+
+
}
diff --git a/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/pom.xml b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/pom.xml
new file mode 100644
index 000000000..1fb6ee717
--- /dev/null
+++ b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/pom.xml
@@ -0,0 +1,41 @@
+
+ 4.0.0
+ org.example
+ junit-categories-check
+ jar
+ 1.0-SNAPSHOT
+ missing-test-plugin
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.1
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+
+ org.pitest
+ pitest-maven
+ ${pit.version}
+
+ true
+ XML
+ false
+ com.example.*
+ com.example*
+ true
+ +CLASSLIMIT(limit[6])
+
+
+
+
+
+
diff --git a/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/Covered.java b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/Covered.java
new file mode 100644
index 000000000..ea7b74b51
--- /dev/null
+++ b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/Covered.java
@@ -0,0 +1,13 @@
+package com.example;
+
+public class Covered {
+
+ public static int someCode(int i) {
+ if ( i == 0 ) {
+ return 1;
+ }
+
+ return 1;
+ }
+
+}
diff --git a/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/NotCovered.java b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/NotCovered.java
new file mode 100644
index 000000000..ac93a193e
--- /dev/null
+++ b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/main/java/com/example/NotCovered.java
@@ -0,0 +1,17 @@
+package com.example;
+
+public class NotCovered {
+
+ public static int someCode(int i) {
+ if ( i == 0 ) {
+ return 1;
+ }
+
+ if ( i == 2 ) {
+ return 42;
+ }
+
+ return i;
+ }
+
+}
diff --git a/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/ATest.java b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/ATest.java
new file mode 100644
index 000000000..1c82cccdf
--- /dev/null
+++ b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/ATest.java
@@ -0,0 +1,21 @@
+package com.example;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ATest {
+
+ @Test
+ public void aTest() {
+ assertEquals(1, NotCovered.someCode(0));
+ }
+
+ @Test
+ public void anotherTest() {
+ assertEquals(42, NotCovered.someCode(2));
+ }
+
+}
diff --git a/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/AnotherTest.java b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/AnotherTest.java
new file mode 100644
index 000000000..5fdc972dc
--- /dev/null
+++ b/pitest-maven-verification/src/test/resources/pit-missing-test-plugin/src/test/java/com/example/AnotherTest.java
@@ -0,0 +1,21 @@
+package com.example;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class AnotherTest {
+
+ @Test
+ public void aTest() {
+ assertEquals(1, Covered.someCode(0));
+ }
+
+ @Test
+ public void anotherTest() {
+ assertEquals(1, Covered.someCode(1));
+ }
+
+}
diff --git a/pitest/src/main/java/org/pitest/junit/JUnitTestPlugin.java b/pitest/src/main/java/org/pitest/junit/JUnitTestPlugin.java
index 85cf5f2b4..1d657941a 100644
--- a/pitest/src/main/java/org/pitest/junit/JUnitTestPlugin.java
+++ b/pitest/src/main/java/org/pitest/junit/JUnitTestPlugin.java
@@ -35,7 +35,22 @@ public String description() {
public Configuration createTestFrameworkConfiguration(TestGroupConfig config,
ClassByteArraySource source, Collection excludedRunners, Collection includedTestMethods) {
Objects.requireNonNull(config);
- return new JUnitCompatibleConfiguration(config, excludedRunners, includedTestMethods);
+
+ if (junit4IsPresent()) {
+ return new JUnitCompatibleConfiguration(config, excludedRunners, includedTestMethods);
+ }
+ return new NullConfiguration();
+ }
+
+ // the plugin performs junit version checks later, but these don't get to run
+ // if junit is completely absent and cannot be loaded.
+ private boolean junit4IsPresent() {
+ try {
+ Class.forName("org.junit.runner.manipulation.Filter");
+ return true;
+ } catch (ClassNotFoundException ex) {
+ return false;
+ }
}
@Override
diff --git a/pitest/src/main/java/org/pitest/junit/NullConfiguration.java b/pitest/src/main/java/org/pitest/junit/NullConfiguration.java
new file mode 100644
index 000000000..0f0128b26
--- /dev/null
+++ b/pitest/src/main/java/org/pitest/junit/NullConfiguration.java
@@ -0,0 +1,26 @@
+package org.pitest.junit;
+
+import org.pitest.help.PitHelpError;
+import org.pitest.testapi.Configuration;
+import org.pitest.testapi.TestSuiteFinder;
+import org.pitest.testapi.TestUnitFinder;
+
+import java.util.Collections;
+import java.util.Optional;
+
+public class NullConfiguration implements Configuration {
+ @Override
+ public TestUnitFinder testUnitFinder() {
+ return c -> Collections.emptyList();
+ }
+
+ @Override
+ public TestSuiteFinder testSuiteFinder() {
+ return c -> Collections.emptyList();
+ }
+
+ @Override
+ public Optional verifyEnvironment() {
+ return Optional.empty();
+ }
+}
diff --git a/pitest/src/test/java/org/pitest/junit/NullConfigurationTest.java b/pitest/src/test/java/org/pitest/junit/NullConfigurationTest.java
new file mode 100644
index 000000000..8d2fdc621
--- /dev/null
+++ b/pitest/src/test/java/org/pitest/junit/NullConfigurationTest.java
@@ -0,0 +1,25 @@
+package org.pitest.junit;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NullConfigurationTest {
+
+ NullConfiguration underTest = new NullConfiguration();
+
+ @Test
+ public void findsNoTests() {
+ assertThat(underTest.testUnitFinder().findTestUnits(this.getClass())).isEmpty();
+ }
+
+ @Test
+ public void findsNoSuites() {
+ assertThat(underTest.testSuiteFinder().apply(this.getClass())).isEmpty();
+ }
+
+ @Test
+ public void passesVerification() {
+ assertThat(underTest.verifyEnvironment()).isEmpty();
+ }
+}
\ No newline at end of file