Skip to content

Commit

Permalink
Fix exceptions during @afterclass not being reported via Instrumentat…
Browse files Browse the repository at this point in the history
…ionResultPrinter

PiperOrigin-RevId: 637095159
  • Loading branch information
agrieve authored and copybara-androidxtest committed Jun 6, 2024
1 parent 9375894 commit 1a073a9
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 35 deletions.
2 changes: 2 additions & 0 deletions runner/android_junit_runner/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

**Bug Fixes**

* Exceptions during `@AfterClass` were not being reported via `InstrumentationResultPrinter`.

**New Features**

**Breaking Changes**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<String> 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);
}
}

0 comments on commit 1a073a9

Please sign in to comment.