the studio script plug make for first configurar available added actualizar android gradle android-gradle android-testing

android - studio - Cómo cambiar/cambiar testInstrumentationRunner dinámicamente con gradle



settings gradle android studio (4)

Mi proyecto tiene 2 grupos diferentes de pruebas. Un grupo solo se ejecuta con AndroidJUnitRunner predeterminado, el otro tiene que ejecutarse con una implementación personalizada. TestRunner extends MonitoringInstrumentation .

Actualmente cambio el testInstrumentationRunner editando build.gradle cada vez que necesito ejecutar el otro grupo de pruebas:

android{ defaultConfig { //testInstrumentationRunner "my.custom.TestRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }

Sé que los sabores pueden tener su propio testInstrumentationRunner pero mi aplicación actual ya tiene 2 flavourDimensions . Usar sabores en realidad tiene la intención de tener diferentes versiones de una aplicación. Necesito 2 versiones de la aplicación de prueba, ambas probando la misma aplicación con diferentes testInstrumentationRunner s.

Traté de cambiar el testInstrumentationRunner iterando sobre todas las variantes de prueba. En realidad, hay múltiples propiedades testInstrumentationRunner :

android.testVariants.all { TestVariant variant -> //readonly variant.variantData.variantConfiguration.instrumentationRunner variant.variantData.variantConfiguration.defaultConfig.testInstrumentationRunner }

Pero tan pronto como se llama a android.testVariants la compilación se configura y todos los cambios no se reflejan en la compilación.

¿Cómo puedo cambiar el testInstrumentationRunner (desde un plugin de Gradle) dinámicamente?

Preferiría tener 2 tareas diferentes de gradle, cada una usando un testInstrumentationRunner diferente pero probando la misma variante. Como intento crear un plugin de gradle, la solución también debería funcionar como plugin.


Tuve un problema similar, utilicé el gramaje de tarea de Gradle. Según su declaración "Mi proyecto tiene 2 grupos diferentes de pruebas". Asumiré que tiene definidas diferentes tareas, las llamaré testGroupOne y testGroupTwo:

task testGroupOne{ } task testGroupTwo{ } gradle.taskGraph.whenReady {taskGraph -> if(taskGraph.hasTask(testGroupOne)){ testInstrumentationRunner "my.custom.TestRunner" } else if (taskGraph.hasTask(testGroupTwo)){ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }

Esto le permite establecer el valor de testInstrumentationRunner después de la configuración, pero antes de la ejecución.


Esta es una solución parcial, pero tal vez esto hará que las cosas sean menos engorrosas para usted: no le permite ejecutar las pruebas con ambos corredores de prueba en la misma versión. Si lo desea, debe clonar todas las instancias de tarea de DeviceProviderInstrumentTestTask , que, en mi opinión, es demasiado compleja y frágil.

Esto funciona para mí (Gradle 2.4 y Android build tools 1.2.3). Utiliza API internas, por lo que es posible que esto ya no funcione con la próxima versión de las herramientas de compilación de Android.

Debe modificar las tareas generadas por el complemento de Android una vez que se haya evaluado el proyecto. Los cambios serán luego utilizados por las tareas de prueba. La propiedad que realmente cambia el corredor de prueba utilizado es task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner . En lugar de realizar estos cambios durante la fase de configuración (es decir, fuera de una tarea), los cambios se aplican con una tarea, por lo que el corredor de prueba solo se utiliza cuando se solicita. Al forzar que las tareas de prueba se ejecuten después de useMyTestRunner (si este último es parte de la compilación), el nombre de la clase del useMyTestRunner de prueba se habrá cambiado cuando se inicie una tarea de prueba:

project.afterEvaluate { task useMyTestRunner << { tasks.withType(com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask.class) { task -> task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner = ''com.mycompany.MyTestRunner'' } } tasks.withType(com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask.class) { task -> task.mustRunAfter useMyTestRunner } }

Ahora puede ejecutar las pruebas utilizando el corredor de prueba predeterminado configurado para el sabor (es) con:

gradle :myApp:connectedAndroidTest

Cuando desee ejecutar las pruebas con su corredor de prueba, use:

gradle :myApp:connectedAndroidTest :myApp:useMyTestRunner

No task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner cheques para null para ninguna de las propiedades recuperadas usando task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner . Debe agregarlos para mayor robustez. Creo que al menos testedConfig necesita atención. Consulte getInstrumentationRunner() en https://android.googlesource.com/platform/tools/build/+/master/builder/src/main/java/com/android/builder/VariantConfiguration.java

Puede usar una importación para com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask en la parte superior de su archivo de compilación, por lo que solo debe usar el nombre simple de la clase.


¿Ha considerado usar el parámetro de la consola como un interruptor entre dos configuraciones? Tan sencillo como eso:

android { defaultConfig { if (project.ext.has("customRunner")) { testInstrumentationRunner "my.custom.TestRunner" } else { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } } }

Y luego, por ejemplo, ejecute gradlew aDeb -PcustomRunner si desea probar utilizando un corredor personalizado o gradlew aDeb para usar el valor predeterminado.

Sé que no es ciencia espacial, pero lo más simple es mejor, ¿no? También puedes usarlo en tu complemento, solo obtén el objeto Project y haz algo similar.


Desde el complemento android gradle 1.3 es posible crear módulos de prueba separados. Cada uno de esos módulos de prueba puede tener su propio testInstrumentationRunner.

Para ver un ejemplo detallado, consulte el proyecto de ejemplo AndroidTestingBlueprint en github.

La solución de @ johan-stuyts que obtuvo recompensa funciona bien (o al menos lo hizo con el complemento Android gradle 1.2). Pero usa API privadas y crear un módulo separado es más fácil y a prueba de futuro.