diff --git a/src/main/java/org/junit/runner/Result.java b/src/main/java/org/junit/runner/Result.java index 73ad059caefb..4b5f4a406238 100644 --- a/src/main/java/org/junit/runner/Result.java +++ b/src/main/java/org/junit/runner/Result.java @@ -28,6 +28,7 @@ public class Result implements Serializable { ObjectStreamClass.lookup(SerializedForm.class).getFields(); private final AtomicInteger count; private final AtomicInteger ignoreCount; + private final AtomicInteger assumptionFailureCount; private final CopyOnWriteArrayList failures; private final AtomicLong runTime; private final AtomicLong startTime; @@ -38,6 +39,7 @@ public class Result implements Serializable { public Result() { count = new AtomicInteger(); ignoreCount = new AtomicInteger(); + assumptionFailureCount = new AtomicInteger(); failures = new CopyOnWriteArrayList(); runTime = new AtomicLong(); startTime = new AtomicLong(); @@ -46,34 +48,35 @@ public Result() { private Result(SerializedForm serializedForm) { count = serializedForm.fCount; ignoreCount = serializedForm.fIgnoreCount; + assumptionFailureCount = serializedForm.assumptionFailureCount; failures = new CopyOnWriteArrayList(serializedForm.fFailures); runTime = new AtomicLong(serializedForm.fRunTime); startTime = new AtomicLong(serializedForm.fStartTime); } /** - * @return the number of tests run + * Returns the number of tests run */ public int getRunCount() { return count.get(); } /** - * @return the number of tests that failed during the run + * Returns the number of tests that failed during the run */ public int getFailureCount() { return failures.size(); } /** - * @return the number of milliseconds it took to run the entire suite to run + * Returns the number of milliseconds it took to run the entire suite to run */ public long getRunTime() { return runTime.get(); } /** - * @return the {@link Failure}s describing tests that failed and the problems they encountered + * Returns the {@link Failure}s describing tests that failed and the problems they encountered */ public List getFailures() { return failures; @@ -86,6 +89,20 @@ public int getIgnoreCount() { return ignoreCount.get(); } + /** + * Returns the number of tests skipped because of an assumption failure + * + * @throws UnsupportedOperationException if the result was serialized in a version before JUnit 4.13 + * @since 4.13 + */ + public int getAssumptionFailureCount() { + if (assumptionFailureCount == null) { + throw new UnsupportedOperationException( + "Result was serialized from a version of JUnit that doesn't support this method"); + } + return assumptionFailureCount.get(); + } + /** * @return true if all tests succeeded */ @@ -137,7 +154,7 @@ public void testIgnored(Description description) throws Exception { @Override public void testAssumptionFailure(Failure failure) { - // do nothing: same as passing (for 4.5; may change in 4.6) + assumptionFailureCount.getAndIncrement(); } } @@ -156,6 +173,7 @@ private static class SerializedForm implements Serializable { private static final long serialVersionUID = 1L; private final AtomicInteger fCount; private final AtomicInteger fIgnoreCount; + private final AtomicInteger assumptionFailureCount; private final List fFailures; private final long fRunTime; private final long fStartTime; @@ -163,6 +181,7 @@ private static class SerializedForm implements Serializable { public SerializedForm(Result result) { fCount = result.count; fIgnoreCount = result.ignoreCount; + assumptionFailureCount = result.assumptionFailureCount; fFailures = Collections.synchronizedList(new ArrayList(result.failures)); fRunTime = result.runTime.longValue(); fStartTime = result.startTime.longValue(); @@ -172,6 +191,7 @@ public SerializedForm(Result result) { private SerializedForm(ObjectInputStream.GetField fields) throws IOException { fCount = (AtomicInteger) fields.get("fCount", null); fIgnoreCount = (AtomicInteger) fields.get("fIgnoreCount", null); + assumptionFailureCount = (AtomicInteger) fields.get("assumptionFailureCount", null); fFailures = (List) fields.get("fFailures", null); fRunTime = fields.get("fRunTime", 0L); fStartTime = fields.get("fStartTime", 0L); @@ -184,6 +204,7 @@ public void serialize(ObjectOutputStream s) throws IOException { fields.put("fFailures", fFailures); fields.put("fRunTime", fRunTime); fields.put("fStartTime", fStartTime); + fields.put("assumptionFailureCount", assumptionFailureCount); s.writeFields(); } diff --git a/src/test/java/junit/tests/runner/ResultTest.java b/src/test/java/junit/tests/runner/ResultTest.java index 9f09fafcb216..7a6042996268 100644 --- a/src/test/java/junit/tests/runner/ResultTest.java +++ b/src/test/java/junit/tests/runner/ResultTest.java @@ -2,6 +2,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -10,6 +12,7 @@ import junit.framework.TestCase; import junit.tests.framework.Success; +import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; @@ -17,18 +20,61 @@ public class ResultTest extends TestCase { + private Result fromStream; + public void testRunFailureResultCanBeSerialised() throws Exception { JUnitCore runner = new JUnitCore(); Result result = runner.run(AnnotationTest.FailureTest.class); assertResultSerializable(result); } + public void testRunFailureResultCanBeReserialised_v4_12() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(AnnotationTest.FailureTest.class); + assertResultReserializable(result, SerializationFormat.V4_12); + } + + public void testRunAssumptionFailedResultCanBeSerialised() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(AssumptionFailedTest.class); + assertResultSerializable(result); + } + + public void testRunAssumptionFailedResultCanBeReserialised_v4_12() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(AssumptionFailedTest.class); + assertResultReserializable(result, SerializationFormat.V4_12); + } + + public void testRunAssumptionFailedResultCanBeReserialised_v4_13() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(AssumptionFailedTest.class); + assertResultReserializable(result, SerializationFormat.V4_13); + } + public void testRunSuccessResultCanBeSerialised() throws Exception { JUnitCore runner = new JUnitCore(); Result result = runner.run(Success.class); assertResultSerializable(result); } + public void testRunSuccessResultCanBeReserialised_v4_12() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(Success.class); + assertResultReserializable(result, SerializationFormat.V4_12); + } + + public void testRunSuccessResultCanBeReserialised_v4_13() throws Exception { + JUnitCore runner = new JUnitCore(); + Result result = runner.run(Success.class); + assertResultReserializable(result, SerializationFormat.V4_13); + } + + private enum SerializationFormat { + V4_12, + V4_13 + } + private void assertResultSerializable(Result result) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); @@ -37,14 +83,26 @@ private void assertResultSerializable(Result result) throws IOException, ClassNo byte[] bytes = byteArrayOutputStream.toByteArray(); ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); Result fromStream = (Result) objectInputStream.readObject(); - assertSerializedCorrectly(result, fromStream); - - InputStream resource = getClass().getResourceAsStream(getName()); - assertNotNull("Could not read resource " + getName(), resource); - objectInputStream = new ObjectInputStream(resource); + assertSerializedCorrectly(result, fromStream, SerializationFormat.V4_13); + } + + private void assertResultReserializable(Result result, SerializationFormat resourceSerializationFormat) + throws IOException, ClassNotFoundException { + String resourceName = getName(); + InputStream resource = getClass().getResourceAsStream(resourceName); + assertNotNull("Could not read resource " + resourceName, resource); + ObjectInputStream objectInputStream = new ObjectInputStream(resource); fromStream = (Result) objectInputStream.readObject(); - - assertSerializedCorrectly(new ResultWithFixedRunTime(result), fromStream); + + assertSerializedCorrectly(new ResultWithFixedRunTime(result), + fromStream, resourceSerializationFormat); + } + + static public class AssumptionFailedTest { + @Test + public void assumptionFailed() throws Exception { + org.junit.Assume.assumeTrue(false); + } } /** @@ -85,14 +143,35 @@ public List getFailures() { public int getIgnoreCount() { return delegate.getIgnoreCount(); } + + @Override + public int getAssumptionFailureCount() { + return delegate.getAssumptionFailureCount(); + } } - private void assertSerializedCorrectly(Result result, Result fromStream) { + private void assertSerializedCorrectly( + Result result, Result fromStream, SerializationFormat serializationFormat) { assertNotNull(fromStream); // Exceptions don't implement equals() so we need to compare field by field assertEquals("failureCount", result.getFailureCount(), fromStream.getFailureCount()); assertEquals("ignoreCount", result.getIgnoreCount(), fromStream.getIgnoreCount()); + + if (serializationFormat == SerializationFormat.V4_13) { + // assumption failures are serialized + assertEquals("assumptionFailureCount", + result.getAssumptionFailureCount(), + fromStream.getAssumptionFailureCount()); + } else { + // assumption failures were not serialized + try { + fromStream.getAssumptionFailureCount(); + fail("UnsupportedOperationException expected"); + } catch (UnsupportedOperationException expected) { + } + } + assertEquals("runTime", result.getRunTime(), fromStream.getRunTime()); assertEquals("failures", result.getFailures().size(), fromStream.getFailures().size()); int index = 0; diff --git a/src/test/java/org/junit/tests/experimental/AssumptionTest.java b/src/test/java/org/junit/tests/experimental/AssumptionTest.java index 4b9f69a545a0..52cd2d844cdc 100644 --- a/src/test/java/org/junit/tests/experimental/AssumptionTest.java +++ b/src/test/java/org/junit/tests/experimental/AssumptionTest.java @@ -213,9 +213,18 @@ public void failingAssumptionInConstructorIgnoresClass() { assertThat(testResult(AssumptionFailureInConstructor.class), isSuccessful()); } - @Test(expected = IllegalArgumentException.class) - public void assumeWithExpectedException() { - assumeTrue(false); + public static class TestClassWithAssumptionFailure { + + @Test(expected = IllegalArgumentException.class) + public void assumeWithExpectedException() { + assumeTrue(false); + } + } + + @Test + public void assumeWithExpectedExceptionShouldThrowAssumptionViolatedException() { + Result result = JUnitCore.runClasses(TestClassWithAssumptionFailure.class); + assertThat(result.getAssumptionFailureCount(), is(1)); } final static String message = "Some random message string."; diff --git a/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12 b/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12 new file mode 100644 index 000000000000..5eb4ef97839d Binary files /dev/null and b/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_12 differ diff --git a/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13 b/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13 new file mode 100644 index 000000000000..6fa2a060b86b Binary files /dev/null and b/src/test/resources/junit/tests/runner/testRunAssumptionFailedResultCanBeReserialised_v4_13 differ diff --git a/src/test/resources/junit/tests/runner/testRunFailureResultCanBeSerialised b/src/test/resources/junit/tests/runner/testRunFailureResultCanBeReserialised_v4_12 similarity index 100% rename from src/test/resources/junit/tests/runner/testRunFailureResultCanBeSerialised rename to src/test/resources/junit/tests/runner/testRunFailureResultCanBeReserialised_v4_12 diff --git a/src/test/resources/junit/tests/runner/testRunSuccessResultCanBeSerialised b/src/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_12 similarity index 100% rename from src/test/resources/junit/tests/runner/testRunSuccessResultCanBeSerialised rename to src/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_12 diff --git a/src/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13 b/src/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13 new file mode 100644 index 000000000000..6c3e1b378ff3 Binary files /dev/null and b/src/test/resources/junit/tests/runner/testRunSuccessResultCanBeReserialised_v4_13 differ