From d7a4a1a2386b6d511adb67b69d0dc66e012af237 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Thu, 31 Dec 2020 12:50:03 +0000 Subject: [PATCH] Failing test for #770 and #746 Failing test to describe general issue behind coverage bugs - child classes are initialized after their parents, so coverage probe is not initialized when parent refers to child in a static initializer block. --- .../simple/ParentChildInitializationTest.java | 22 +++++++ .../execute/CoverageProcessSystemTest.java | 65 ++++++++++--------- 2 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java diff --git a/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java new file mode 100644 index 000000000..7de72f79a --- /dev/null +++ b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java @@ -0,0 +1,22 @@ +package com.example.coverage.execute.samples.simple; + +import org.junit.Test; + +public class ParentChildInitializationTest { + @Test + public void test() { + new TesteeChild(); + } +} + +class TesteeParent { + static TesteeChild child = new TesteeChild(); +} + +class TesteeChild extends TesteeParent { + final static Object f = "hello"; + + TesteeChild() { + System.out.println(f); + } +} diff --git a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java index 1fe5a1729..d86c06204 100644 --- a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java +++ b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java @@ -7,6 +7,7 @@ import com.example.coverage.execute.samples.exceptions.ThrowsExceptionFromLargeMethodTestee; import com.example.coverage.execute.samples.exceptions.ThrowsExceptionInFinallyBlockTestee; import com.example.coverage.execute.samples.exceptions.ThrowsExceptionTestee; +import com.example.coverage.execute.samples.simple.ParentChildInitializationTest; import com.example.coverage.execute.samples.simple.Testee; import com.example.coverage.execute.samples.simple.Testee2; import com.example.coverage.execute.samples.simple.TesteeWithComplexConstructorsTest; @@ -57,8 +58,7 @@ public class CoverageProcessSystemTest { private final MethodName foo = MethodName.fromString("foo"); @Test - public void shouldRecordSomeCoverage() throws IOException, - InterruptedException, ExecutionException { + public void shouldRecordSomeCoverage() throws Exception { final List coverage = runCoverageForTest(TestsForMultiBlockCoverage.class); assertFalse(coverage.iterator().next().getCoverage().isEmpty()); } @@ -80,8 +80,7 @@ public void shouldCalculateCoverageForSingleBlockMethods() // } @Test - public void shouldCalculateCoverageFor3BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor3BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test3", 2); } @@ -122,22 +121,19 @@ public void shouldCalculateCoverageForBlockMethods() throws IOException, } @Test - public void shouldCalculateCoverageFor7BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor7BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test7", 2); } @Test - public void shouldCalculateCoverageFor8BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor8BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test8", 2); } @Test - public void shouldCalculateCoverageFor9BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor9BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test9", 2); } @@ -150,50 +146,44 @@ public void shouldCalculateCoverageFor10BlockMethods() throws IOException, } @Test - public void shouldCalculateCoverageFor11BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor11BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test11", 2); } @Test - public void shouldCalculateCoverageFor12BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor12BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test12", 2); } @Test - public void shouldCalculateCoverageFor13BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor13BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test13", 2); } @Test - public void shouldCalculateCoverageFor14BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor14BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test14", 2); } @Test - public void shouldCalculateCoverageFor15BlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageFor15BlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "test15", 2); } @Test - public void shouldCalculateCoverageForLargeBlockMethods() throws IOException, - InterruptedException, ExecutionException { + public void shouldCalculateCoverageForLargeBlockMethods() throws Exception { final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class); assertCoverage(coveredClasses, "testMany", 2); } @Test public void shouldCalculateCoverageForAllRelevantClasses() - throws IOException, InterruptedException, ExecutionException { + throws Exception{ final List coveredClasses = runCoverageForTest(Tests.class); @@ -204,7 +194,7 @@ public void shouldCalculateCoverageForAllRelevantClasses() @Test public void shouldCalculateCoverageForSmallMethodThatThrowsException() - throws IOException, InterruptedException, ExecutionException { + throws Exception { final List coveredClasses = runCoverageForTest(TestsClassWithException.class); assertThat(coveredClasses).anyMatch(coverageFor(CoveredBeforeExceptionTestee.class)); @@ -222,7 +212,7 @@ public void shouldCalculateCoverageForSmallMethodThatThrowsException() @Test public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock() - throws IOException, InterruptedException, ExecutionException { + throws Exception { final List coveredClasses = runCoverageForTest(TestThrowsExceptionInFinallyBlock.class); final ClassName clazz = ClassName @@ -237,7 +227,7 @@ public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock( @Test public void shouldCalculateCoverageForLargeMethodThatThrowsException() - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = runCoverageForTest(TestThrowsExceptionFromLargeMethodTestee.class); final ClassName clazz = ClassName @@ -262,7 +252,7 @@ public void testFoo() { @Test public void shouldCalculateCoverageOfClassesRunInDifferentClassLoader() - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = runCoverageForTest(TestInDifferentClassLoader.class); assertThat(coveredClasses).anyMatch(coverageFor(Testee2.class)); assertThat(coveredClasses).anyMatch(coverageFor(Testee.class)); @@ -314,6 +304,13 @@ public void shouldFailWithExitCode() throws Exception { assertEquals(ExitCode.JUNIT_ISSUE, exitCode); } + @Test + public void handlesParentChildInitializationOrderIssues() throws Exception { + final List coveredClasses = runCoverageForTest(ParentChildInitializationTest.class); + assertThat(coveredClasses) + .anyMatch(coverageFor(ClassName.fromString("com.example.coverage.execute.samples.simple.TesteeChild"))); + } + private ClassPath classPathWithoutJUnit() { final List cpWithoutJUnit = ClassPath.getClassPathElementsAsFiles().stream() @@ -328,7 +325,7 @@ private Predicate failingTest() { } private List runCoverageForTest(final Class test) - throws IOException, InterruptedException, ExecutionException { + throws IOException, InterruptedException { final List coveredClasses = new ArrayList<>(); @@ -360,16 +357,20 @@ private void runCoverageProcess(final Class test, } } - private Predicate coverageFor(final Class class1) { + private Predicate coverageFor(final Class clazz) { + return coverageFor(ClassName.fromClass(clazz)); + } + + private Predicate coverageFor(ClassName clazz) { return new Predicate() { @Override public boolean test(final CoverageResult a) { - return FCollection.contains(a.getCoverage(), resultFor(class1)); + return FCollection.contains(a.getCoverage(), resultFor(clazz)); } - private Predicate resultFor(final Class class1) { - return a -> a.isFor(ClassName.fromClass(class1)); + private Predicate resultFor(ClassName clazz) { + return a -> a.isFor(clazz); } }; }