La realización de pruebas en componentes de Angular que contienen elementos repetitivos presenta desafíos únicos que requieren estrategias específicas. Cuando trabajamos con galerías de imágenes o listas dinámicas, necesitamos métodos que nos permitan interactuar con elementos individuales dentro de colecciones. Dominar estas técnicas es fundamental para garantizar la calidad y robustez de nuestras aplicaciones Angular.
¿Cómo probar elementos repetitivos en Angular?
Cuando desarrollamos componentes que muestran colecciones de elementos, como galerías de imágenes, nos enfrentamos al reto de probar interacciones específicas con elementos individuales dentro de esas colecciones. En estos casos, no podemos simplemente agregar un data-testid único a cada elemento, ya que estos se generan dinámicamente.
El problema principal radica en que una buena práctica dicta que los atributos data-testid deben ser únicos, similar a los IDs en HTML. Cuando trabajamos con elementos generados mediante ciclos iterativos (como *ngFor), necesitamos una estrategia diferente.
Uso de selectores para elementos repetitivos
Para resolver este problema, podemos utilizar selectores que nos permitan acceder a colecciones de elementos. La estrategia consiste en:
Asignar un data-testid al contenedor que alberga los elementos repetitivos
Utilizar métodos de consulta para acceder a los elementos hijos específicos
Interactuar con los elementos individuales según sea necesario
Veamos un ejemplo práctico:
// Asignamos el data-testid al contenedor<div data-testid="gallery"><img *ngFor="let image of product.images"[src]="image"(click)="changeImage(image)"></div>
En nuestras pruebas, podemos acceder a todas las imágenes dentro de la galería:
it('Debería cambiar el cover cuando una imagen es clickeada',()=>{// Renderizamos el componente fixture.detectChanges();// Obtenemos el contenedor de la galeríaconst gallery = screen.getByTestId('gallery');// Obtenemos todas las imágenes dentro de la galeríaconst images = gallery.querySelectorAll('img');// Verificamos que existan imágenes antes de hacer clicif(images && images.length>0){// Hacemos clic en la segunda imagen (índice 1) fireEvent.click(images[1]);// Verificamos que el cover haya cambiado// Aquí iría la lógica para verificar el cambio}});
Generación de datos de prueba personalizados
Para tener un control más preciso sobre nuestras pruebas, es recomendable generar datos de prueba específicos. En el ejemplo, utilizamos Faker para generar imágenes de prueba:
// Importamos fakerimport{ faker }from'@faker-js/faker';// Generamos un producto con 4 imágenesconst mockProduct ={// Otras propiedades del producto images:[ faker.image.url(), faker.image.url(), faker.image.url(), faker.image.url()]};
Esto nos permite tener un conjunto conocido de datos para nuestras pruebas, lo que facilita la verificación de comportamientos específicos.
¿Cómo verificar interacciones con elementos repetitivos?
Una vez que tenemos acceso a los elementos individuales, podemos probar interacciones específicas como clics y verificar que el comportamiento sea el esperado.
Prueba de interacción con imágenes en una galería
En nuestro ejemplo, queremos verificar que al hacer clic en una imagen de la galería, el cover principal cambie:
it('Debería cambiar el cover cuando una imagen es clickeada',()=>{// Configuración inicial fixture.detectChanges();// Obtenemos la galería y sus imágenesconst gallery = screen.getByTestId('gallery');const images = gallery.querySelectorAll('img');// Guardamos la referencia al cover inicialconst initialCover = screen.getByTestId('main-cover').src;// Hacemos clic en la segunda imagenif(images && images.length>1){ fireEvent.click(images[1]);// Verificamos que el cover haya cambiadoconst newCover = screen.getByTestId('main-cover').src;expect(newCover).not.toEqual(initialCover);expect(newCover).toEqual(mockProduct.images[1]);}});
Es importante notar que en programación los índices comienzan en 0, por lo que images[1] se refiere a la segunda imagen de la colección.
Manejo de listas potencialmente vacías
Cuando trabajamos con colecciones que podrían estar vacías, es importante incluir verificaciones para evitar errores:
// Verificamos que existan imágenes antes de interactuarif(images && images.length>0){// Realizamos la interacción fireEvent.click(images[0]);}
Este enfoque defensivo nos protege contra errores en tiempo de ejecución durante las pruebas.
¿Qué ventajas ofrece este enfoque de testing?
El uso de selectores para acceder a elementos repetitivos en nuestras pruebas ofrece varias ventajas:
Flexibilidad: Podemos trabajar con colecciones dinámicas de elementos
Precisión: Podemos seleccionar elementos específicos dentro de una colección
Mantenibilidad: Evitamos la proliferación de atributos data-testid únicos
Realismo: Las pruebas se asemejan más a cómo los usuarios interactúan con la aplicación
Este enfoque nos permite probar de manera efectiva componentes complejos como galerías de imágenes, listas de productos, tablas de datos y otros elementos que muestran colecciones de información.
La capacidad de seleccionar y probar elementos individuales dentro de colecciones es una habilidad esencial para crear pruebas completas y robustas en aplicaciones Angular. Dominar estas técnicas te permitirá garantizar que tus componentes funcionen correctamente en todos los escenarios.
¿Has tenido dificultades al probar componentes con elementos repetitivos? Comparte tus experiencias y soluciones en los comentarios para ayudar a otros desarrolladores a superar estos desafíos.