diff --git a/runner/android_junit_runner/CHANGELOG.md b/runner/android_junit_runner/CHANGELOG.md index 0e374a29f..cc5a575a0 100644 --- a/runner/android_junit_runner/CHANGELOG.md +++ b/runner/android_junit_runner/CHANGELOG.md @@ -6,6 +6,8 @@ **Bug Fixes** +* Exceptions during `@AfterClass` were not being reported via `InstrumentationResultPrinter`. + **New Features** **Breaking Changes** diff --git a/runner/android_junit_runner/java/androidx/test/internal/runner/listener/InstrumentationResultPrinter.java b/runner/android_junit_runner/java/androidx/test/internal/runner/listener/InstrumentationResultPrinter.java index 7cb820220..5e230c8e7 100644 --- a/runner/android_junit_runner/java/androidx/test/internal/runner/listener/InstrumentationResultPrinter.java +++ b/runner/android_junit_runner/java/androidx/test/internal/runner/listener/InstrumentationResultPrinter.java @@ -44,7 +44,7 @@ */ public class InstrumentationResultPrinter extends InstrumentationRunListener { - private static final String TAG = "InstrumentationResultPrinter"; + private static final String TAG = "InstrResultPrinter"; /** * This value, if stored with key {@link android.app.Instrumentation#REPORT_KEY_IDENTIFIER}, @@ -152,14 +152,12 @@ public void testFinished(Description description) throws Exception { @Override public void testFailure(Failure failure) throws Exception { - boolean shouldCallFinish = false; - if (!isAnyTestStarted()) { - // Junit failed during initialization and testStarted was never called. For example, an - // exception was thrown in @BeforeClass method. We must artificially call testStarted and - // testFinished in order to print a descriptive result that external tools (like Studio) can - // understand. + // getMethodName() == null when an exception is thrown during @BeforeClass or @AfterClass. + // No matching testStart() / testFinish() is emitted, so simulate them here for the sake of + // instrumentation consumers. + boolean shouldCallFinish = failure.getDescription().getMethodName() == null; + if (shouldCallFinish) { testStarted(failure.getDescription()); - shouldCallFinish = true; } testResultCode = REPORT_VALUE_RESULT_FAILURE; reportFailure(failure); diff --git a/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/BUILD b/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/BUILD index 95c3103b2..7728121fe 100644 --- a/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/BUILD +++ b/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/BUILD @@ -44,15 +44,8 @@ axt_android_library_test( "//ext/junit", "//runner/android_junit_runner", "//runner/android_junit_runner/javatests/androidx/test/testing/fixtures", - "//runner/rules", - "//services/events/java/androidx/test/services/events", - "//services/storage", "@androidsdk//:legacy_test-34", - "@maven//:com_google_guava_guava", - "@maven//:com_google_truth_truth", "@maven//:junit_junit", - "@maven//:org_hamcrest_hamcrest_core", - "@maven//:org_mockito_mockito_core", ], ) diff --git a/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/InstrumentationResultPrinterTest.java b/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/InstrumentationResultPrinterTest.java index 037a8cad8..caa6e6371 100644 --- a/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/InstrumentationResultPrinterTest.java +++ b/runner/android_junit_runner/javatests/androidx/test/internal/runner/listener/InstrumentationResultPrinterTest.java @@ -23,11 +23,17 @@ import android.os.Bundle; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import java.util.ArrayList; +import java.util.List; import junit.framework.Assert; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.Computer; import org.junit.runner.Description; +import org.junit.runner.JUnitCore; +import org.junit.runner.Request; import org.junit.runner.RunWith; -import org.junit.runner.notification.Failure; @RunWith(AndroidJUnit4.class) @SmallTest @@ -62,27 +68,50 @@ public void sendStatus(int code, Bundle bundle) { assertTrue(resultBundle[0].containsKey(REPORT_KEY_STACK)); } - @Test - public void verifyFailureDescriptionPropagatedToStartAndFinishMethods() throws Exception { - Description[] descriptions = new Description[2]; - InstrumentationResultPrinter intrResultPrinter = - new InstrumentationResultPrinter() { - @Override - public void testStarted(Description description) throws Exception { - descriptions[0] = description; - } + private static class TestInstrumentationResultPrinter extends InstrumentationResultPrinter { + final List resultsLog = new ArrayList<>(); - @Override - public void testFinished(Description description) throws Exception { - descriptions[1] = description; - } - }; + @Override + public void sendStatus(int code, Bundle bundle) { + resultsLog.add( + String.format( + "code=%s, name=%s#%s", + code, + bundle.getString(REPORT_KEY_NAME_CLASS), + bundle.getString(REPORT_KEY_NAME_TEST))); + } + } + + public static class ThrowingTest { + @BeforeClass + public static void setUpClass() { + throw new RuntimeException(); + } + + @AfterClass + public static void tearDownClass() { + throw new RuntimeException(); + } - Description d = Description.createTestDescription(this.getClass(), "Failure Description"); - Failure testFailure = new Failure(d, new Exception()); - intrResultPrinter.testFailure(testFailure); + @Test + public void emptyTest() {} + } + + @Test + public void verifyBeforeClassExceptionsReported() throws Exception { + JUnitCore core = new JUnitCore(); + var intrResultPrinter = new TestInstrumentationResultPrinter(); + core.addListener(intrResultPrinter); + Request testRequest = Request.classes(new Computer(), new Class[] {ThrowingTest.class}); + core.run(testRequest); - assertEquals(d, descriptions[0]); - assertEquals(d, descriptions[1]); + String className = ThrowingTest.class.getName(); + assertEquals( + List.of( + "code=1, name=" + className + "#null", + "code=-2, name=" + className + "#null", + "code=1, name=" + className + "#null", + "code=-2, name=" + className + "#null"), + intrResultPrinter.resultsLog); } }