Fundamentos de Unit Tests
Los Unit Tests son el cimiento de la automatización de pruebas. Verifican las partes más pequeñas de un software de forma aislada y proporcionan retroalimentación rápida cuando algo deja de funcionar. Quien aprovecha bien los Unit Tests evita errores costosos y genera confianza en su código.
En resumen
- Los Unit Tests verifican funciones, clases o métodos individuales de forma aislada.
- Son rápidos, repetibles y ofrecen retroalimentación inmediata.
- Un buen Unit Test es independiente, determinista y se enfoca en un comportamiento específico.
- Forman la base amplia de la pirámide de pruebas.
Descripción técnica concisa
Un Unit Test verifica la unidad más pequeña y comprobable de un software en aislamiento. Típicamente se invoca una función o método con entradas definidas y se compara el resultado con un valor esperado. Las dependencias como bases de datos, sistemas de archivos o servicios externos se reemplazan con stubs o mocks, de modo que la prueba evalúa exclusivamente la lógica de la unidad.
Estructura de un Unit Test
Un Unit Test clásico sigue el patrón Arrange-Act-Assert:
- Arrange: Preparación de las entradas, objetos y dependencias.
- Act: Ejecución de la función bajo prueba.
- Assert: Verificación del resultado contra una expectativa.
Mejores prácticas
- Un test, un concepto: Cada prueba debe verificar un único comportamiento.
- Independencia: Las pruebas no deben depender las unas de las otras.
- Determinismo: Las mismas entradas deben producir siempre los mismos resultados.
- Legibilidad: Los nombres de las pruebas describen el comportamiento, no la metodología.
- Usa mocks con moderación: Demasiados mocks ocultan errores reales.
- No olvides los casos extremos: Prueba entradas vacías, valores nulos y límites.
Ejemplo práctico: Cálculo de precio con descuento
import unittest
def calculate_price(base_price, discount_percent):
if base_price < 0:
raise ValueError("Preis darf nicht negativ sein")
if discount_percent < 0 or discount_percent > 100:
raise ValueError("Rabatt muss zwischen 0 und 100 liegen")
return base_price * (1 - discount_percent / 100)
class TestPriceCalculation(unittest.TestCase):
def test_no_discount(self):
self.assertEqual(calculate_price(100, 0), 100)
def test_with_discount(self):
self.assertEqual(calculate_price(100, 20), 80)
def test_full_discount(self):
self.assertEqual(calculate_price(100, 100), 0)
def test_invalid_price(self):
with self.assertRaises(ValueError):
calculate_price(-10, 10)
def test_invalid_discount(self):
with self.assertRaises(ValueError):
calculate_price(100, 110)
if __name__ == '__main__':
unittest.main()
Ventajas e inconvenientes
Ventajas
- Retroalimentación rápida: Los Unit Tests se ejecutan en milisegundos hasta segundos.
- Localizar errores: Los problemas se acotan directamente a una unidad específica.
- Seguridad durante refactoring: Las pruebas existentes muestran si los cambios son correctos.
- Mejor estructura de código: El código testeable suele estar mejor modularizado.
- Documentación: Las pruebas demuestran cómo debe usarse una unidad.
Inconvenientes
- Esfuerzo inicial: Las pruebas deben escribirse y mantenerse.
- No todo es comprobable: La lógica de UI compleja o los sistemas externos son difíciles de testear de forma aislada.
- Falsa seguridad: Una cobertura de código alta no dice nada sobre la calidad de las pruebas.
- Mantenimiento de pruebas: Los Unit Tests mal escritos ralentizan el desarrollo.
Puntos clave para pruebas
- Definición y propósito de los Unit Tests.
- Patrón Arrange-Act-Assert.
- Diferencia entre Unit Tests e Integration Tests.
- Ventajas y limitaciones de los Unit Tests.
- Frameworks comunes: JUnit, NUnit, pytest, Jest.
Preguntas típicas de prueba (con respuesta breve)
-
¿Qué es un Unit Test? Una prueba que verifica una unidad comprobable más pequeña de forma aislada.
-
¿Qué patrón se usa frecuentemente para Unit Tests? Arrange-Act-Assert.
-
¿Qué es un Mock? Un objeto sustituto para una dependencia que simula un comportamiento controlado.
-
¿Por qué los Unit Tests deben ser deterministas? Para que las mismas entradas siempre produzcan el mismo resultado y las pruebas sean confiables.
-
Menciona una ventaja de los Unit Tests durante refactoring. Muestran inmediatamente si un cambio rompe el comportamiento existente.
Continúa en la ruta de aprendizaje de Software Testing
El siguiente artículo en la ruta de aprendizaje de Software Testing trata sobre Fundamentos de Integration Tests — cómo se prueba la interacción entre múltiples componentes.
Fuentes principales
- https://martinfowler.com/bliki/UnitTest.html
- https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html
- https://en.wikipedia.org/wiki/Unit_testing



