2008-12-18 14 views
21

Acabo de comenzar a escribir pruebas para una gran cantidad de código. Hay muchas clases con dependencias al sistema de archivos, es decir, leen archivos CSV, archivos de configuración de lectura/escritura, etc.Mejores prácticas para las dependencias del sistema de archivos en las pruebas de unidad/integración

Actualmente los archivos de prueba se almacenan en el directorio de prueba del proyecto (es un proyecto Maven2) pero por varias razones este directorio no siempre existe, por lo que las pruebas fallan.

¿Conoces las mejores prácticas para hacer frente a las dependencias del sistema de archivos en las pruebas de unidad/integración?

Editar: No estoy buscando una respuesta para ese problema específico que describí anteriormente. Eso fue solo un ejemplo. Preferiría recomendaciones generales sobre cómo manejar las dependencias al sistema de archivos/bases de datos, etc.

Respuesta

0

Por lo general, las pruebas del sistema de archivos no son muy críticas: el sistema de archivos se entiende bien, es fácil de configurar y mantener estable. Además, los accesos suelen ser bastante rápidos, por lo que no hay razón para evitarlo o para burlarse de las pruebas.

Sugiero que averigüe por qué el directorio no existe y asegúrese de que lo haga. Por ejemplo, verifique la existencia de un archivo o directorio en setUp() y copie los archivos si la verificación falla. Esto solo ocurre una vez, por lo que el impacto en el rendimiento es mínimo.

1

Hay dos opciones para el código de prueba que necesita para leer de archivos:

  1. Mantener los archivos relacionados con las pruebas de la unidad de control de origen (por ejemplo, en una carpeta de datos de prueba), por lo que cualquier persona que recibe el Lo último y ejecuta las pruebas siempre tiene los archivos relevantes en una carpeta conocida relativa a los archivos binarios de prueba. Esta es probablemente la "mejor práctica".

  2. Si los archivos en cuestión son enormes, es posible que no desee mantenerlos en control de fuente. En este caso, un recurso compartido de red accesible desde todos los desarrolladores y máquinas de creación es probablemente un compromiso razonable.

Obviamente, la mayoría de las clases bien redactadas no tendrán dependencias duras en el sistema de archivos en primer lugar.

24

Primero uno debe intentar mantener las pruebas de la unidad lejos del sistema de archivos - vea esto Set of Unit Testing Rules. Si es posible, haga que su código funcione con Streams que serán almacenamientos intermedios (es decir, en la memoria) para las pruebas unitarias y FileStream en el código de producción.

Si esto no es posible, puede hacer que las pruebas de su unidad generen los archivos que necesitan. Esto hace que la prueba sea fácil de leer, ya que todo está en un solo archivo. Esto también puede evitar el problema de permisos.

Puede mock el sistema de archivos/base de datos/acceso a la red en las pruebas de su unidad.

Puede considerar las pruebas unitarias que dependen de DB o sistemas de archivos como pruebas de integración.

2

dependencias del sistema de ficheros son de dos tipos: de aquí

  • archivos que sus pruebas dependen; si necesita archivos para ejecutar la prueba, puede generarlos en sus pruebas y ponerlos en un directorio /tmp.
  • archivos de los que depende su código: archivos de configuración o archivos de entrada.

En este segundo caso, a menudo es posible volver a la estructura de su código para eliminar la dependencia de un archivo (por ejemplo java.io.File se puede sustituir por java.io.InputStream y java.io.OutputStream, etc.) Esto puede no ser posible por supuesto.

Es posible que también necesite manejar 'no-determinismo' en el sistema de archivos (tuve un demonio de trabajo depurando algo en un NFS una vez). En este caso, probablemente deba envolver el sistema de archivos en una interfaz delgada.

En su forma más simple, esto es sólo métodos auxiliares que tienen un archivo y desviar la llamada a ese archivo:

InputStream getInputStream(File file) throws IOException { 
    return new FileInputStream(file); 
} 

Luego, puede sustituir a éste con una maqueta que se puede dirigir a emitir la excepción, o devuelva un ByteArrayInputStream, o lo que sea.

Lo mismo puede decirse de las URL y URI.

0

Proporcione los archivos de prueba, tanto dentro como fuera, nombres estructuralmente similares al nombre de prueba de la unidad.

En JUnit, por ejemplo, que haría uso:

File reportFile = new File("tests/output/" + getClass().getSimpleName() + "/" + getName() + ".report.html"); 
Cuestiones relacionadas