android testing android-espresso kotlin

android - Kotlin y la nueva ActivityTestRule: la @Rule debe ser pública



testing android-espresso (4)

Con Kotlin 1.0.0+, esto funciona:

@Rule @JvmField val mActivityRule = ActivityTestRule(MainActivity::class.java)

Estoy tratando de hacer una prueba de IU para mi aplicación de Android en Kotlin. Desde el nuevo sistema que usa ActivityTestRule, no puedo hacer que funcione: se compila correctamente, y en tiempo de ejecución, obtengo:

java.lang.Exception: The @Rule ''mActivityRule'' must be public. at org.junit.internal.runners.rules.RuleFieldValidator.addError(RuleFieldValidator.java:90) at org.junit.internal.runners.rules.RuleFieldValidator.validatePublic(RuleFieldValidator.java:67) at org.junit.internal.runners.rules.RuleFieldValidator.validateField(RuleFieldValidator.java:55) at org.junit.internal.runners.rules.RuleFieldValidator.validate(RuleFieldValidator.java:50) at org.junit.runners.BlockJUnit4ClassRunner.validateFields(BlockJUnit4ClassRunner.java:170) at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:103) at org.junit.runners.ParentRunner.validate(ParentRunner.java:344) at org.junit.runners.ParentRunner.<init>(ParentRunner.java:74) at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55) at android.support.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:38) at android.support.test.runner.AndroidJUnit4.<init>(AndroidJUnit4.java:36) at java.lang.reflect.Constructor.constructNative(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:417) at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.buildAndroidRunner(AndroidAnnotatedBuilder.java:57) at android.support.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:45) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29) at org.junit.runner.Computer.getRunner(Computer.java:38) at org.junit.runner.Computer$1.runnerForClass(Computer.java:29) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57) at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:98) at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:84) at org.junit.runners.Suite.<init>(Suite.java:79) at org.junit.runner.Computer.getSuite(Computer.java:26) at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:691) at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:654) at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:329) at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:226) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)

Así es como declaró mActivityRule:

RunWith(javaClass<AndroidJUnit4>()) LargeTest public class RadisTest { Rule public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>()) ... }

Ya es público: /


Con Kotlin 1.0.4:

val mActivityRule: ... @Rule get


JUnit permite proporcionar reglas a través de un campo de clase de prueba o un método getter.

Sin embargo, lo que anotó es en Kotlin una propiedad , que JUnit no reconocerá.

Estas son las formas posibles de especificar una regla JUnit en Kotlin:

A través de un método getter anotado

Desde M13 , el procesador de anotación admite objetivos de anotación . Cuando escribes

@Rule public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

sin embargo, la anotación utilizará el destino de la property de forma predeterminada (no visible para Java).

Sin embargo, puede anotar el captador de propiedades, que también es público y, por lo tanto, cumple los requisitos de JUnit para un captador de reglas:

@get:Rule public val mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(javaClass<MainActivity>())

Alternativamente, puede definir la regla con una función en lugar de una propiedad (logrando manualmente el mismo resultado que con @get:Rule ).

A través de un campo público anotado

Kotlin también permite, ya que el candidato beta, compilar de manera determinista las propiedades de los campos en la JVM, en cuyo caso las anotaciones y los modificadores se aplican al campo generado. Esto se realiza utilizando la anotación de propiedad @JvmField de Kotlin, según lo respondió @jkschneider .

Nota al margen: asegúrese de prefijar la anotación de Rule con un carácter @ , ya que ahora es la única sintaxis compatible para las anotaciones , y evite @publicField ya que pronto se eliminará .


Utilizar esta:

@get:Rule var mActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)