Pruebas unitarias de Android Studio: leer archivo de datos (entrada)


En una prueba unitaria, ¿cómo puedo leer datos de un archivo json en mi sistema de archivos (de escritorio), sin codificar la ruta?

Me gustaría leer la entrada de prueba (para mis métodos de análisis) de un archivo en lugar de crear cadenas estáticas.

El archivo está en la misma ubicación que mi código de pruebas unitarias, pero también puedo colocarlo en otro lugar del proyecto si es necesario. Estoy usando Android Studio.

Author: Frank, 2015-03-30

5 answers

Dependiendo de android-gradle-plugin versión:

1. versión 1.5 y superior:

Simplemente coloque el archivo json en src/test/resources/test.json y haga referencia a él como

classLoader.getResource("test.json"). 

No se necesita ninguna modificación de gradle.

2. versión inferior a 1.5 : (o si por alguna razón la solución anterior no funciona)

  1. Asegúrate de usar al menos Android Gradle Plugin versión 1.1. Sigue el enlace para configurar Android Studio correctamente.

  2. Crear test directorio. Ponga las clases de prueba unitaria en el directorio java y ponga su archivo de recursos en el directorio res. Android Studio debe marcarlos como sigue:

    introduzca la descripción de la imagen aquí

  3. Crear gradle tarea para copiar recursos en el directorio de clases para hacerlos visibles para classloader:

    android{
       ...
    }
    
    task copyResDirectoryToClasses(type: Copy){
        from "${projectDir}/src/test/res"
        into "${buildDir}/intermediates/classes/test/debug/res"
    }
    
    assembleDebug.dependsOn(copyResDirectoryToClasses)
    
  4. Ahora puede usar este método para obtener File referencia para el recurso de archivo:

    private static File getFileFromPath(Object obj, String fileName) {
        ClassLoader classLoader = obj.getClass().getClassLoader();
        URL resource = classLoader.getResource(fileName);
        return new File(resource.getPath());
    }
    
    @Test
    public void fileObjectShouldNotBeNull() throws Exception {
        File file = getFileFromPath(this, "res/test.json");
        assertThat(file, notNullValue());
    }
    
  5. Ejecutar la prueba unitaria mediante Ctrl+Shift+F10 en toda la clase o método de prueba específico.
 114
Author: klimat,
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
2018-03-07 09:57:42

Para pruebas unitarias locales (vs.pruebas de instrumentación), puede poner archivos bajo src/test/resources y leerlos usando ClassLoader. Por ejemplo, el siguiente código abre el archivo myFile.txt en el directorio resources.

InputStream in = this.getClass().getClassLoader().getResourceAsStream("myFile.txt");

Funcionó con

  • Android Studio 1.5.1
  • complemento de gradle 1.3.1
 56
Author: user3113045,
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
2016-01-28 20:43:38

En mi caso, la solución fue agregar al archivo gradle

sourceSets {
    test.resources.srcDirs += 'src/unitTests/resources'
  } 

Después de que todo fue encontrado por AS 2.3.1

javaClass.classLoader.getResourceAsStream("countries.txt")
 9
Author: ar-g,
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-05-25 12:00:38

He tenido muchos problemas con los recursos de prueba en Android Studio, así que configuré algunas pruebas para mayor claridad. En mi mobile (Aplicación Android) proyecto He añadido los siguientes archivos:

mobile/src/test/java/test/ResourceTest.java
mobile/src/test/resources/test.txt
mobile/src/test/resources/test/samePackage.txt

La clase de prueba (todas las pruebas pasan):

assertTrue(getClass().getResource("test.txt") == null);
assertTrue(getClass().getResource("/test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getResource("samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getResource("/test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getClassLoader().getResource("test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getClassLoader().getResource("test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));

En el mismo proyecto raíz tengo un proyecto Java (no Android) llamado data. Si añado los mismos archivos al proyecto de datos:

data/src/test/java/test/ResourceTest.java
data/src/test/resources/test.txt
data/src/test/resources/test/samePackage.txt

Entonces todas las pruebas anteriores fallarán si las ejecuto desde Android Studio, pero pasan el línea de comandos con ./gradlew data:test. Para evitar que utilice este hack (en Groovy)

def resource(String path) {
    getClass().getResource(path) ?:
            // Hack to load test resources when executing tests from Android Studio
            new File(getClass().getClassLoader().getResource('.').path
                    .replace('/build/classes/test/', "/build/resources/test$path"))
}

Uso: resource('/test.txt')

Android Studio 2.3, Gradle 3.3

 7
Author: Love,
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-03-12 18:44:40

Si va a Ejecutar -> Editar configuraciones -> JUnit y luego selecciona la configuración de ejecución para sus pruebas unitarias, hay una configuración de 'Directorio de trabajo'. Eso debería apuntar a dónde está su archivo json. Tenga en cuenta que esto podría romper otras pruebas.

 6
Author: Tas Morf,
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-04-07 12:55:31