unit testing - unitarias - Mejores prácticas para las dependencias del sistema de archivos en pruebas de unidad/integración
tdd (5)
Hay dos opciones para probar el código que necesita leer de los archivos:
Mantenga los archivos relacionados con las pruebas unitarias en control de fuente (por ejemplo, en una carpeta de datos de prueba), de modo que cualquiera que obtenga la última versión y ejecute las pruebas siempre tendrá los archivos relevantes en una carpeta conocida relativa a los archivos binarios de prueba. Esta es probablemente la "mejor práctica".
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.
Empecé a escribir pruebas para un montón 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.
Actualmente, los archivos de prueba se almacenan en el directorio de prueba del proyecto (es un proyecto de Maven2) pero por varias razones este directorio no siempre existe, por lo que las pruebas fallan.
¿Conoce 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.
Las dependencias en el sistema de archivos vienen en dos formas aquí:
- archivos de los que dependen tus pruebas; 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 estructurar el código para eliminar la dependencia de un archivo (por ejemplo, java.io.File se puede reemplazar por java.io.InputStream
y java.io.OutputStream
, etc.) Esto puede no ser así. ser posible, por supuesto.
También es posible que 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 solo métodos auxiliares que toman un archivo y reenvían la llamada a ese archivo:
InputStream getInputStream(File file) throws IOException {
return new FileInputStream(file);
}
A continuación, puede reemplazar este con un simulacro que puede dirigir para lanzar la excepción, o devolver un ByteArrayInputStream
, o lo que sea.
Lo mismo puede decirse de las URL y URI.
Por lo general, las pruebas del sistema de archivos no son muy importantes: el sistema de archivos se entiende bien, es fácil de configurar y se mantiene 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.
Primero, debe tratar de mantener las pruebas unitarias alejadas del sistema de archivos ; consulte este conjunto de reglas de prueba de unidades . De ser posible, haga que su código funcione con Streams que serán buffers (es decir, en la memoria) para las pruebas unitarias y FileStream en el código de producción.
Si esto no es factible, 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 simular el acceso al sistema de archivos / base de datos / 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.
Proporcione los archivos de prueba, tanto dentro como fuera, nombres estructuralmente similares al nombre de prueba de la unidad.
En JUnit, por ejemplo, usaría:
File reportFile = new File("tests/output/" + getClass().getSimpleName() + "/" + getName() + ".report.html");