Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

numShards, shardIndex support #270

Open
jerry-jeon opened this issue May 9, 2022 · 3 comments
Open

numShards, shardIndex support #270

jerry-jeon opened this issue May 9, 2022 · 3 comments
Assignees

Comments

@jerry-jeon
Copy link

The sharding feature that's available in AndroidJunitRunner is not working in AndroidJunit5Runner.
Is there any way to achieve it? I tried to do it through the ExecutionCondition extension, but it makes the test "ignored". I want to make the runner doesn't recognize tests that aren't included in the specific sharding.

I briefly changed the code by refering the AndroidJunitRunner code and it's working well. But I am not sure it's the right way to do it.

internal fun createRunnerParams(testClass: Class<*>): AndroidJUnit5RunnerParams {
    val instrumentation = InstrumentationRegistry.getInstrumentation()
    val arguments = InstrumentationRegistry.getArguments()

    // Parse environment variables & pass them to the JVM
    val environmentVariables = arguments.getString(ARG_ENVIRONMENT_VARIABLES)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse system properties & pass them to the JVM
    val systemProperties = arguments.getString(ARG_SYSTEM_PROPERTIES)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse configuration parameters
    val configurationParameters = arguments.getString(ARG_CONFIGURATION_PARAMETERS)
        ?.run { PropertiesParser.fromString(this) }
        ?: emptyMap()

    // Parse the selectors to use from what's handed to the runner.
    val selectors = ParsedSelectors.fromBundle(testClass, arguments)

    // The user may apply test filters to their instrumentation tests through the Gradle plugin's DSL,
    // which aren't subject to the filtering imposed through adb.
    // A special resource file may be looked up at runtime, containing
    // the filters to apply by the AndroidJUnit5 runner.
    val filters = mutableListOf<Filter<*>>()
    val contextFilters = GeneratedFilters.fromContext(instrumentation.context)
    filters.addAll(contextFilters)

    class ShardingFilter(val numShards: Int, val shardIndex: Int) : PostDiscoveryFilter {
        override fun apply(descriptor: TestDescriptor): FilterResult {
            if (descriptor.isTest) {
                val remainder = abs(descriptor.hashCode()) % numShards
                val runningShard = remainder == shardIndex
                return if (runningShard) {
                    FilterResult.included(null)
                } else {
                    FilterResult.excluded("excluded")
                }
            }

            for (each in descriptor.children) {
                return if (apply(each).included()) {
                    FilterResult.included(null)
                } else {
                    FilterResult.excluded("excluded")
                }
            }

            return FilterResult.excluded("excluded")
        }
    }

    val numShards = arguments.getString("numShards")?.toInt() ?: -1
    val shardIndex = arguments.getString("shardIndex")?.toInt() ?: -1
    if (numShards > 0 && shardIndex >= 0 && shardIndex < numShards) {
        filters.add(ShardingFilter(numShards, shardIndex))
    }

    return AndroidJUnit5RunnerParams(
        selectors,
        filters,
        environmentVariables,
        systemProperties,
        configurationParameters
    )
}
@mannodermaus
Copy link
Owner

I deployed a new 1.3.1-SNAPSHOT version of the instrumentation libraries where support for numShards and shardIndex are added. Would you try it out and let me know if this works for you?

dependencies {
  androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.3.1-SNAPSHOT")
  androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.3.1-SNAPSHOT")
}

@mannodermaus mannodermaus added this to the instrumentation-1.3.1 milestone Jun 23, 2022
@jerry-jeon
Copy link
Author

Hello @mannodermaus . Thanks for working on it.
It’s working well, but there’s a problem related to the test result.

I have tests both of junit4 and junit5. For the shard that only contains junit4 tests, the test result considered as failed even if all tests are passed. (As you can see the screen shot) Screen Shot 2022-07-08 at 4 07 01 PM
When it happens the suspicious log appears - I/TestRunner: finished: JUnit Jupiter If the shard contains at least one junit5 test, it doesn’t appear.
Screen Shot 2022-07-08 at 4 10 06 PM

Here's the part of XML file that exported from the result. Each tests are passed but in the testSuite tag, the result is failed. I guess it’s why the result shown as failed in the android studio.
Screen Shot 2022-07-08 at 4 54 36 PM

I created the sample project that can reproduce the issue. In the project problematic numShards and shardIndex value is assigned already, so if you run the whole tests then you will see the issue.

Because of it, my project always fails on the Firebase Testlab. I would really appreciate it if you could help me.
If you need more information, please let me know.
Thank you.

@mannodermaus mannodermaus removed this from the instrumentation-1.3.1 milestone Sep 17, 2023
@mannodermaus
Copy link
Owner

Hey, apologies for only coming back to this now. Thank you for the sample project! I executed the instrumentation tests in it and it ran the same tests I can see in your screenshots, but my XML file has a different format with less information. I wonder if there have been changes to AS itself that resolved an internal issue here? (For context, I'm running from AS Iguana Canary 3)

Screenshot 2023-09-18 at 10 45 44

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants