Introducción al curso

1

Cypress Avanzado: Pruebas Automatizadas con Docker y Jenkins

2

Configuración Inicial de Cypress Avanzado en Node.js

Cookies y Localstorage

3

Gestión de Cookies en Cypress: Métodos Tradicionales y Experimentales

4

Automatización de Pruebas con Local Storage y Cypress

Emulando dispositivos

5

Emulación de Dispositivos Móviles con Cypress

Instalando plugins

6

Uso de Plugins y XPath en Cypress para Automatización Web

Flaky tests

7

Evitar pruebas inestables con Cypress: uso de retries y buenas prácticas

8

Interceptación de solicitudes de red con Cypress

9

Simulación de Errores de Red con Cypress Intercept

Buenas prácticas

10

Implementación de Page Object Model en Cypress

11

Comandos Personalizados en Cypress: Alternativa al Page Object Model

12

Variables de Entorno: Uso y Configuración en Cypress

13

Configuración de Variables de Entorno en Cypress

Visual testing

14

Implementación de Visual Testing con Cypress y Plugins

Seguridad

15

Seguridad en Cypress: Navegación y Pruebas entre Dominios

16

Manipulación de pestañas en Cypress: eliminar atributo target

17

Visitar múltiples dominios y compartir datos en Cypress 10

18

Creación de plugins en Cypress para compartir datos entre tests

Data Driven Test

19

Uso de Fixtures en Pruebas Automatizadas con Cypress

BDD

20

Configuración de Cucumber y Cypress para pruebas BDD

21

Reutilización de Step Definitions en Gherkin y Cucumber

22

Pruebas Automatizadas con Gherkin: Escenarios Outline y Tags

Reportes

23

Configuración y uso de múltiples reportes con Cypress

24

Configuración de Allure con Cypress y uso de plugins

Docker

25

Uso de Docker y Cypress para Pruebas Automatizadas

Dashboard

26

Conexión y uso del Dashboard de Cypress para pruebas automatizadas

27

Alternativa gratuita al dashboard de Cypress: instalación y uso

CI/CD

28

Integración de Jenkins y Cypress para Pruebas en Paralelo

Final

29

Instalación y uso del plugin Cypress Escenario Recorder

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Cypress Avanzado

Curso de Cypress Avanzado

Javier Fuentes Mora

Javier Fuentes Mora

Evitar pruebas inestables con Cypress: uso de retries y buenas prácticas

7/29
Recursos

¿Qué son los flaky tests y cómo evitarlos?

En el mundo del desarrollo de software, una de las mayores frustraciones para los desarrolladores son las pruebas inestables, o como se les conoce en inglés, los flaky tests. Estas son pruebas que a veces pasan y otras veces fallan sin una razón clara. Este fenómeno puede causar problemas serios, ya que lleva a perder tiempo y recursos tratando de identificar el problema. Vamos a explorar las causas comunes y cómo evitarlas para mejorar la estabilidad de nuestras pruebas.

¿Cuáles son las causas de los flaky tests?

Existen varias razones por las cuales las pruebas pueden ser inestables:

  • Respuestas inconsistentes de APIs: A veces, las APIs pueden devolver respuestas erróneas o correctas de manera aleatoria.
  • Timeouts: Ocurre cuando un componente tarda demasiado en responder, causando que la prueba falle.
  • Disponibilidad de servicios externos: Librerías o servicios externos pueden no estar disponibles en el momento de la prueba.
  • Elementos dinámicos: En aplicaciones de página única, donde elementos pueden cambiar de manera inesperada.

¿Cómo podemos evitarlos?

Para combatir los flaky tests, Cypress ofrece soluciones efectivas:

  1. Reintentar Pruebas: Cypress permite ejecutar pruebas automáticamente en caso de una falla inicial. Esto se logra mediante comandos específicos, en lugar de repetir todo el flujo de manera manual.

Configuración de reintentos en Cypress

En el archivo de configuración de Cypress (cypress.config), puedes habilitar los reintentos estableciendo el número de intentos deseados. Por defecto, esto está configurado en cero.

module.exports = {
  retries: {
    runMode: 2,       // Número de intentos al correr con Cypress Run
    openMode: 0       // Número de intentos al correr con Cypress Open
  }
}

Comandos single query y aserciones

¿Qué son los single query commands?

Utilizar comandos de consulta única en lugar de múltiples llamadas ayuda a que las pruebas sean más estables. Estos comandos permiten validar elementos dinámicos de manera más eficiente.

Ejemplo de código

Aquí tienes un ejemplo de cómo implementar un single query command:

cy.get('ci-selector')
  .should('have.text', 'Expected Text')

Esto permite que Cypress intente encontrar el elemento hasta que el texto coincida, reduciendo así la probabilidad de falla.

Ejemplo de alternar comandos con aserciones

El siguiente ejemplo muestra la importancia de validar que un botón no esté deshabilitado antes de hacer clic:

cy.get('button[type=submit]')
  .should('not.be.disabled')
  .click();

Este comando verifica que el botón no esté desactivado antes de realizar la acción de clic, asegurando más estabilidad en la prueba.

Importancia de las buenas prácticas de Cypress

Implementar las mejores prácticas de Cypress, como los single query commands y la configuración adecuada de reintentos, nos ayuda a crear pruebas más resistentes a cambios inesperados. Invito a los desarrolladores a aplicar estos principios en sus propios proyectos para disminuir la incidencia de flaky tests y mejorar la eficiencia en sus flujos de trabajo.

Finalmente, no olvidemos la importancia de continuar aprendiendo e incorporando estas herramientas en nuestra caja de herramientas para el desarrollo ágil y eficaz. ¡Nos vemos en la próxima clase donde continuaremos explorando cómo lidiar con los flaky tests a un nivel más profundo!

Aportes 1

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

# **Flaky test** Uno de los conceptos más desconocidos, pero a su vez más vividos, por los programadores es el «flaky test». Este concepto viene a referirse a la debilidad que tienen nuestros tests ya que son inestables y frágiles a cualquier cambio externo. Es decir, que el test se puede comportar diferente en cada ejecución presentando diferentes resultados (exitoso o fallido) sin haber realizado cambios en el código o en el test. Imagina que tienes un caso de uso que matricula a un estudiante con un curso determinado. ```js class EnrollmentStudentUseCase { private EnrollmentRepositoryInterface $enrollmentRepository; private CourseApi $courseApi; public function __construct( EnrollmentRepositoryInterface $enrollmentRepository, CourseApi $courseApi ) { $this->enrollmentRepository = $enrollmentRepository; $this->courseApi = $courseApi; } public function make( EnrollmentId $id, EnrollmentStudentId $studentId, EnrollmentCourseId $courseId ): void { $course = $this->courseApi->findByCourseId($courseId); $enrollment = Enrollment::make( $id, $studentId, $courseId, $course->title() ); $this->enrollmentRepository->save($enrollment); } } ```class EnrollmentStudentUseCase { private EnrollmentRepositoryInterface $enrollmentRepository; private CourseApi $courseApi; public function \_\_construct( EnrollmentRepositoryInterface $enrollmentRepository, CourseApi $courseApi ) { $this->enrollmentRepository = $enrollmentRepository; $this->courseApi = $courseApi; } public function make( EnrollmentId $id, EnrollmentStudentId $studentId, EnrollmentCourseId $courseId ): void { $course = $this->courseApi->findByCourseId($courseId); $enrollment = Enrollment::make( $id, $studentId, $courseId, $course->title() ); $this->enrollmentRepository->save($enrollment); } } **Prueba unitaria** ```js final class EnrollmentStudentUseCaseTest extends MockeryTestCase { /** @test */ public function it_should_enroll_student(): void { list($id, $title, $studentId, $courseId) = EnrollmentFaker::createValueObjectOne(); $enrollmentRepositoryInterfaceMock = $this->createEnrollmentRepositoryInterfaceMock(); $courseApi = new CourseApi(); $enrollmentMaker = new EnrollmentStudentUseCase($enrollmentRepositoryInterfaceMock, $courseApi); $enrollmentMaker->make($id, $studentId, $courseId); } private function createEnrollmentRepositoryInterfaceMock(): EnrollmentRepositoryInterface { $mock = \Mockery::mock(EnrollmentRepositoryInterface::class); $mock->shouldReceive('save')->once()->withArgs([Enrollment::class])->andReturnNull(); return $mock; } } ```final class EnrollmentStudentUseCaseTest extends MockeryTestCase { /\*\* @test \*/ public function it\_should\_enroll\_student(): void { list($id, $title, $studentId, $courseId) = EnrollmentFaker::createValueObjectOne(); $enrollmentRepositoryInterfaceMock = $this->createEnrollmentRepositoryInterfaceMock(); $courseApi = new CourseApi(); $enrollmentMaker = new EnrollmentStudentUseCase($enrollmentRepositoryInterfaceMock, $courseApi); $enrollmentMaker->make($id, $studentId, $courseId); } private function createEnrollmentRepositoryInterfaceMock(): EnrollmentRepositoryInterface { $mock = \Mockery::mock(EnrollmentRepositoryInterface::class); $mock->shouldReceive('save')->once()->withArgs(\[Enrollment::class])->andReturnNull(); return $mock; } } El test depende de un servicio externo (CourseApi), si este servicio es bastante inestable el test fallará. Con lo cual, tendremos un flaky test. Una forma de resolver esto es mockeando la dependencia que tiene el caso de uso. A continuación dejo una lista de cosas que pueden hacer que nuestro tests se conviertan en un flaky test. * Timeouts * Asynchronous Waits * Cache * Order dependency * Time of day