Configuración y uso de Live Unit Testing
Mientras desarrolla una aplicación, Live Unit Testing ejecuta automáticamente y en segundo plano las pruebas unitarias afectadas y presenta los resultados y la cobertura de código en tiempo real. Cuando modifica el código, Live Unit Testing proporciona comentarios sobre cómo los cambios afectaron a las pruebas existentes y si el código nuevo que ha agregado está cubierto por una o varias pruebas existentes. Esto le recuerda que debe escribir pruebas unitarias cuando realiza correcciones de errores o agrega nuevas características.
Cuando se usa Live Unit Testing para las pruebas, conserva los datos sobre el estado de las pruebas. El uso de datos persistentes permite que Live Unit Testing ofrezca un rendimiento superior mientras se ejecutan las pruebas de forma dinámica en respuesta a los cambios en el código.
Live Unit Testing solo está disponible en la edición Enterprise de Visual Studio para proyectos que tienen como destino .NET Core o .NET Framework.
Marcos de prueba admitidos
Live Unit Testing funciona con los tres marcos de pruebas unitarias conocidos enumerados en la tabla siguiente. También se muestra la versión mínima admitida de sus adaptadores y marcos. Los marcos de pruebas unitarias están disponibles en NuGet.org.
Marco de prueba | Versión mínima del adaptador de Visual Studio | Versión mínima del marco |
---|---|---|
xUnit.net | xunit.runner.visualstudio version 2.2.0-beta3-build1187 | xunit 1.9.2 |
NUnit | NUnit3TestAdapter version 3.5.1 | NUnit version 3.5.0 |
MSTest | MSTest.TestAdapter 1.1.4-preview | MSTest.TestFramework 1.0.5-preview |
Si tiene proyectos de prueba basados en versiones anteriores de MSTest que hacen referencia a Microsoft.VisualStudio.QualityTools.UnitTestFramework y no quiere migrar a los paquetes NuGet de MSTest más recientes, actualice a Visual Studio 2019 o Visual Studio 2017.
En algunos casos, es posible que tenga que restaurar explícitamente los paquetes NuGet a los que un proyecto hace referencia para que Live Unit Testing funcione. Tiene dos opciones:
- Restaurar mediante una compilación explícita de la solución. Seleccione Compilar>Recompilar solución en el menú de Visual Studio de nivel superior.
- Restaurar paquetes en la solución. Haga clic con el botón derecho en la solución y seleccione Restaurar paquetes NuGet.
Configurar
La primera vez que inicie Live Unit Testing para una solución, un asistente de configuración le permitirá configurar la forma en que Live Unit Testing debe compilar y ejecutar pruebas.
Cuando Live Unit Testing se detenga, también podrá abrir el asistente para la instalación; para ello, vaya a Prueba>Live Unit Testing>Configurar Live Unit Testing para la solución.
Cuando se ejecuta, Live Unit Testing crea un área de trabajo, que es una copia del repositorio original. Live Unit Testing aplica los cambios no guardados realizados en Visual Studio al área de trabajo, realiza una compilación, lleva a cabo una ejecución de prueba e informa sobre la cobertura de código más reciente.
Lo primero que debe configurar mediante el asistente es desde dónde y a dónde se deben copiar los archivos.
Raíz del repositorio
La raíz del repositorio especifica la carpeta que se copiará para crear el área de trabajo Live Unit Testing. Debe ser la carpeta raíz del repositorio, es decir, debe contener todos los orígenes, archivos binarios y herramientas. En los casos en los que el archivo de solución no esté presente en la raíz del repositorio, es posible que sea necesario cambiar la raíz del repositorio.
Raíz del área de trabajo
La raíz del área de trabajo especifica la carpeta donde Live Unit Testing mantiene un clon del repositorio. Tenga en cuenta las excepciones que indican que la ruta de acceso es demasiado larga. De forma predeterminada, la raíz se crea en la carpeta principal. Sin embargo, como ejemplo, si normalmente necesita crear el repositorio en la unidad C, la raíz del área de trabajo podría adaptarse a algo como C:\lut\Repo.
Especificar los archivos excluidos
No todos los archivos se deben copiar en el área de trabajo de Live Unit Testing. Los artefactos que se generan durante la compilación deben excluirse de la copia para que las compilaciones normales no interfieran con las compilaciones de Live Unit Testing. Además, el comando normal nuget restore
no debe interferir con el comando nuget restore
de Live Unit Testing.
De forma predeterminada, Live Unit Testing excluye uno de los dos patrones de archivos:
- En el caso de los repositorios de Git, los archivos especificados en el archivo de gitignore no se copian en el área de trabajo Live Unit Testing.
- En el caso de los repositorios que no son de Git, no se copia en el área de trabajo Live Unit Testing una lista básica de carpetas, como bin/ y obj/.
Para repositorios más complejos, es posible que tenga que especificar su propio archivo ignore. Seleccione la opción "<Personalizado>" del asistente. Después de seleccionar Siguiente, aparecerá el contenido de un archivo de omisión personalizado que Live Unit Testing crea después de finalizar el asistente. Es el archivo lutignore.
Nota
Para algunos repositorios de Git, se necesita un archivo lutignore personalizado, ya que es posible comprobar los archivos en el repositorio de Git que también se omiten en el archivo de gitignore. Sin un archivo de lutignore personalizado, Live Unit Testing no copiará estos archivos, lo que podría provocar errores de compilación.
Estructura de archivos Lutignore
El archivo lutignore usa el mismo formato que un archivo gitignore. Debe contener reglas que coincidan con las carpetas o archivos generados durante la compilación para que no se copien en el área de trabajo. Para la mayoría de las plantillas de proyecto predeterminadas, el siguiente archivo ignore es suficiente:
[BB]IN
[OO]BJ
# WILL NOT COPY ANY BIN AND OBJ FOLDERS TO THE LIVE UNIT TESTING WORKSPACE
En cambio, si el repositorio tiene una sola carpeta de compilación, el archivo ignore debe enumerar esa carpeta:
[AA]RTIFACTS/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE
Si el repositorio incluye otras herramientas en la carpeta de compilación, estas herramientas deben excluirse en el conjunto de patrones coincidentes:
[AA]RTIFACTS/
![AA]RTIFACTS/TOOLS/
# WILL NOT COPY THE ARTIFACTS FOLDER TO THE LIVE UNIT TESTING WORKSPACE
# HOWEVER IT WILL COPY THE TOOLS SUBFOLDER THAT MIGHT CONTAIN TOOLS AND UTILITIES
Opciones de compilación
La segunda parte de la página de configuración del asistente es donde se configuran las opciones de compilación:
- Generación de archivos PDB: para acelerar la compilación, Live Unit Testing no genera archivos PDB durante las compilaciones. Estos archivos de símbolos permiten ir a los seguimientos de la pila cuando se producen errores de prueba.
- Compilación mediante varios núcleos de CPU: de forma predeterminada, Live Unit Testing realiza compilaciones mediante varios núcleos de CPU, lo que mejora los tiempos de compilación. Si la máquina se ralentiza o si la solución no se puede compilar mediante varios procesadores, no seleccione esta opción.
Opciones de ejecución de pruebas
La última parte de la página de configuración del asistente es donde se configuran las opciones de ejecución de pruebas:
- Tiempo de espera del caso de prueba: algunas de las pruebas pueden tardar mucho tiempo en ejecutarse. Al establecer este campo, se anulan automáticamente las ejecuciones si alguna de las pruebas supera una duración de tiempo específica. Las pruebas se pueden cancelar automáticamente.
- Uso de varios procesadores: de forma predeterminada, Live Unit Testing intenta usar varios procesadores para acelerar el rendimiento de la ejecución. Si su máquina se ralentiza cuando esto ocurre o su solución no puede ejecutar pruebas en paralelo, no seleccione esta opción. Por ejemplo, estos escenarios podrían producirse si varias pruebas intentan escribir o leer desde las mismas rutas de acceso de archivo.
Más opciones de configuración
Configure Live Unit Testing desde Herramientas>Opciones en la barra de menús de Visual Studio de nivel superior. En el panel izquierdo del cuadro de diálogo Opciones, seleccione Live Unit Testing.
Una vez que Live Unit Testing se habilite (vea Iniciar, pausar y detener Live Unit Testing), también podrá abrir el cuadro de diálogo Opciones si selecciona Prueba>Live Unit Testing>Opciones.
La imagen siguiente muestra las opciones de configuración Live Unit Testing disponibles en el cuadro de diálogo.
A continuación se indican las opciones que se pueden configurar:
Si Live Unit Testing se pausa cuando se compila y depura una solución.
Si Live Unit Testing se pausa cuando la energía de la batería del sistema cae por debajo de un umbral especificado.
La capacidad de eliminar todos los datos persistentes. Esta funcionalidad es útil cuando Live Unit Testing se comporta de forma impredecible o inesperada, lo que sugiere que los datos persistentes están dañados.
La cantidad máxima de memoria que pueden consumir los procesos de Live Unit Testing.
El nivel de la información que se escribe en la ventana Salida de Live Unit Testing.
Las opciones incluyen no registrar nada (Ninguno), solo los mensajes de error (Error), mensajes de error e informativos (Información, el valor predeterminado) o todos los detalles (Detallado).
También puede mostrar la salida detallada en la ventana Salida de Live Unit Testing asignando un valor de 1 a una variable de entorno de usuario denominada
VS_UTE_DIAGNOSTICS
. A continuación, reinicie Visual Studio.Para capturar mensajes de registro de MSBuild detallados desde Live Unit Testing en un archivo, establezca la variable de entorno de usuario
LiveUnitTesting_BuildLog
en el nombre del archivo que va a contener el registro.
Personalización de la compilación para Live Unit Testing
Para soluciones más complejas, puede ser necesario personalizar aún más la compilación. Por ejemplo, es posible que no sea necesario compilar archivos de traducción durante las ejecuciones de prueba. Para acelerar las compilaciones, puede deshabilitar la compilación del archivo de traducción con Live Unit Testing. Para ello solo tiene que manipular los archivos del proyecto.
Añadir invalidaciones de Live Unit Testing
Si la solución requiere la compilación de pasos personalizados para la instrumentación (Live Unit Testing) que no son necesarios para la compilación no instrumentada "normal", entonces puede agregar código al proyecto o a los archivos .targets que compruebe la propiedad BuildingForLiveUnitTesting
y realice pasos personalizados anteriores y posteriores a la compilación.
Por ejemplo, puede escribir el ejemplo siguiente para agregar otro destino solo ejecutado para Live Unit Testing:
<Target Name="GenerateNuGetPackages" BeforeTargets="AfterBuild" Condition="'$(BuildingForLiveUnitTesting)' == 'true'">
<Exec Command='"$(MSBuildThisFileDirectory)..\tools\GenPac" '/>
</Target>
Puede usar la propiedad BuildingForLiveUnitTesting
para deshabilitar algunas tareas que no se deben ejecutar para las compilaciones de prueba. Por ejemplo, Live Unit Testing establece <RunAnalyzers>false</RunAnalyzers>
para deshabilitar los analizadores de las pruebas.
Dependencias de prueba de Live Unit Testing
Es posible que no se copien todos los archivos necesarios para que se ejecuten las pruebas. Live Unit Testing crea una carpeta independiente donde ejecuta pruebas. Esa disposición permite que se produzcan compilaciones mientras se ejecutan las pruebas, pero no todos los archivos de la carpeta de compilación se copian en la carpeta de prueba.
Normalmente, se agregan las dependencias de prueba por una de estas dos razones:
- Las pruebas dependen de los archivos del árbol de origen. Por ejemplo, las pruebas examinan el contenido de los archivos de resx o tal vez leen algunos archivos de configuración.
- Las pruebas dependen de algunas bibliotecas a las que hacen referencia. Por ejemplo, una prueba efectúa un archivo ejecutable que se compila como una dependencia.
Nota
Las dependencias de prueba deben existir en el directorio especificado como raíz del repositorio en el asistente para la instalación.
En ambos casos, Live Unit Testing de forma predeterminada no copiará estos archivos para minimizar el número de archivos que se deben copiar para ejecutar una prueba. Debe especificar explícitamente estos archivos mediante la propiedad LiveUnitTestingTestDependency
si es necesario para una ejecución de prueba. Por ejemplo, supongamos que tenemos el siguiente diseño:
SRC/
CONSOLE_UTILITY/
TEST_PROJECT/
ARTIFACTS/
CONSOLE_UTILITY/NET472/DEBUG/
TEST_PROJECT/NET472/DEBUG/
De forma predeterminada, al compilar estos proyectos con Live Unit Testing, solo se copia Artifacts/Test_Project
en la carpeta de prueba. Para agregar orígenes o el console_utility a la carpeta de prueba, agregue el ejemplo siguiente a test_project.csproj
:
<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Src/ConsoleUtility” />
<LiveUnitTestingTestDependency Include=”$(RepoRoot)/Artifacts/ConsoleUtility/net472/$(Configuration)/</LiveUnitTestingTestDependency” />
Iniciar, pausar y detener
Para habilitar Live Unit Testing, seleccione Prueba>Live Unit Testing>Iniciar en el menú de Visual Studio de nivel superior. Cuando Live Unit Testing se habilita, las opciones disponibles en el menú Live Unit Testing pasan de un elemento único (Iniciar) a Pausar y Detener:
Pausar suspende temporalmente Live Unit Testing.
Cuando Live Unit Testing se pausa, la visualización de la cobertura no aparece en el editor, pero se conservan todos los datos recopilados. Para reanudar Live Unit Testing, seleccione Continuar en el menú Live Unit Testing. Live Unit Testing hace el trabajo necesario para ponerse al día con todas las ediciones realizadas mientras estaba en pausa y actualiza los glifos apropiadamente.
Detener para completamente Live Unit Testing. Live Unit Testing descarta todos los datos que ha recopilado.
Si inicia Live Unit Testing en una solución que no incluye ningún proyecto de prueba unitaria, las opciones Pausar y Detener aparecerán en el menú Live Unit Testing, pero Live Unit Testing no se iniciará. En la ventana Salida se muestra un mensaje que comienza por "No supported test adapters are referenced by this solution..." ("Esta solución no hace referencia a ningún adaptador de prueba compatible...").
Live Unit Testing puede pausarse temporalmente o detenerse por completo en cualquier momento. Puede hacerlo, por ejemplo, si está en curso una refactorización y sabe que las pruebas se interrumpirán durante un tiempo.
Incluir y excluir proyectos de prueba y métodos de prueba
Al iniciar Live Unit Testing, aparecerá la ventana de la herramienta Live Unit Testing y le pedirá que seleccione el conjunto de pruebas que desea probar en Live Unit Testing.
Para soluciones más pequeñas en las que las pruebas unitarias tarden muy poco tiempo en ejecutarse, seleccione Incluir todas las pruebas, lo que hace que Live Unit Testing ejecute todas las pruebas.
Para soluciones más grandes con muchos proyectos de prueba, puede editar la lista de reproducción para controlar qué proyectos y métodos individuales de un proyecto participan en Live Unit Testing. Por ejemplo, si tiene una solución con cientos de proyectos de prueba, puede seleccionar un conjunto de proyectos de prueba de destino para participar en Live Unit Testing.
Puede editar una lista de reproducción de Live Unit Testing para elegir qué Live Unit Testing debe ejecutarse, una característica que funciona igual que las listas de reproducción en el Explorador de pruebas.
Hay varias maneras de editar la lista de reproducción de Live Unit Testing:
- La ventana de herramientas de Live Unit Testing
- La ventana del editor de código
- Explorador de soluciones
- Programando con el código de prueba
Live Unit Testing guarda el estado de inclusión o exclusión como una configuración de usuario y lo recuerda cuando una solución se cierra y se vuelve a abrir.
La ventana de herramientas de Live Unit Testing
Puede usar el editor de listas de reproducción de la pestaña Live Unit Testing para incluir o excluir proyectos, espacios de nombres o clases de la ejecución. Seleccione Editar lista de reproducción en la ventana de herramientas.
Puede seleccionar o borrar los elementos de vista de árbol para incluir o excluir pruebas. Por ejemplo, si comprueba una sola prueba, Live Unit Testing la ejecuta en los cambios. Si selecciona una clase, todas las pruebas de esa clase se ejecutan y las nuevas pruebas agregadas a esa clase también se ejecutan.
La ventana del editor de código
Puede usar la ventana del editor de código para incluir o excluir métodos de prueba individuales. Haga clic con el botón derecho en la firma o cuerpo del método de prueba en la ventana del editor de código y seleccione una de las opciones siguientes:
- Live Unit Testing>Incluir <método seleccionado>
- Live Unit Testing>Excluir <método seleccionado>
- Live Unit Testing>Excluir todo menos <método seleccionado>
Explorador de soluciones
Para seleccionar los proyectos individuales en pruebas unitarias, siga estos pasos después de iniciar Live Unit Testing:
- Haga clic con el botón derecho en la solución en el Explorador de soluciones y elija Live Unit Testing>Excluir para excluir toda la solución.
- Haga clic con el botón derecho en cada proyecto de prueba que quiera incluir en las pruebas y seleccione Live Unit Testing>Incluir.
Programando con el código de prueba
Puede aplicar el atributo ExcludeFromCodeCoverageAttribute para, mediante programación, excluir los métodos, las clases o las estructuras y evitar que informen de su cobertura en Live Unit Testing.
Use los atributos siguientes para excluir los métodos individuales de Live Unit Testing:
- xUnit:
[Trait("Category", "SkipWhenLiveUnitTesting")]
- NUnit:
[Category("SkipWhenLiveUnitTesting")]
- MSTest:
[TestCategory("SkipWhenLiveUnitTesting")]
Use los atributos siguientes para excluir un conjunto entero de pruebas de Live Unit Testing:
- xUnit:
[assembly: AssemblyTrait("Category", "SkipWhenLiveUnitTesting")]
- NUnit:
[assembly: Category("SkipWhenLiveUnitTesting")]
- MSTest:
[assembly: TestCategory("SkipWhenLiveUnitTesting")]
Ver visualización de cobertura
Cuando ya se ha habilitado, Live Unit Testing actualiza cada línea de código en el editor de Visual Studio para mostrar si el código que está escribiendo está cubierto por las pruebas unitarias y si las pruebas que cubre se superan.
En la imagen siguiente se muestran líneas de código con pruebas superadas y con errores y líneas de código que no están cubiertas por las pruebas. Las líneas con un "✓" verde solo se cubren al superar las pruebas. Las líneas con una "x" roja están cubiertas por una o varias pruebas con errores. Las líneas con un "➖" azul no están cubiertas por ninguna prueba.
La visualización de cobertura de Live Unit Testing se actualiza inmediatamente cuando modifica el editor de código. Mientras se procesan las modificaciones, la visualización cambia e indica que los datos no están actualizados con una imagen de cronómetro redondo debajo de los símbolos de superado, no superado y no cubierto, como se muestra en la imagen siguiente.
Obtener información acerca del estado de una prueba
Al mantener el puntero sobre el símbolo de superado o no superado en la ventana de código, puede ver cuántas pruebas alcanzan esa línea. Para ver el estado de las pruebas individuales, seleccione el símbolo.
Además de proporcionar los nombres y el resultado de las pruebas, la información sobre herramientas permite volver a ejecutar o depurar el conjunto de pruebas. Si selecciona una o varias de las pruebas de la información sobre herramientas, también puede ejecutar o depurar solo esas pruebas. Esta acción le permite depurar las pruebas sin tener que salir de la ventana de código.
Durante la depuración, además de observar cualquier punto de interrupción que ya pueda estar establecido, la ejecución del programa se pausa cuando el depurador ejecuta un método Assert que devuelve un resultado inesperado.
Al mantener el puntero sobre una prueba con error en la información sobre herramientas, esta se expande para proporcionar más información sobre el error, como se muestra en la siguiente imagen. Para ir directamente a una prueba con errores, haga doble clic en ella en la información sobre herramientas.
Cuando vaya a la prueba con errores, Live Unit Testing indicará visualmente en la firma del método las pruebas que:
- se han superado (indicado por un vaso de precipitado lleno hasta la mitad junto con una marca "✓" verde).
- no se han superado (indicado por un vaso de precipitado lleno hasta la mitad junto con una marca "🞩" en rojo).
- no están cubiertas por Live Unit Testing (indicado por un vaso de precipitado lleno hasta la mitad junto con una marca "➖" azul).
Los métodos no probados no se identifican con ningún símbolo. En la imagen siguiente se muestran los cuatro tipos de métodos.
Diagnosticar y corregir errores en las pruebas
A partir de la prueba con error, puede depurar fácilmente el código del producto, realizar ediciones y continuar desarrollando la aplicación. Dado que Live Unit Testing se ejecuta en segundo plano, no es necesario detener y reiniciar Live Unit Testing durante el ciclo de depuración, edición y continuación.
Por ejemplo, el error de la prueba que se muestra en la imagen anterior fue causado por la suposición incorrecta en el método de prueba de que los caracteres no alfabéticos devolverían true
cuando se pasaran al método System.Char.IsLower. Después de corregir el método de prueba, se deberían superar todas las pruebas. No tiene que pausar ni detener Live Unit Testing.
Ventana de Live Unit Testing
Live Unit Testing, similar al Explorador de pruebas, proporciona una interfaz que permite ejecutar y depurar pruebas, y analizar sus resultados. Cuando se habilita Live Unit Testing, el estado de las pruebas unitarias en el Explorador de pruebas se actualiza inmediatamente. No es necesario que ejecute de forma explícita las pruebas unitarias.
Cuando Live Unit Testing no está habilitado o está detenido, en Live Unit Testing se muestra el estado de las pruebas unitarias la última vez que se ha ejecutado una prueba. Después de reiniciar Live Unit Testing, se necesita un cambio del código fuente para volver a ejecutar las pruebas.
Para iniciar Live Unit Testing, seleccione Prueba>Live Unit Testing>Iniciar en el menú de Visual Studio de nivel superior. También puede abrir la ventana de Live Unit Testing mediante Vista>Otras ventanas>la ventana de Live Unit Testing.
Es posible que en la ventana de Live Unit Testing algunas de las pruebas aparezcan atenuadas. Por ejemplo, al detener y reiniciar Live Unit Testing, en la ventana de Live Unit Testing se atenúan todas las pruebas, como se muestra en la imagen siguiente.
Los resultados de las pruebas atenuadas indican que la prueba no formaba parte de la última ejecución de pruebas unitarias dinámicas. Las pruebas solo se ejecutan cuando se detecta un cambio en la prueba o en sus dependencias. Si no hay ningún cambio, evita que la prueba se ejecute de manera innecesaria. En este caso, el resultado de la prueba atenuada sigue siendo "actualizado", aunque no formara parte de la última ejecución.
Puede volver a ejecutar las pruebas que aparecen atenuadas si realiza un cambio en el código.
Hay algunas diferencias entre la ejecución y actualización automáticas de resultados de pruebas en Live Unit Testing y la ejecución explícita de pruebas desde el Explorador de pruebas. Estas diferencias incluyen:
- La ejecución o depuración de pruebas desde la ventana Explorador de pruebas ejecuta archivos binarios normales. Live Unit Testing ejecuta archivos binarios instrumentados.
- Live Unit Testing no crea un dominio de aplicación para ejecutar pruebas. En su lugar, ejecuta pruebas desde el dominio predeterminado. Las pruebas que se ejecutan desde la ventana Explorador de pruebas crean un nuevo dominio de aplicación.
- Live Unit Testing ejecuta pruebas secuencialmente en cada ensamblado de prueba. En la ventana Explorador de pruebas, puede optar por ejecutar varias pruebas en paralelo.
Cancelación de ejecuciones de pruebas de Live Unit Testing
Live Unit Testing sigue ejecutando pruebas cada vez que realice cambios en el código. Si una ejecución está en curso y realiza más cambios en el código, Live Unit Testing pone en cola otra ejecución mientras espera a que se complete la primera ejecución.
Siempre que guarde archivos, Live Unit Testing cancelará la primera ejecución y programará en su lugar y de forma inmediata la ejecución en cola. Este proceso ayuda con escenarios en los que la primera ejecución habría tardado mucho tiempo en completarse.