-->

Running instrumentation tests from specific packag

2019-05-09 06:51发布

问题:

I am using spoon-gradle-plugin from Roman Mazur. I am capable of running all tests at once but I am having trouble to specify "group" of tests that I would like to launch. Currently my spoon setup looks like that:

spoon {
    debug = true

    baseOutputDir = file("$buildDir/spoon-log")
    if (project.hasProperty('spoonClassName')) {
        className = project.spoonClassName

        if (project.hasProperty('spoonMethodName')) {
            methodName = project.spoonMethodName
        }
    }

    adbTimeout = 60 * 60;
}

My tests are located in packages:

And my goal is to create separate gradle tasks that are depending on spoon to launch tests from each package separately. Roman gave us parameter instrumentationArgs which should be capable of editing some properties within the spoon.

As I can see on main git of spoon there is written that you can specify package, where spoon-runner should look for your tests and example goes like that:

--e package=com.mypackage.unit_tests

So my idea was to put this property into instrumentationArgs. Consequently I created my spoon tasks like that:

task spoonAuthFlowTests(type: GradleBuild, dependsOn: ['spoon']) {
    spoon {
        instrumentationArgs = ["package=com.myapp.instrumentation.flowtests.AuthFlowTests"]
        noAnimations = true;
    }
}

task spoonFlowTests(type: GradleBuild, dependsOn: ['spoon']) {
    spoon {
        instrumentationArgs = ["package=com.myapp.instrumentation.flowtests"]
        noAnimations = true;
    }
}

What can I say is that noAnimations parameter is nicely extending default spoon config, preventing gifs from being created. So instrumentationArgs is for sure taking my string array, but doesn't apply the change because in my terminal:

2016-01-08 15:13:10 [SDR.run] About to actually run tests for [04ffe19ad317d2e7]
03:13:10 I/RemoteAndroidTest: Running am instrument -w -r   -e package com.myapp.instrumentation.flowtests -e class com.myapp.instrumentation.flowtests.AuthFlowTests.LoginUserFlowTests com.myapp.debug1.test/com.myapp.instrumentation.helper.runner.MyAppTestRunner on lge-nexus_4-04ffe19ad317d2e7

No mather what I do with "package" property, I always receive result:

-e package com.myapp.instrumentation.flowtests

And I want to change it, but don't know how. Furthermore I can say that I tried to look up in my project "com.myapp.instrumentation.flowtests" string and the only locations where it is used are: tests in package + gradle tasks presented above. So it isn't hardcoded anywhere. Same location is picked if I start tests by:

./gradlew spoon

And after I use:

./gradlew spoonAuthFlowTests

It also runs whole test set.

回答1:

Your problem is that you incorrectly interpret how spoon block works in your Gradle config. When you write something like

spoon {
  debug = true
}

You basically modify a singleton object associated with your Gradle project. This project contains a configuration shared between all the tasks created by the spoon plugin. Spoon plugin creates separate tasks for different flavors defined in your project (so that you can run tests for each flavour separately). Also there are tasks like spoonSmall, spoonMedium to run tests annotated with @Small or @Medium only. All these tasks use the same configuration object you alter with spoon {}.

Hence, when you call spoon {} inside of your tasks definitions you simply override existing values. And the last values are applied.

If you want to create a custom spoon runner task, you should write something like

import com.stanfy.spoon.gradle.SpoonRunTask
task spoonAuthFlowTests(type: SpoonRunTask) {
  instrumentationArgs = ['package=com.myapp.instrumentation.flowtests.AuthFlowTests']
  // But you will have to set many other options on the tasks,
  // like instrumentationApk and applicationApk files.
}

You can see all the tasks properties in SpoonRunTask sources. Majority of them are set from that single configuration object by the plugin when it creates its tasks.

If this sounds too complicated, you can choose a different way. Configure your arguments using project properties that can be defined in command line.

spoon {
  instrumentationArgs = ["package=${project.getProperty('spoonPackage')}"]
  noAnimations = true;
}

Now you can run

./gradlew spoon -PspoonPackage=com.myapp.instrumentation.flowtests

So instead of specifying different tasks in the command line you will be specifying different project properties.

The downside is that you will not be able to run tests for 2 packages with one gradle invocation. You will have to call it twice with different values.