9. Nombres claros para las pruebas

9.1 Introducción

El nombre de una prueba unitaria es más importante de lo que parece. Una prueba no solo ejecuta una verificación: también comunica una intención a quienes leen y mantienen el código.

Cuando una prueba falla, muchas veces lo primero que vemos es su nombre. Si el nombre es claro, ya tenemos una pista sobre el comportamiento que se rompió. Si el nombre es genérico, debemos abrir la prueba y leer todo el cuerpo para entender qué ocurrió.

En este tema veremos cómo elegir nombres útiles, qué formatos se usan habitualmente y qué errores conviene evitar.

9.2 Qué debe comunicar el nombre

Un buen nombre de prueba debería comunicar tres ideas:

  • Qué unidad o comportamiento se prueba.
  • En qué situación o condición se ejecuta.
  • Qué resultado se espera.

Por ejemplo, el nombre test_edad_18_puede_registrarse comunica una situación concreta y un resultado esperado. En cambio, test_registro es demasiado general.

Un buen nombre de prueba funciona como una frase breve que describe el comportamiento esperado.

9.3 Ejemplo inicial

Supongamos una función que decide si una persona puede registrarse según su edad.

def puede_registrarse(edad):
    return edad >= 18


def test_edad_17_no_puede_registrarse():
    assert puede_registrarse(17) == False


def test_edad_18_puede_registrarse():
    assert puede_registrarse(18) == True

Estos nombres son útiles porque muestran el caso probado y el resultado esperado. Si falla test_edad_18_puede_registrarse, sabemos que el problema está en el límite de mayoría de edad o en la regla asociada.

9.4 Nombres genéricos

Los nombres genéricos son uno de los errores más frecuentes al comenzar.

def test_usuario():
    ...


def test_calculo():
    ...


def test_funciona():
    ...

Estos nombres no indican qué comportamiento se verifica. Cuando fallan, no aportan información. Además, con el tiempo aparecen muchas pruebas con nombres parecidos y la suite se vuelve difícil de navegar.

9.5 Nombres demasiado técnicos

El extremo opuesto es usar nombres que describen detalles internos en lugar del comportamiento esperado.

def test_if_linea_8_retorna_true():
    ...


def test_variable_auxiliar_queda_en_15():
    ...

Estos nombres acoplan la prueba a la implementación. Si refactorizamos el código sin cambiar el comportamiento, los nombres dejan de tener sentido. Conviene nombrar pruebas desde el punto de vista del comportamiento observable.

9.6 Formato: unidad, condición y resultado

Un formato práctico es:

test_[unidad o comportamiento]_[condición]_[resultado esperado]

Ejemplos:

  • test_calcular_descuento_cliente_vip_devuelve_15_por_ciento
  • test_validar_password_con_menos_de_8_caracteres_falla
  • test_carrito_vacio_tiene_total_cero
  • test_transferencia_mayor_al_saldo_es_rechazada

No todos los equipos usan exactamente este formato, pero la idea central se mantiene: el nombre debe explicar el caso.

9.7 Formato: dado, cuando, entonces

Otra forma común toma inspiración de la estructura "dado, cuando, entonces":

test_dado_[contexto]_cuando_[acción]_entonces_[resultado]

Ejemplo:

def test_dado_carrito_con_items_cuando_calcula_total_entonces_devuelve_suma():
    carrito = Carrito()
    carrito.agregar_item(100)
    carrito.agregar_item(50)

    total = carrito.calcular_total()

    assert total == 150

Este formato puede ser muy expresivo, aunque a veces produce nombres largos. Conviene usarlo cuando la claridad extra justifica la longitud.

9.8 Formato: debería

Algunos equipos usan nombres que expresan el comportamiento esperado con la palabra "debería".

def test_deberia_rechazar_transferencia_si_no_hay_saldo_suficiente():
    cuenta = Cuenta(saldo=100)

    resultado = cuenta.puede_transferir(150)

    assert resultado == False

La ventaja es que el nombre se lee como una especificación. La desventaja es que, si se abusa, muchos nombres empiezan igual y la parte importante queda al final.

9.9 Elegir un estilo consistente

No existe un único estilo obligatorio para nombrar pruebas. Lo importante es que el equipo use una convención consistente.

Un proyecto con nombres mezclados puede ser difícil de recorrer:

  • test_usuario
  • shouldValidateUserAge
  • test_dado_usuario_menor_entonces_error
  • pruebaEdadIncorrecta

La consistencia facilita buscar pruebas, entender reportes y mantener la suite.

9.10 Nombres para casos límite

Los casos límite deben quedar claramente identificados en el nombre. Esto ayuda a entender por qué se eligieron ciertos valores.

def password_tiene_longitud_valida(password):
    return len(password) >= 8


def test_password_de_7_caracteres_no_es_valido():
    assert password_tiene_longitud_valida("abcdefg") == False


def test_password_de_8_caracteres_es_valido():
    assert password_tiene_longitud_valida("abcdefgh") == True

Los nombres explican que 7 y 8 no son valores casuales: están alrededor del límite de la regla.

9.11 Nombres para errores esperados

Cuando el comportamiento esperado es un error controlado, el nombre debe decirlo con claridad.

def dividir(a, b):
    if b == 0:
        raise ValueError("No se puede dividir por cero")
    return a / b


def test_dividir_por_cero_lanza_value_error():
    try:
        dividir(10, 0)
        assert False
    except ValueError:
        assert True

El nombre indica la condición y el error esperado. Esto es más claro que un nombre como test_dividir_error.

9.12 Nombres para cambios de estado

Cuando la prueba verifica un cambio de estado, el nombre debe indicar el estado inicial, la acción o el resultado final.

def test_depositar_incrementa_el_saldo_en_el_importe_indicado():
    cuenta = Cuenta(100)

    cuenta.depositar(50)

    assert cuenta.saldo == 150

Este nombre comunica que la prueba no solo verifica que el método se ejecute, sino que el saldo aumenta correctamente.

9.13 Nombres para reglas de negocio

En reglas de negocio conviene usar vocabulario del dominio. Eso ayuda a que la prueba sea entendible incluso para personas que conocen el negocio pero no todos los detalles internos del código.

def test_cliente_vip_recibe_descuento_del_15_por_ciento():
    descuento = calcular_descuento(tipo_cliente="vip", monto=1000)

    assert descuento == 150

El nombre usa términos como cliente_vip y descuento, que pertenecen al dominio. Esto es mejor que nombrar la prueba según variables internas.

9.14 Nombres para pruebas parametrizadas

En pruebas parametrizadas, una misma prueba se ejecuta con varios datos. El nombre general debe describir la regla, y los parámetros deben ayudar a identificar cada caso.

def test_edades_mayores_o_iguales_a_18_pueden_registrarse():
    edades_validas = [18, 19, 30]

    for edad in edades_validas:
        assert puede_registrarse(edad) == True

Más adelante veremos pruebas parametrizadas con herramientas específicas. Por ahora, la idea importante es que el nombre explique la regla común a todos los datos.

9.15 Evitar nombres que prometen demasiado

El nombre de una prueba debe coincidir con lo que realmente verifica. Si el nombre dice que valida todo el registro de usuario, pero la prueba solo verifica la edad, el nombre es engañoso.

def test_registro_completo_de_usuario():
    assert puede_registrarse(18) == True

Un nombre más honesto sería:

def test_usuario_de_18_anios_puede_registrarse():
    assert puede_registrarse(18) == True

Una prueba debe prometer exactamente lo que comprueba.

9.16 Longitud del nombre

Un nombre largo no es necesariamente malo si aporta claridad. En pruebas unitarias, suele ser aceptable usar nombres más descriptivos que en funciones de producción.

Comparación:

Nombre Evaluación
test_descuento Demasiado general.
test_cliente_vip_recibe_descuento Más claro.
test_cliente_vip_con_compra_de_1000_recibe_descuento_de_150 Muy específico, útil si ese caso es importante.

El objetivo no es escribir el nombre más corto, sino el más útil.

9.17 Nombres y reportes de prueba

Cuando ejecutamos una suite, las herramientas suelen mostrar el nombre de las pruebas que fallan. Por eso el nombre debe ser informativo incluso fuera del contexto del archivo.

Un reporte que dice test_calculo falló obliga a investigar desde cero. Un reporte que dice test_descuento_cero_no_modifica_precio ya indica qué comportamiento se rompió.

Los buenos nombres reducen tiempo de diagnóstico.

9.18 Tabla de nombres buenos y malos

Nombre débil Nombre más claro
test_usuario test_usuario_menor_de_edad_no_puede_registrarse
test_total test_carrito_con_dos_items_calcula_total_correcto
test_error test_dividir_por_cero_lanza_value_error
test_descuento_ok test_cliente_vip_recibe_descuento_del_15_por_ciento
test_password test_password_de_7_caracteres_no_es_valido

9.19 Lista de comprobación

Antes de dejar una prueba, revisa su nombre:

  • ¿Indica el comportamiento probado?
  • ¿Menciona la condición o caso relevante?
  • ¿Expresa el resultado esperado?
  • ¿Evita detalles internos innecesarios?
  • ¿Coincide con lo que la prueba realmente verifica?
  • ¿Sería útil si aparece en un reporte de falla?

Si el nombre no responde estas preguntas, probablemente puede mejorarse.

9.20 Qué debes recordar de este tema

  • El nombre de una prueba debe comunicar intención.
  • Un buen nombre indica comportamiento, condición y resultado esperado.
  • Los nombres genéricos dificultan el diagnóstico.
  • Conviene evitar nombres basados en detalles internos.
  • La consistencia de estilo importa dentro de un proyecto.
  • Un nombre puede ser largo si aporta claridad.
  • El nombre debe coincidir con lo que la prueba realmente verifica.

9.21 Conclusión

Nombrar bien una prueba unitaria es parte del diseño de la prueba. Un nombre claro ayuda a leer la suite, entender reglas, diagnosticar fallas y mantener el proyecto con menos esfuerzo.

Las pruebas son documentación ejecutable, y el nombre es la primera línea de esa documentación. Por eso conviene dedicarle atención.

En el próximo tema estudiaremos las aserciones, que son las comprobaciones que determinan si una prueba pasa o falla.