Skip to content

Cannot filter transpiled Junit tests on Robolectric/Android #1

@marcprux

Description

@marcprux

When writing Swift unit tests, it is often useful to run just a subset of all the tests in a module. Xcode offers good support for this by letting you pick individual tests to run from the Test navigator, and execute it by clicking the green "run" arrow. The "Test Again" menu item can then be used to re-execute the filtered test, enabling a fast test-driven development (TDD) cycle.

However, this test filtering does not apply to the transpiled Skip JUnit tests. Those are all run from a test package's single XCSkipTests test, which implements XCGradleHarness to invoke the gradle process to compile and run the test cases (either locally with Robolectric, or, when the ANDROID_SERIAL environment is present, against the named Android emulator or device). This always executes all the transpiled JUnit test cases, which, for a large package (like SkipFoundation or SkipUI), can take a very long time.

We should provide the ability to filter down the test cases so the test-driven developer can quickly iterate on a single test case. Ideally, we would be able to just click the green arrow next to a test case and have it execute not just the Swift XCUnit test, but also execute the single transpiled JUnit test. However, given that we don't require the Swift test cases to implement any Skip-specific protocol, we don't have any way to intercept the execution of that one test case.

Should we want to enable this ability (at the loss of SkipZero support for that test module) by, say, having the test case extend SkipFilterableTestCase, we could intercept the execution of the test case to run both the Swift XCTest case, as well as invoke gradle testDebug (Robolectric) or gradle connectedDebugAndroidTest (Android) with the correct flags to run only a subset of the test cases. These two test environments are very different: Robolectric uses the local JVM to just run the tests on the local file system, whereas Android packages up the tests into a test harness .apk file and transmits it to the emulator/device for execution. The test filter flags for these two targets are different, and I'm not even sure it is possible to do in the Android test environment (attempts to pass -P android.testInstrumentationRunnerArguments.package=skip.ui.SkipUITests through to gradle do not seem to successfully filter down the tests).

Another approach might be to have the transpiler's KotlinUnitTestTransformer add in support for this by, say, injecting a check into each transpiled test method for a SKIP_TEST_FILTER environment variable, and if it doesn't match the current test, just skip over it using the standard XCTSkip method. The JUnit test would still be run, but it would be quickly skipped. This approach has the benefit of working the same regardless of whether the test environment is Robolectric or Android, but assumes that we'd be able to pass the environment variable through to the emulator's test environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions