Módulo INTERMEDIOLección 10 de 10

Testing con pytest

Escribe pruebas automáticas: la red de seguridad de tu código.

01

Teoría y Fundamentos

Lee y asimila los conceptos clave antes de evaluar

Un test es código que verifica tu código. pytest es el framework estándar de Python: escribes funciones normales con asserts y él hace el resto. Sin tests, cada cambio es un salto al vacío.

Tu primer test

Digamos que tienes mis_funciones.py:

def sumar(a, b):
    return a + b

Creas test_mis_funciones.py:

from mis_funciones import sumar

def test_sumar_dos_numeros():
    assert sumar(2, 3) == 5

def test_sumar_negativos():
    assert sumar(-1, -1) == -2

Ejecutas en la terminal:

pytest          # descubre y corre todos los test_*.py

Y ves:

test_mis_funciones.py ..                    [100%]
2 passed

Eso es todo: archivos test_*.py con funciones test_*() que usan assert. pytest los descubre por convención.

La convención de descubrimiento

  • Archivos: test_algo.py o algo_test.py
  • Funciones: empiezan con test_
  • Clases de tests: TestAlgo (sin __init__)

Si el nombre no cumple la convención, pytest no lo corre — error típico de principiante.

Qué probar: los tres niveles

def dividir(a, b):
    if b == 0:
        raise ValueError("división entre cero")
    return a / b

def test_caso_normal():
    assert dividir(10, 2) == 5.0

def test_caso_limite():
    assert dividir(0, 5) == 0.0      # el "borde" de tu dominio

def test_caso_de_error():            # verificar que SÍ lanza
    import pytest
    with pytest.raises(ValueError):
        dividir(1, 0)
  • Caso normal: entrada típica, resultado esperado
  • Casos límite: ceros, vacíos, negativos, valores máximos — donde viven los bugs
  • Casos de error: verificar que lanza la excepción correcta (pytest.raises)

Fixtures: preparar el escenario

Cuando varios tests necesitan los mismos datos, una fixture los construye:

import pytest

@pytest.fixture
def lista_ejemplo():
    return [3, 1, 2]

def test_maximo(lista_ejemplo):        # pytest inyecta la fixture
    assert max(lista_ejemplo) == 3

def test_ordenada(lista_ejemplo):
    assert sorted(lista_ejemplo) == [1, 2, 3]

La fixture se declara una vez y pytest la pasa como argumento por su nombre. Ideal para datos de prueba, conexiones temporales, archivos temporales (tmp_path).

Estructura de un buen test: AAA

def test_retiro_resta_del_saldo():
    # Arrange: preparar el escenario
    cuenta = Cuenta(saldo_inicial=100)

    # Act: ejecutar la acción bajo prueba
    cuenta.retirar(30)

    # Assert: verificar el resultado
    assert cuenta.saldo == 70

Un test = una sola razón de fallo. Si pruebas cinco cosas en un test y falla, no sabes cuál.

La regla de oro

No pruebes la implementación (cómo lo hace); prueba el comportamiento (qué promete). Así puedes refactorizar todo el interior sin romper un solo test — la red de seguridad que te deja moverte rápido sin miedo.

Resumen

  • test_*.py con funciones test_*() y assert — eso es pytest
  • Prueba casos normales, límites y errores (pytest.raises)
  • Las fixtures preparan datos reutilizables que se inyectan por nombre
  • Estructura AAA: Arrange, Act, Assert
  • Los tests no evitan bugs: los detectan antes de que lleguen a producción

¿Terminaste de leer la teoría?

Marca este paso para registrar tu avance y saltar a las preguntas

02

Quiz de Comprobación

3 preguntas de comprensión rápida (requiere 70% para aprobar)

  1. 1

    ¿Cómo debe llamarse un archivo y una función de test para que pytest los descubra?

  2. 2

    ¿Con qué instrucción se afirma un resultado en pytest?

  3. 3

    ¿Para qué sirve una fixture en pytest?

03

Laboratorio de Código Python

2 ejercicios interactivos ejecutados en tu navegador

EJERCICIO 01Python 3.12

Tu primer caso de prueba

Completa `es_palindromo(texto)` (se lee igual al derecho y al revés, sin distinguir mayúsculas). Los asserts funcionan como un mini pytest en tu navegador.

ejercicio_1.py
Tab: 4 spaces

Iniciando editor de código…

Ctrl/Cmd + Enter para ejecutar
EJERCICIO 02Python 3.12

Pensar en casos límite

Completa `suma_digitos(n)` (suma los dígitos del número). Los asserts cubren el caso normal, el límite (0) y números grandes.

ejercicio_2.py
Tab: 4 spaces

Iniciando editor de código…

Ctrl/Cmd + Enter para ejecutar