Decoradores de Unit Test para Saltar Pruebas y Detectar Fallos

Clase 8 de 20Curso de Unit Testing en Python

Resumen

En el desarrollo de software, es común enfrentarse a situaciones donde las pruebas unitarias no pueden ejecutarse por cambios o desarrollos en curso. En estos casos, comentar el código de las pruebas no es la mejor práctica. Afortunadamente, Python y unittest ofrecen decoradores que nos permiten omitir pruebas temporalmente, sin comprometer el flujo de trabajo ni la integridad del proyecto. Aquí aprenderemos cómo usar decoradores como @skip, @skipIf y @expectedFailure para manejar estos casos de manera eficiente.

¿Cómo utilizar el decorador @skip?

El decorador @skip se utiliza cuando sabemos que una prueba no debería ejecutarse temporalmente. Esto es útil si estamos trabajando en un feature que aún no está completo y, por lo tanto, las pruebas no tienen sentido. Al aplicar @skip, podemos evitar la ejecución de la prueba y aún así tener visibilidad de que está pendiente de ser corregida.

  • Aplicamos el decorador con una razón clara.
  • Cuando ejecutamos las pruebas, en el reporte se indicará que la prueba fue saltada.

Ejemplo de uso:

@unittest.skip("Trabajo en progreso, será habilitada nuevamente.")
def test_skip_example(self):
    self.assertEqual("hola", "chau")

¿Cuándo aplicar @skipIf?

El decorador @skipIf es útil cuando queremos omitir una prueba bajo una condición específica. Esto es común cuando nuestras pruebas dependen del entorno, como servidores diferentes o configuraciones específicas.

  • Requiere una condición y una razón para ser aplicado.
  • Se ejecutará solo si la condición es verdadera.

Ejemplo de uso:

server = "server_b"
@unittest.skipIf(server == "server_a", "Saltada porque no estamos en el servidor correcto.")
def test_skipif_example(self):
    self.assertEqual(1000, 100)

¿Qué hace el decorador @expectedFailure?

Este decorador se usa cuando sabemos que una prueba fallará debido a un cambio en la lógica del negocio o un bug conocido, pero queremos mantener la prueba visible en el reporte de pruebas.

  • Es útil para reflejar fallos esperados sin interferir con el flujo de integración continua.
  • El reporte mostrará que la prueba falló como se esperaba.

Ejemplo de uso:

@unittest.expectedFailure
def test_expected_failure_example(self):
    self.assertEqual(100, 150)

¿Cómo aplicar @skipUnless en casos avanzados?

El decorador @skipUnless es valioso cuando queremos ejecutar una prueba solo si se cumple una condición. Un ejemplo clásico es validar si un servicio externo, como una API, está disponible antes de ejecutar la prueba.

  • Es ideal para escenarios donde dependemos de recursos externos, como API’s de terceros.

Ejemplo de uso:

@unittest.skipUnless(api_available(), "API no disponible.")
def test_skipunless_example(self):
    self.assertEqual(get_currency_rate("USD"), 1.0)

¿Cuándo utilizar estos decoradores en desarrollo colaborativo?

El uso de decoradores como @skip, @skipIf, @expectedFailure y @skipUnless en un equipo de desarrollo asegura que las pruebas no interfieran en el flujo de trabajo, mientras mantienen la visibilidad de las pruebas pendientes. Es esencial en entornos de integración continua (CI), donde se busca que las pruebas no bloqueen el desarrollo, pero sin ignorarlas por completo.