Ejecución de pruebas JUnit simples en Android Studio (IntelliJ) cuando se utiliza una configuración basada en Gradle


Estoy usando Android Studio/IntelliJ para construir sobre un proyecto existente Android y me gustaría agregar algunas pruebas unitarias simples JUnit. ¿Cuál es la carpeta correcta para agregar tales pruebas?

El complemento android Gradle define una estructura de directorios con src/main/java para el código fuente principal y src/instrumentTest/java para las pruebas Android.

Intentar agregar mis pruebas JUnit en instrumentTest no funcionó para mí. Puedo ejecutarlo como una prueba Android (eso es lo que parece ese directorio) pero eso no es lo que estoy buscando-solo quiero ejecute una prueba simple JUnit. Intenté crear una configuración de JUnit run para esta Clase, pero eso tampoco funcionó, supongo que porque estoy usando un directorio que está marcado como Android Test en lugar de Source.

Si creo una nueva carpeta de origen y la marqué como tal en la Estructura del proyecto, se borrará la próxima vez que IntelliJ actualice la configuración del proyecto desde los archivos de compilación de gradle.

¿Cuál es la forma más apropiada de configurar las pruebas JUnit en un android basado en gradle project on IntelliJ? ¿Qué estructura de directorios usar para esto?

Author: hoss, 2013-07-25

6 answers

A partir de Android Studio 1.1, la respuesta ahora es simple: http://tools.android.com/tech-docs/unit-testing-support

 22
Author: Erik B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-11 20:53:48

Normalmente, no se puede. Bienvenido al mundo de Android, donde todas las pruebas deben ejecutarse en un dispositivo(excepto Robolectric).

La razón principal es que en realidad no tiene las fuentes del framework, incluso si convence al IDE de ejecutar la prueba localmente, obtendrá inmediatamente un " Stub! No implementado" excepción. "¿Por qué?"¿te preguntarás? Debido a que el android.jar que el SDK le da es en realidad todo stubbed - todas las clases y métodos están allí, pero todos ellos solo arrojan una excepción. Es allí para proporcionar una API, pero no para darle ninguna implementación real.

Hay un maravilloso proyecto llamado Robolectric que implementa gran parte del framework solo para que pueda ejecutar pruebas significativas. Junto con un buen marco de simulación (por ejemplo, Mockito), hace que su trabajo sea manejable.

Complemento de Gradle: https://github.com/robolectric/robolectric-gradle-plugin

 36
Author: Delyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-28 18:48:02

Intro

Tenga en cuenta que en el momento de escribir robolectric 2.4 es la última versión y no tiene soporte para la biblioteca appcompat v7. Se agregará soporte en la versión robolectric 3.0 ( todavía no hay ETA ). También ActionBar Sherlock puede causar problemas con robolectric.

Para usar Robolectric dentro de Android Studio tienes 2 opciones:

(Opción 1) - Ejecutar pruebas JUnit con Android Studio utilizando un módulo Java

Esta técnica utiliza un módulo java para todas sus pruebas con un dependencia a su módulo Android y un corredor de prueba personalizado con algo de magia:

Las Instrucciones se pueden encontrar aquí: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/

También verifique el enlace al final de esa publicación para ejecutar las pruebas desde android studio.

(Opción 2)-Ejecutar pruebas JUnit con Android Studio usando robolectric-gradle-plugin

Me encontré con algunos problemas al configurar las pruebas junit para que se ejecuten desde gradle en Android Studio.

Este es un proyecto de ejemplo muy básico para ejecutar pruebas junit desde un proyecto basado en gradle en Android Studio: https://github.com/hanscappelle/android-studio-junit-robolectric Esto se probó con Android Studio 0.8.14, JUnit 4.10, robolectric gradle plugin 0.13+ y robolectric 2.3

Buildscript (project/build.gradle)

El script de compilación es la compilación.archivo gradle en la raíz de tu proyecto. Allí tuve que añadir robolectric gradle plugin a classpath

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.13.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'

    }
}

allprojects {
    repositories {
        jcenter()
    }
}

Project buildscript (App/build.gradle)

En el script de compilación de su módulo de aplicación use el complemento robolectric, agregue robolectric config y agregue androidTestCompile dependencias.

apply plugin: 'com.android.application'
apply plugin: 'robolectric'

android {
    // like any other project
}

robolectric {
    // configure the set of classes for JUnit tests
    include '**/*Test.class'
    exclude '**/espresso/**/*.class'

    // configure max heap size of the test JVM
    maxHeapSize = '2048m'

    // configure the test JVM arguments
    jvmArgs '-XX:MaxPermSize=512m', '-XX:-UseSplitVerifier'

    // configure whether failing tests should fail the build
    ignoreFailures true

    // use afterTest to listen to the test execution results
    afterTest { descriptor, result ->
        println "Executing test for {$descriptor.name} with result: ${result.resultType}"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    androidTestCompile 'org.robolectric:robolectric:2.3'
    androidTestCompile 'junit:junit:4.10'
}

Crear clases de Prueba JUnit

Ahora coloca las clases de prueba en la ubicación predeterminada (o actualiza la configuración de gradle)

app/src/androidTest/java

Y nombre sus clases de pruebas que terminan con Test (o de nuevo actualizar configuración), extendiendo junit.framework.TestCase y anotar métodos de prueba con @Test.

package be.hcpl.android.mytestedapplication;

import junit.framework.TestCase;
import org.junit.Test;

public class MainActivityTest extends TestCase {

    @Test
    public void testThatSucceeds(){
        // all OK
        assert true;
    }

    @Test
    public void testThatFails(){
        // all NOK
        assert false;
    }
}

Ejecutar pruebas

Luego ejecute las pruebas usando gradlew desde la línea de comandos (hágalo ejecutable usando chmod +x si es necesario)

./gradlew clean test

Salida de muestra:

Executing test for {testThatSucceeds} with result: SUCCESS
Executing test for {testThatFails} with result: FAILURE

android.hcpl.be.mytestedapplication.MainActivityTest > testThatFails FAILED
    java.lang.AssertionError at MainActivityTest.java:21

2 tests completed, 1 failed                                  
There were failing tests. See the report at: file:///Users/hcpl/Development/git/MyTestedApplication/app/build/test-report/debug/index.html
:app:test                      

BUILD SUCCESSFUL

Solución de problemas

Directorios de fuentes alternativas

Al igual que puede tener sus archivos fuente java en otro lugar, puede mover sus archivos fuente de prueba. Simplemente actualiza la configuración de gradle sourceSets.

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        androidTest {
            setRoot('tests')
        }
    }

Paquete org.junit no existe

Olvidaste agregar la dependencia de prueba junit en el script de compilación de la aplicación

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    androidTestCompile 'org.robolectric:robolectric:2.3'
    androidTestCompile 'junit:junit:4.10'
}

Java.lang.RuntimeException: Stub!

Está ejecutando esta prueba con las configuraciones ejecutar desde Android Studio en lugar de la línea de comandos (pestaña Terminal en Android Studio). Para ejecutarlo desde Android Studio tendrás que actualizar el archivo app.iml para tener la entrada jdk listada en la parte inferior. Ver ejemplo de deckard-gradle para más detalles.

Ejemplo de error completo:

!!! JUnit version 3.8 or later expected:

java.lang.RuntimeException: Stub!
    at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5)
    at junit.textui.TestRunner.<init>(TestRunner.java:54)
    at junit.textui.TestRunner.<init>(TestRunner.java:48)
    at junit.textui.TestRunner.<init>(TestRunner.java:41)
    at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:190)
    at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:173)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

ERROR: JAVA_HOME se establece en un directorio no válido

Ver esta pregunta para una solución. Agregue la siguiente exportación a su perfil de bash:

export JAVA_HOME=`/usr/libexec/java_home -v 1.7`  

El registro de errores completo:

ERROR: JAVA_HOME is set to an invalid directory: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.

Clase de prueba no encontrada

Si desea ejecutar sus pruebas desde Android Studio Junit Test runner en su lugar, tendrá que expandir la compilación.gradle archiva un poco más para que android studio pueda encontrar tus clases de prueba compiladas:

sourceSets {
    testLocal {
        java.srcDir file('src/test/java')
        resources.srcDir file('src/test/resources')
    }
}

android {

    // tell Android studio that the instrumentTest source set is located in the unit test source set
    sourceSets {
        instrumentTest.setRoot('src/test')
    }
}

dependencies {

    // Dependencies for the `testLocal` task, make sure to list all your global dependencies here as well
    testLocalCompile 'junit:junit:4.11'
    testLocalCompile 'com.google.android:android:4.1.1.4'
    testLocalCompile 'org.robolectric:robolectric:2.3'

    // Android Studio doesn't recognize the `testLocal` task, so we define the same dependencies as above for instrumentTest
    // which is Android Studio's test task
    androidTestCompile 'junit:junit:4.11'
    androidTestCompile 'com.google.android:android:4.1.1.4'
    androidTestCompile 'org.robolectric:robolectric:2.3'

}

task localTest(type: Test, dependsOn: assemble) {
    testClassesDir = sourceSets.testLocal.output.classesDir

    android.sourceSets.main.java.srcDirs.each { dir ->
        def buildDir = dir.getAbsolutePath().split('/')
        buildDir =  (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/')

        sourceSets.testLocal.compileClasspath += files(buildDir)
        sourceSets.testLocal.runtimeClasspath += files(buildDir)
    }

    classpath = sourceSets.testLocal.runtimeClasspath
}

check.dependsOn localTest

De: http://kostyay.name/android-studio-robolectric-gradle-getting-work /

Algunos recursos más

Los mejores artículos que encontré alrededor de esto son:

 32
Author: hcpl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-01 07:49:29

Esto ahora es compatible con Android Studio a partir de Android Gradle plugin 1.1.0, mira esto:

Https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

Aplicación de ejemplo con pruebas unitarias locales en GitHub:

Https://github.com/googlesamples/android-testing/tree/master/unittesting/BasicSample

 4
Author: Lorenzo Polidori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-16 08:07:51

Para Android Studio 1.2 + configurar un proyecto para JUnit es bastante simple intenta seguir este tutorial:

Esta es la parte más simple de configurar un proyecto para JUnit:

Https://io2015codelabs.appspot.com/codelabs/android-studio-testing#1

Siga el enlace anterior hasta "Ejecutando sus pruebas "

Ahora, si desea integrarse con la prueba de intrumentación, siga a lo largo de aquí:

Https://io2015codelabs.appspot.com/codelabs/android-studio-testing#6

 1
Author: commonSenseCode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-09 00:50:58

Por favor, consulte este tutorial del sitio oficial de Desarrolladores de Android. Este artículo también muestra cómo crear maquetas para sus pruebas.

Por cierto, debe tener en cuenta que el alcance de las dependencias para la prueba simple JUnit debe ser "testCompile".

 0
Author: BlueMice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-09 01:36:06