¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. JavaScript y Angular
  3. Test unitarios
Extrait - JavaScript y Angular De los fundamentos del lenguaje al desarrollo de una aplicación web
Extractos del libro
JavaScript y Angular De los fundamentos del lenguaje al desarrollo de una aplicación web Volver a la página de compra del libro

Test unitarios

Introducción

Los test son una parte integral del ciclo de desarrollo de una aplicación. En un proceso de integración continuo, si una prueba no se realiza correctamente, se detiene todo el proceso.

Como regla general, probar una aplicación significa verificar que, a partir de datos conocidos, su comportamiento se corresponde perfectamente con lo esperado. Por ejemplo, probar una calculadora es tomar dos números, sumarlos y observar el resultado. Si el resultado coincide con lo que se esperaba, entonces la prueba es concluyente.

Angular hace que la escritura de test sea rápida y sencilla. Jasmine y Karma son las dos bibliotecas a cargo de los test unitarios (y Protractor, de los test de extremo a extremo; consulte el capítulo Test de extremo a extremo).

Un test unitario es un test para verificar una parte de un elemento aislado. Pueden ser los métodos de un componente, un servicio, un pipe e incluso una etiqueta HTML.

Un test unitario no comprueba las dependencias. Por lo tanto, será necesario simular el resultado de llamar a las dependencias para no bloquear el test. La modificación de un servicio, por ejemplo, nunca debe dar errores en los test unitarios de un componente que depende de él. Serán los test unitarios del propio servicio los que se verán afectados. Este principio de aislamiento es extremadamente importante. Un test unitario solo prueba un método...

Jasmine

Por convención, Angular busca pruebas unitarias en archivos que terminan en spec.ts. El archivo de pruebas unitarias para la clase de TypeScript my-Class.ts es myClass.spec.ts. Al generar un nuevo elemento con Angular CLI, siempre se crea un archivo de pruebas unitarias.

ng generate class clases/C17calculadora 

Jasmine tiene varios métodos esenciales para una buena redacción de exámenes. El mínimo es:

  • describe(): para declarar un grupo de varias pruebas.

  • it(): para declarar una sola prueba.

  • expect(): para definir el comportamiento esperado.

describe(descripcion, ( ) {  
        it(nombreDelTest, ( ) {  
                expect().metodoJasmine() ;  
        }  
}); 

metodoJasmine() es un método de la biblioteca Jasmine que introduce el concepto de parámetro de comparación. Los parámetros de comparación son lo suficientemente explícitos, siempre que el desarrollador tenga unos mínimos conocimientos de inglés. 

  • toBe: espera encontrar una igualdad estricta (igualdad de valores y tipos).

  • toEqual: espera encontrar una igualdad no estricta (igualdad de valores).

  • toContain: espera encontrar un elemento dentro de una matriz o cadena de caracteres.

  • toBeDefined: espera encontrar un objeto definido.

  • toBeNull: espera encontrar un valor de objeto nulo.

  • toBeTruthy: espera encontrar un valor de objeto verdadero.

  • toBeFalsy: espera encontrar un valor de objeto falso.

  • toHaveBeenCalled: espera que el método haya sido llamado.

  • toHaveBeenCalledWith: espera que el método haya sido llamado con los parámetros requeridos.

  • not: permite esperar lo contrario, de manera...

Test unitarios de un componente Angular

1. Clase TypeScript

Para probar un componente angular, se utiliza una biblioteca llamada @angular/core/testing. En esta biblioteca, la clase TestBed le permitirá definir un entorno apropiado para la prueba de componentes.

El método TestBed.configureTestingModule( { } ) es comparable en su sintaxis al decorador @NgModule() del archivo app.module.ts. Toma como parámetro un objeto compuesto por los atributos imports, declarationsproviders y schemas.

TestBed.configureTestingModule( {  
        imports: [ ],  
        declarations: [ ],  
        providers: [ ],  
        schemas: [ ]  
}).compileComponents(); 

El módulo de test contendrá así todos los objetos necesarios para el componente que se va a probar.

ng generate component componentes/C17 

Lo primero que debe probar es si el componente se ha instanciado correctamente.

TestBed permite la creación de un componente usando el método createComponent unComponente).

miVariable = TestBed.createComponent(miComponente); 

La prueba se relacionará con la instancia de la variable miVariable. Solo comprueba si es verdadera.

Dado que todas las pruebas se relacionarán con el componente creado, se recomienda encarecidamente poner todas las operaciones de creación de componentes en el método beforeEach().

// C:\JavaScriptYAngular\Angular\miProyectoAngular\src\app\  
components\c17.component.spec.ts  
import {ComponentFixture, TestBed} from '@angular/core/testing';  
import {C17Component} from './c17.component';  
  
describe('El componenteC17', () => {  
 let componente: C17Component;  
 let fixture: ComponentFixture<C17Component>;  
  
 beforeEach(() => {  
     // El componente está configurado y compilado  
     TestBed.configureTestingModule({  
       imports: [ ],  
       declarations: [C17Component],  
       providers: [ ],  
       schemas: [ ]  
 ...

Karma

Karma es un producto puro de los equipos de Angular. Junto con Jasmine, permite probar el mismo código en varios navegadores web diferentes de una manera completamente automatizada.

Configurado por defecto para trabajar con Jasmine al crear la aplicación por Angular CLI, Karma deja la posibilidad al desarrollador de cambiar la biblioteca de prueba si Jasmine no es adecuado. Además, Karma encaja perfectamente en un ciclo de desarrollo de aplicaciones de integración continua.

El archivo de configuración de Karma se encuentra en la raíz de un proyecto Angular: karma.conf.js.

Contiene, entre otras cosas, los complementos utilizados, los parámetros para la cobertura del código y todos los parámetros necesarios para iniciar un servidor y un navegador web.

Karma detecta cada modificación del código a medida que se inicia y se recarga para tener en cuenta los elementos más recientes (autowatch).

Puede iniciar uno o más navegadores web al mismo tiempo. Los valores posibles son Chrome, Firefox, Opera, IE, Safari… Pero se deben agregar complementos adicionales para eso.

npm install karma-firefox-launcher -save  
npm install karma-opera-launcher -save  
npm install karma-chrome-launcher -save  
npm install karma-ie-launcher -save  
npm install karma-safari-launcher --save 

// C:\miProyectoAngular\karma.conf.js  ...

Cobertura de código

ng test tiene una opción especialmente solicitada por los jefes de proyecto. Esto permite determinar el porcentaje de código cubierto por las pruebas unitarias.

ng test --code-coverage --watch=false 

Este comando produce dos elementos:

  • una tabla en la consola que lanzó el comando,

  • un sitio web visible en un navegador.

images/Image17-6.PNG

Visualización de la cobertura del código en la consola

El sitio web se genera automáticamente en un directorio de cobertura en la raíz del proyecto. Para acceder a él, simplemente abra el archivo index.html en un navegador.

images/Image17-7.PNG

Visualización de la cobertura del código en un navegador web

La cobertura del código solo se aplica al final del código realmente ejecutado, lo que significa que se puede lograr fácilmente una tasa de cobertura del 100 % sin probar absolutamente nada. De hecho, si no se prueba app.component.ts, no se prueba el componente principal de la aplicación y, por lo tanto, no se ejecuta absolutamente nada. Si no se ejecuta nada, se prueba todo.

En una aplicación clásica, con los archivos de prueba unitarios generados por Angular CLI, el informe de cobertura de código se parece más a esto:

images/Image17-8.PNG

Cobertura de código de una aplicación Angular

El sitio web permite la navegación mediante enlaces de hipertexto. Por lo tanto, podemos ver con precisión qué funciones...

Práctica

1. Enunciado

A partir de la aplicación PokemonManager desarrollada en los capítulos anteriores, instituya una cobertura de código mínima del 80 % en los cuatro elementos del informe.

Asegúrese de lograr una cobertura de código del 80 %.

2. Corrección

Por ahora, el comando ng test --code-coverage --watch=false no cumple con todas las condiciones de validez.

images/Image17-11.PNG

Cobertura del código inicial

Por supuesto, estos números pueden ser diferentes.

El servicio pokemons.service.ts es la clase más fácil de probar, ya que basta con verificar que los tres métodos están bien implementados. No es necesario comprobar el retorno de la llamada asincrónica a la API ya que una prueba unitaria no debe depender de otra clase. Aquí, la prueba debe ser concluyente, tanto si la API funciona como si no.

// C:\JavaScriptYAngular\Angular\PokemonManager\src\app\  
services\pokemons.service.spec.ts   
import { TestBed, inject } from '@angular/core/testing';  
  
import { PokemonsService } from './pokemons.service';  
import { HttpClientTestingModule } from '@angular/common/  
http/testing';  
  
describe('PokemonsService', () => {  
 let service: PokemonsService;  
  
 beforeEach(() => {  
   TestBed.configureTestingModule({  
     imports: [HttpClientTestingModule]  
   });  
   service = TestBed.get(PokemonsService);  
 });  
  
 it('debe ser creado', () => {  
   expect(service).toBeTruthy();   
 });  
  
 it(' debe implementar tres métodos ', () => {  
   expect(service.getGenerations()).not.toBeUndefined();  
   expect(service.getPokemons()).not.toBeUndefined();  
   expect(service.getPokemon('test')).not.toBeUndefined();   });  
}); 

El formulario de búsqueda es una clase de TypeScript simple que contiene un constructor y un setter. Probar esta clase es relativamente fácil....