Saltar al contenido
Cómo ejecutar pruebas unitarias en Angular

Cómo ejecutar pruebas unitarias en Angular

Aprenda a realizar pruebas unitarias en Angular, cómo simular un servicio en Angular y mucho más en este tutorial de pruebas unitarias Angular.

9min read

La mayoría de los equipos de desarrollo estarán de acuerdo en que las pruebas unitarias en Angular requieren mucho tiempo y muchos también estarán de acuerdo en que son innecesarias, y decidirán omitirlas. Dependiendo de la escala de su proyecto y las habilidades de programación de las personas que trabajan en él, no probar su aplicación Angular podría ser lo correcto. Pero, en general, las pruebas unitarias son extremadamente valiosas para evitar la creación de una base de código mal diseñada que dará lugar a una depuración y correcciones de código mucho más costosas más adelante. Entonces, ¿preferiría arriesgar la calidad de su código o preferiría comprender el código que está desarrollando por adelantado, ayudando a encontrar errores en el código al principio del ciclo de desarrollo?

Yo digo que no subestimes las pruebas unitarias, especialmente cuando trabajes en proyectos de aplicaciones de gran Angular, big data o ciencia de datos.

Try Ignite UI for Angular

A grandes rasgos: ¿Qué son las pruebas unitarias?

En el desarrollo de software, las pruebas unitarias (también llamadas pruebas aisladas) se llevan a cabo para garantizar que su aplicación funcione como debería, eliminando cualquier error en unidades separadas del código en la fase de desarrollo. Una prueba unitaria se puede ejecutar varias veces para comprobar el comportamiento de una unidad de código determinada para diferentes conjuntos de entrada.

Aborda problemas como la captura de valores faltantes, o preguntas como "¿La función de filtro reduce los valores de la manera correcta?", o otros más complejos en aplicaciones de ciencia de datos como "¿Los retornos de la función tienen formas como se esperaba?" y muchos otros.

En cuanto a por qué necesita pruebas unitarias, esto es lo que pienso:

  • La realización de pruebas unitarias le permite detectar y corregir errores de inmediato, evitando así salidas inesperadas en una fase mucho más avanzada del ciclo de desarrollo de la aplicación, cuando será más costoso y lento reescribir el código.
  • Al saber qué comportamiento esperar de una unidad particular del código, puede ver lo que está roto y, por lo tanto, puede actualizar su código más fácilmente.
  • La ejecución de pruebas unitarias le da confianza en la calidad del código y le ayuda a estructurarlo de una mejor manera.
  • Puedes probar clases individuales de forma aislada y los puntos fuertes de los bloques de acoplamiento en tu app para ver cómo se comportan.
  • Las pruebas unitarias permiten la refactorización, lo que significa que puedes modificar el código sin errores sin cambiar cómo se comporta, ya que ya sabes cómo funciona todo.
  • Dado que se realiza en unidades aisladas del código, cada vez que desee probar una característica recién agregada o una modificación de archivo, tiene la garantía de que la ejecución de pruebas unitarias no interrumpirá todo el código.
  • Las pruebas unitarias son súper rápidas y son capaces de simular todas las condiciones de error.
  • No pueden fallar por razones accidentales, como una interrupción de la red y el servicio o errores de autenticación de datos.
  • Súper útil en la llamada metodología de Programación Extrema que esencialmente te pide que pruebes todo lo que pueda romperse.
  • Si desea obtener información sobre una funcionalidad que proporciona una unidad y ver cómo usarla, puede usar las pruebas unitarias para obtener una comprensión básica de la API de la unidad.

¿Qué son las pruebas unitarias en Angular?

Las pruebas unitarias en Angular son un proceso para probar unidades individuales de código con el objetivo de identificar problemas como funciones que se comportan mal, lógica incorrecta y más lo antes posible. Y debido a que Angular proyectos son modulares de forma predeterminada, la ejecución de pruebas unitarias en dichas aplicaciones se siente un poco más intuitiva, ya que le permiten examinar las funciones de su aplicación de forma aislada.

A diferencia de otros marcos, Angular ofrece una excelente manera de realizar pruebas unitarias de sus modelos. Por lo general, los desarrolladores realizan pruebas manuales para verificar comportamientos y ver si su código es funcional o no. Sin embargo, en algunos casos, probar manualmente cada cambio menor lleva más tiempo en comparación con el desarrollo de una prueba unitaria. Pero Angular ofrece herramientas y ejecutores de pruebas como Karma que hacen las pruebas unitarias por ti.

Por qué deberías probar Angular aplicaciones

Probar su Angular base de código función por función es la mejor manera de mejorar la calidad del código, tener menos errores en producción y menos código muerto, reducir los costos de mantenimiento y lograr una refactorización más rápida e incluso actualizaciones sin discrepancias que rompan todo el código.

Puede parecer lento al principio, pero vale la pena a largo plazo. Los errores se detectan durante todo el desarrollo. Se ha mejorado el proceso de depuración. Si una determinada prueba falla, podemos encontrar fácilmente qué es exactamente lo que no funciona como se esperaba. Y debido a que el desarrollo basado en pruebas y las pruebas unitarias en particular suenan un poco más desafiantes de lo que realmente son, confiar en nuevas herramientas y mejores prácticas realmente puede facilitar y automatizar todo el proceso.

Cómo hacer pruebas unitarias en Angular y probar componentes Angular

Hay varias cosas que puede hacer un componente y debemos asegurarnos de que todos estos comportamientos se tengan en cuenta al escribir pruebas para componentes:

  • Pueden renderizar plantillas en el árbol HTML DOM.
  • Pueden aceptar datos de los componentes principales mediante entradas y emitir datos mediante salidas.
  • Pueden interactuar con diferentes tipos de eventos.
  • Pueden hablar con servicios o tiendas.
  • Pueden vincular datos y permitir que el usuario los edite.

En las siguientes secciones, demostraré cómo realizar pruebas unitarias en Angular y probar componentes.

We will start testing Angular components, using Ignite UI for Angular. Here’s what to do.

Set up TestBed

Angular proporciona TestBed para las pruebas, lo que crea un entorno en el que podemos probar componentes y servicios fácilmente. Se configura como un módulo Angular normal y luego se compilan todos los componentes declarados. Para guardar el código duplicado en cada prueba, podemos usarlo en la función beforeEach.

Configuración del banco de pruebas en el fragmento de código de prueba unitaria de Angular

Una vez compilados los componentes, podemos crear un componente que se renderiza en el DOM HTML. Cuando se utiliza un componente en el entorno de prueba, no se vuelve a representar automáticamente en las actualizaciones. Es por eso que necesitamos activarlo manualmente:

    fixture.detectChanges(); 

Probando el DOM

La mayoría de las veces, las funciones de los componentes realizan alguna lógica que refleja la plantilla. Podemos acceder al árbol DOM usando DebugElement y sus métodos query y queryAll:

  • La consulta devuelve el primer elemento que coincide con una condición
  • queryAll devuelve una colección de elementos coincidentes

Usando By.css() podemos obtener elementos por selectores CSS.

testing the dom in angular unit testing code screenshot

Desencadenar controladores de eventos

Imagine que tenemos una función que envía los datos de un formulario y se activa cuando hacemos clic en un botón en particular. En los exámenes, tenemos dos opciones. La primera es ejecutar la función directamente y la segunda, que es preferible, es simular un evento de clic en ese botón. Esto se puede hacer fácilmente usando triggerEventHandler de DebugElement. Tiene dos argumentos: el nombre del evento y las propiedades del evento.

Desencadenamiento de eventos en pruebas unitarias angulares

Si el evento es necesario, debe crearse con la palabra clave new y, a continuación, enviarse como parámetro en lugar de null.

Cómo "simular" datos usando dependencias falsas

En la mayoría de los casos, queremos probar un código concreto de forma aislada. Pero debido a que los componentes se comunican con muchos servicios diferentes y cada servicio tiene sus propias dependencias, se vuelve complejo (y el código se vuelve innecesariamente largo) agregar todas las dependencias solo para probar una funcionalidad.

En cambio, utilizando nuestro completo conjunto de herramientas de Ignite UI para Angular, podemos crear dependencias falsas que simulen el comportamiento de las reales. Este método se denomina simulación.

Using Jasmine spies

Jasmine nos proporciona una gran funcionalidad para crear dependencias falsas llamadas espías. Pongamos un ejemplo:.

using jasmine spies in angular unit testing

Vamos a tener un componente simple con un método que llama a fetchData desde DataService, que está haciendo una solicitud a una API para obtener algunos datos y después de eso, si hay una respuesta, guardamos estos datos en el componente.  En este caso, no queremos probar lo que está sucediendo en la función fetchData. Lo que nos importa es la respuesta. Entonces, aquí podemos fingir la respuesta usando el método spyOn y luego verificar si se activó este método.

Captura de pantalla de cómo obtener datos en Angular Unit Testing

Cómo probar código asincrónico y Angular observables

Las pruebas de código asincrónico son similares con pequeñas diferencias.

Prueba de código asincrónico en pruebas unitarias en código de captura de pantalla angular

Si queremos espiar un método que es asíncrono, usamos .resolveTo() en lugar de .returnValues(). Después de eso, si estamos probando un método asíncrono, hacemos dos cosas más. Primero, envolvemos la prueba en fakeAsync y luego usamos tick() que simula el paso del tiempo asíncrono.

Lo mismo se aplica si estamos probando datos de Angular Observable y BehaviorSubject que queremos mostrar en la plantilla. Necesitamos llenar el asunto con .next y luego usar tick() para esperar algún tiempo antes de procesar a la siguiente línea.

testing asynchronous method in unit testing in angular screenshot code

Medición de la cobertura del código

La cobertura de código es una métrica que nos indica qué partes del código se prueban con pruebas unitarias. Descubre partes de la aplicación que aún no se han probado. Al escribir código, debemos asegurarnos de que la puntuación de cobertura general no se reduzca, sino que aumente. Se acepta que la cobertura del código del 80% es un objetivo de código al que aspirar. Pero trate de cubrir la mayor cantidad de código posible. Cuanto más, mejor. Hay un comando incorporado que nos da un informe de cobertura. Todo lo que debemos hacer es agregar el indicador –code-coverage a nuestro comando de prueba.

Prueba NG –cobertura de código

Cobertura de código de medición en el código de captura de pantalla de Angular Unit Testing

Si no queremos usar el generador de cobertura de código incorporado de ng template, hay miles de otros paquetes npm entre los que puede elegir. Además, si está utilizando Azure DevOps para el desarrollo, también tienen funcionalidad integrada que podemos usar.

Por último, ¿cuáles son Angular mejores prácticas de pruebas unitarias?

Para terminar, me gustaría compartir un par de buenas prácticas que puede adoptar al realizar pruebas unitarias Angular.

  • Asegúrese de haber configurado correctamente su módulo de prueba ejecutando ng test desde la línea de comandos para comenzar a compilar y ejecutar Angular pruebas unitarias.
  • Asigne un nombre Angular la prueba unitaria correctamente, describiendo el método, el escenario en el que se está probando la unidad.
  • Construya sus funciones lo más pequeñas posible para que la prueba unitaria pueda ejecutarse de forma rápida y sin problemas.
  • Ejecute siempre pruebas unitarias en un entorno aislado, eliminando cualquier dependencia externa.
  • Utilice espías del marco de Jasmine para las dependencias al probar los servicios.
  • Es mejor acceder al DOM con debugElement (proporcionando una abstracción para el entorno de tiempo de ejecución principal) en lugar de llamar a nativeElement al probar componentes.
  • En caso de que ejecute su aplicación en el servidor, use By.css en lugar de queryselector, ya que este último solo funciona en el navegador.
  • Asegúrese de tener al menos un 80% de cobertura de código.
Ignite UI for Angular

Solicitar una demostración