2015-07-21 18 views
16

Il mio progetto ha 2 diversi gruppi di test. Un gruppo viene eseguito solo con il valore predefinito AndroidJUnitRunner mentre l'altro deve essere eseguito con un'implementazione personalizzata .Come cambiare/cambiare testInstrumentationRunner in modo dinamico con gradle

Attualmente mi passare il testInstrumentationRunner modificando il build.gradle ogni volta che ho bisogno di eseguire l'altro gruppo di test:

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

So che i sapori possono avere il proprio testInstrumentationRunner ma il mio attuale applicazione ha già 2 flavourDimensions. L'utilizzo di sapori è in realtà destinato a versioni diverse di un'app. Ho bisogno di 2 versioni dell'applicazione di test, entrambe testano la stessa app con diversi testInstrumentationRunner s.

Ho provato a cambiare il testInstrumentationRunner iterando su tutte le varianti di test. Ci sono in realtà molteplici testInstrumentationRunner proprietà:

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

    variant.variantData.variantConfiguration.defaultConfig.testInstrumentationRunner 

} 

Ma appena android.testVariants si chiama la costruzione ottiene configurato e tutte le modifiche non si riflettono nella build.

Come posso modificare dinamicamente TestInstrumentationRunner (da un plugin gradle)?

Preferirei avere 2 compiti gradle diversi, ognuno con un diverso testInstrumentationRunner ma testando la stessa variante. Poiché intendo creare un plugin gradle, la soluzione dovrebbe funzionare anche come plugin.

risposta

2

Ho avuto un problema simile, ho usato taskgraph del gradle. In base alla tua affermazione "Il mio progetto ha 2 diversi gruppi di test." Ho intenzione di assumere avete diversi compiti definiti, io chiamarli testGroupOne e 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" 
    } 
} 

Ciò consente di impostare il valore di testInstrumentationRunner dopo la configurazione, ma prima dell'esecuzione.

+0

Il plug-in Android è già stato configurato e utilizza testInstrumentationRunner dalla fase di configurazione. – thaussma

0

Questa è una soluzione parziale, ma forse questo renderà le cose un po 'meno ingombranti per te: non ti consente di eseguire i test con entrambi i test runner nella stessa build. Se lo desideri, dovrai clonare tutte le istanze di attività di DeviceProviderInstrumentTestTask, che, a mio avviso, sono troppo complesse e fragili.

Questo funziona per me (Gradle 2.4 e Android build tools 1.2.3). Utilizza le API interne, quindi è possibile che questo non funzioni più con la prossima versione degli strumenti di build di Android.

È necessario modificare le attività generate dal plug-in Android dopo che il progetto è stato valutato. Le modifiche verranno quindi utilizzate dalle attività di test. La proprietà che modifica effettivamente il runner di test utilizzato è task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner. Invece di apportare queste modifiche durante la fase di configurazione (ad esempio all'esterno di un'attività), le modifiche vengono applicate utilizzando un'attività, quindi il test runner viene utilizzato solo quando richiesto.Forzando i compiti di prova a rincorrere useMyTestRunner (se quest'ultimo è parte della costruzione), il nome della classe del test runner sarà stato modificato quando un compito test inizia:

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 
    } 
} 

È ora possibile eseguire i test utilizzando il test runner predefinito configurato per il sapore (s) con:

gradle :myApp:connectedAndroidTest 

Quando si desidera eseguire i test con l'utilizzo test runner:

gradle :myApp:connectedAndroidTest :myApp:useMyTestRunner 

ho fatto non aggiungere controlli per null per nessuna delle proprietà recuperate utilizzando task.testVariantData.variantConfiguration.testedConfig.mergedFlavor.testInstrumentationRunner. Dovresti aggiungerli per robustezza. Penso che almeno lo testedConfig richieda attenzione. Vedi getInstrumentationRunner() a https://android.googlesource.com/platform/tools/build/+/master/builder/src/main/java/com/android/builder/VariantConfiguration.java

È possibile utilizzare un'importazione per com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask nella parte superiore del file di generazione, quindi è sufficiente utilizzare il nome semplice della classe.

2

Avete considerato di utilizzare il parametro della console come un passaggio tra due configurazioni? Più semplice di così:

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

E poi per esempio eseguire gradlew aDeb -PcustomRunner se si desidera verificare utilizzando corridore personalizzato o gradlew aDeb da utilizzare di default.

So che non è scienza missilistica, ma più semplice è meglio, giusto? Puoi usarlo anche nel tuo plugin, basta ottenere l'oggetto Project e fare la stessa cosa.

+0

come scrivere la stessa cosa nel file Android.mk? qualche idea? – Ambi

+0

È possibile attivare questo passaggio dalla configurazione di esecuzione di Android Studio? – funkybro

+0

dai un'occhiata a questo: http://stackoverflow.com/questions/21972581/how-to-pass-a-parameter-in-run-debug-configuration-from-android-studio – Dmide

4

Dal plug-in Android Gradle 1.3 è possibile creare moduli di test separati. Ciascuno di questi moduli di test può avere il proprio testInstrumentationRunner.

Per un esempio dettagliato vedere il progetto di esempio AndroidTestingBlueprint su github.

La soluzione da @ johan-stuyts che ha tanta rounty funziona bene (o almeno lo ha fatto con il plugin gradle android 1.2). Ma utilizza API private e la creazione di un modulo separato è più facile e a prova di futuro.

+2

Quel progetto di esempio non illustra più moduli di test in un singolo progetto, in effetti non crea correttamente. – funkybro

+0

Il progetto di esempio non funziona e non c'è alcuna configurazione per TestRunner diverso. –

Problemi correlati