2009-11-26 10 views
25

Estoy usando Visual Studio 2008 con las herramientas de prueba de Microsoft. Necesito acceder a un archivo de texto desde la unidad de prueba.Pruebas unitarias: ¿cómo acceder a un archivo de texto?

que ya ha configurado el archivo con la acción de construcción del grupo de 'contenido' y copiar al directorio de salida a 'Copiar siempre', pero el archivo no se está copiando en el directorio de salida, que según System.Environment.CurrentDirectory es

'{} project_path \ Resultado de la Pruebas \ Pablo_COMPU 2009-11-26 15_01_23 \ Out'

Esta carpeta contiene todas las dependencias DLL del proyecto, pero mi archivo de texto no está allí.

¿Cuál es la forma correcta de acceder a un archivo de texto desde una prueba unitaria?

Respuesta

35

Debe agregar el atributo DeploymentItem a su clase de prueba. Con este atributo, especifica los archivos que se copian en el directorio de salida para la ejecución de la prueba.

Por ejemplo:

[TestMethod] 
[DeploymentItem(@"myfile.txt", "optionalOutFolder")] 
public void MyTest() 
{ 
    ... 
} 

Consulte también: http://msdn.microsoft.com/en-us/library/ms182475.aspx.

0

¿Cómo está realizando sus pruebas?

Usamos (TestDriven.net -> Ejecutar pruebas).

Desde mi experiencia, algunos corredores de prueba (como Junit en Netbeans) no copiarán automáticamente ningún archivo de texto adicional que pueda necesitar para la prueba. Entonces, en su caso, es posible que deba hacer una compilación completa y luego intente ejecutar las pruebas nuevamente.

Y la manera correcta de acceder a los archivos de texto de las pruebas es la forma en que intenta hacerlo. (Configurando los archivos para "copiar siempre" y "contenido", y accediendo a ellos desde el directorio compilado).

Además, no estoy seguro de dónde está obteniendo la gente la idea de que tener pruebas basadas en archivos es algo malo. No es.

En todo caso, tener archivos de prueba separados, solo limpiará sus pruebas y las hará más legibles. Considere algunas método de análisis sintáctico XML que devuelve una cadena grande:

String expectedOutput = fileOperator.ReadStringFromFile("expectedFileContents.xml"); 
String result = systemUnderTest.Parse(somethingtoparse); 
Assert.Equals(expectedOutput, result); 

Imagínese si la salida era de 30 líneas de largo, le desorden de su código de prueba con una cadena gigante? o simplemente léelo de un archivo.

+0

Es un proyecto de Visual Studio Test. Prueba -> Ejecutar -> Todas las pruebas en solución. – Pablote

+0

¿Solucionó el problema una solución de reconstrucción? – vicsz

3

No puedo responder a su pregunta ya que no utilizo MSTest. Sin embargo, consideraría si acceder al sistema de archivos en una prueba unitaria es lo correcto. Si introduce una dependencia en el sistema de archivos, la prueba será más lenta y menos confiable (ahora depende de algo que puede no estar allí/accesible/etc.). Es por estas razones que mucha gente dirá "no es una prueba unitaria si llega al sistema de archivos".

Aunque esta no es una regla difícil, siempre vale la pena considerarla. Cada vez que tengo que tocar el sistema de archivos en las pruebas, trato de evitarlo porque encuentro que las pruebas que se basan en archivos son más difíciles de mantener y generalmente son menos consistentes.

Consideraría abstracting the file operations hasta cierto punto. Puede hacer muchas cosas aquí, desde cambiar la estrategia de carga interna (a través de Inyección de Dependencia) hasta, incluso mejor, separar la carga/uso del archivo para que el consumidor del contenido del archivo ni siquiera tenga que importar sobre la estrategia de carga.

+1

+1 Streams o TextReader/TextWriter son generalmente suficientes abstracciones. –

+2

No estoy seguro de dónde está obteniendo la idea de que las pruebas con archivos son malas. No es. Leer una cadena rápida de un archivo de texto NO es una operación lenta, y hacer que un archivo de prueba sea parte de su prueba (el mismo directorio) no es menos confiable. – vicsz

+4

Tengo la idea de trabajar en un proyecto con 10k pruebas mantenidas por varias personas. Los que tocan archivos son más volubles, más difíciles de mantener y más lentos que las pruebas que no afectan al sistema de archivos. Ejemplo: tuvimos que encontrar a alguien durante una sesión de refactorización para arreglar sus pruebas, ya que estábamos obteniendo errores de archivos no encontrados a pesar de que el archivo estaba presente y copiado en el directorio de salida. Resultó ser un error bastante oscuro en la prueba que dependía de la orden. Eso simplemente no sucedería con una prueba en la unidad de memoria. –

3

Cuando necesito un trozo de texto como parte de una prueba de unidad y es más que una línea o dos, utilizo un embedded resource. No satura su código de prueba, porque es un archivo de texto separado en el código fuente. Se compila directamente en el ensamblaje, por lo que no tiene que preocuparse de copiar en un archivo separado después de la compilación. Su objeto bajo prueba puede aceptar un TextReader y pasar el StreamReader que obtiene al cargar el recurso incrustado.

+0

¡Esta es una gran idea! ¿Puedes agregar un ejemplo del código? –

+0

Lo siento, no tengo un ejemplo a mano, @ fatcat1111. ¿Has leído el artículo de la base de conocimiento al que me he vinculado? –

+0

Consulte aquí para ver un ejemplo: https://adamprescott.net/2012/07/26/files-as-embedded-resources-in-unit-tests/ –

6

Alternativamente si establece todos sus archivos de texto a "Copiar a construir el directorio", entonces usted podría hacer referencia a su trayectoria en sus pruebas al hacer esto

var directory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
var path = string.Format("{0}\\{1}",directory,"myFile.txt"); 
+0

.. excepto que GetExecutingAssembly devuelve nulo cuando se lo llama desde un código no administrado, p. el corredor de pruebas Resharper 2016.2. – stuartd