17. Valores límite aplicados a pruebas unitarias

17.1 Introducción

En el tema anterior vimos clases de equivalencia: agrupamos valores que deberían comportarse igual. Ahora vamos a enfocarnos en los valores límite, es decir, los valores que están justo en el borde donde una regla cambia.

Muchos defectos aparecen por usar mal operadores como >, >=, < o <=. Por eso, probar los límites exactos es una técnica muy efectiva en pruebas unitarias.

En este tema veremos cómo elegir valores antes, en y después del límite, y cómo convertirlos en pruebas claras.

17.2 Qué es un valor límite

Un valor límite es un valor cercano al punto donde cambia el comportamiento de una regla.

Ejemplos:

  • Edad mínima 18: los valores importantes son 17, 18 y 19.
  • Contraseña mínima de 8 caracteres: 7, 8 y 9 caracteres.
  • Envío gratis desde 5000: 4999, 5000 y 5001.
  • Rango permitido de 1 a 10: 0, 1, 10 y 11.

No elegimos estos valores al azar. Los elegimos porque están alrededor de una decisión.

17.3 Regla general: antes, en y después

Una forma práctica de aplicar valores límite es elegir tres valores:

Un valor justo antes del límite, el valor exacto del límite y un valor justo después del límite.

Si la regla es "desde 18 inclusive", probamos 17, 18 y 19. Si la regla es "mayor que 10000", probamos 10000 y 10001, y muchas veces también 9999.

17.4 Ejemplo con edad mínima

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


def test_edad_19_puede_registrarse():
    assert puede_registrarse(19) == True

La prueba de 18 es la más importante porque confirma si el límite es inclusivo. Las pruebas de 17 y 19 verifican los lados cercanos del límite.

17.5 Error típico que detecta esta técnica

Supongamos que alguien implementa mal la regla:

def puede_registrarse(edad):
    return edad > 18

Con esta implementación, una persona de 18 años no puede registrarse. La prueba test_edad_18_puede_registrarse fallará y señalará el problema.

Este tipo de error es muy común: confundir un límite inclusivo con uno exclusivo.

17.6 Límite inclusivo y exclusivo

Un límite inclusivo acepta el valor exacto del límite. Un límite exclusivo lo rechaza.

Regla Operador Valor límite Resultado para el límite
Edad al menos 18 >= 18 18 Aceptado
Monto mayor que 10000 > 10000 10000 Rechazado
Máximo 10 ítems <= 10 10 Aceptado
Menor que 5 intentos < 5 5 Rechazado

17.7 Ejemplo con monto mínimo

Regla: una compra tiene envío gratis si el total es mayor o igual a 5000.

def tiene_envio_gratis(total):
    return total >= 5000


def test_total_4999_no_tiene_envio_gratis():
    assert tiene_envio_gratis(4999) == False


def test_total_5000_tiene_envio_gratis():
    assert tiene_envio_gratis(5000) == True


def test_total_5001_tiene_envio_gratis():
    assert tiene_envio_gratis(5001) == True

Estos tres casos dejan clara la frontera de la regla.

17.8 Ejemplo con contraseña mínima

Regla: una contraseña debe tener al menos 8 caracteres.

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


def test_password_de_9_caracteres_es_valido():
    assert password_tiene_longitud_valida("abcdefghi") == True

La longitud exacta de 8 caracteres es el punto principal. Los valores 7 y 9 verifican los lados cercanos.

17.9 Límites superiores

También existen límites máximos. Por ejemplo, una lista puede aceptar hasta 10 elementos.

def cantidad_permitida(items):
    return len(items) <= 10


def test_9_items_es_cantidad_permitida():
    assert cantidad_permitida([1,2,3,4,5,6,7,8,9]) == True


def test_10_items_es_cantidad_permitida():
    assert cantidad_permitida([1,2,3,4,5,6,7,8,9,10]) == True


def test_11_items_no_es_cantidad_permitida():
    assert cantidad_permitida([1,2,3,4,5,6,7,8,9,10,11]) == False

El límite superior exacto es 10. El valor 11 confirma que el máximo no se supera.

17.10 Rangos con mínimo y máximo

Algunas reglas tienen un mínimo y un máximo. En ese caso debemos revisar ambos bordes.

Regla: una calificación es válida si está entre 1 y 10 inclusive.

def calificacion_valida(nota):
    return nota >= 1 and nota <= 10

Valores relevantes: 0, 1, 2 para el borde inferior y 9, 10, 11 para el borde superior.

17.11 Pruebas para rango completo

def test_nota_0_no_es_valida():
    assert calificacion_valida(0) == False


def test_nota_1_es_valida():
    assert calificacion_valida(1) == True


def test_nota_10_es_valida():
    assert calificacion_valida(10) == True


def test_nota_11_no_es_valida():
    assert calificacion_valida(11) == False

Estos casos cubren ambos bordes. Podemos agregar 2 o 9 si queremos confirmar valores cercanos internos, pero los valores exactos y externos suelen ser los más importantes.

17.12 Valores límite y clases de equivalencia

Las clases de equivalencia y los valores límite se complementan.

  • Las clases de equivalencia ayudan a elegir grupos representativos.
  • Los valores límite ayudan a probar los bordes entre esos grupos.

Para una edad mínima de 18, las clases son menor a 18 y mayor o igual a 18. Los valores límite son 17, 18 y 19.

17.13 Cuándo no hace falta probar tantos valores

No siempre necesitamos antes, en y después de cada límite. La cantidad de casos depende del riesgo y de la importancia de la regla.

Si una regla es crítica, conviene ser más cuidadoso. Si es una regla simple y de bajo impacto, quizá baste con el valor exacto y un valor inválido cercano.

La técnica es una guía, no una obligación automática de triplicar todas las pruebas.

17.14 Valores límite con decimales

Con valores decimales, el "justo antes" y "justo después" depende de la precisión del dominio.

Por ejemplo, si una comisión aplica desde 1000.00 inclusive y trabajamos con dos decimales, los valores cercanos pueden ser 999.99, 1000.00 y 1000.01.

def aplica_comision(monto):
    return monto >= 1000.00


def test_monto_999_99_no_aplica_comision():
    assert aplica_comision(999.99) == False


def test_monto_1000_aplica_comision():
    assert aplica_comision(1000.00) == True

La precisión debe tener sentido para el negocio. En dinero, dos decimales suelen ser importantes.

17.15 Valores límite con fechas

Las fechas también tienen límites. Por ejemplo, un cupón puede ser válido hasta el 31 de diciembre de 2026 inclusive.

from datetime import date


def cupon_vigente(fecha_actual):
    return fecha_actual <= date(2026, 12, 31)


def test_cupon_vigente_en_fecha_limite():
    assert cupon_vigente(date(2026, 12, 31)) == True


def test_cupon_no_vigente_despues_de_fecha_limite():
    assert cupon_vigente(date(2027, 1, 1)) == False

La fecha exacta de vencimiento y el día siguiente son valores de alto interés.

17.16 Nombrar pruebas de límite

En pruebas de valores límite, conviene que el nombre incluya el valor o la condición exacta.

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

El nombre muestra que 18 no es un valor cualquiera: es el límite de la regla. Esto ayuda a entender la intención sin leer todo el cuerpo de la prueba.

17.17 Tabla de ejemplos

Regla Valores límite útiles Qué detectan
Edad mínima 18 17, 18, 19 Inclusión correcta del mínimo.
Envío gratis desde 5000 4999, 5000, 5001 Uso correcto de >=.
Máximo 10 ítems 9, 10, 11 Respeto del máximo permitido.
Nota entre 1 y 10 0, 1, 10, 11 Mínimo y máximo del rango.
Cupón válido hasta una fecha Fecha límite y día siguiente Vencimiento inclusivo o exclusivo.

17.18 Errores comunes

  • Probar solo valores alejados del límite.
  • No probar el valor exacto del límite.
  • No distinguir entre límite inclusivo y exclusivo.
  • Usar valores "cercanos" que no tienen sentido para la precisión del dominio.
  • Olvidar límites superiores cuando se prueban rangos.
  • Agregar demasiados casos sin relación con un límite real.

17.19 Lista de comprobación

Al aplicar valores límite, revisa:

  • ¿Cuál es el límite exacto de la regla?
  • ¿El límite es inclusivo o exclusivo?
  • ¿Probaste el valor exacto del límite?
  • ¿Probaste un valor justo antes y uno justo después si aporta valor?
  • ¿La unidad tiene mínimo y máximo?
  • ¿La precisión del dato está bien elegida?
  • ¿El nombre de la prueba deja claro el límite probado?

17.20 Qué debes recordar de este tema

  • Los valores límite están alrededor del punto donde una regla cambia.
  • Muchos errores aparecen por confundir operadores como > y >=.
  • Conviene probar justo antes, en y después del límite cuando el riesgo lo justifica.
  • Los rangos pueden tener límite inferior y superior.
  • Fechas, decimales, longitudes y cantidades también tienen límites.
  • Los valores límite complementan las clases de equivalencia.
  • El valor exacto del límite suele ser el caso más importante.

17.21 Conclusión

El análisis de valores límite es una técnica muy efectiva para pruebas unitarias. Permite encontrar errores pequeños pero importantes en comparaciones, rangos y condiciones.

Probar los bordes exactos ayuda a documentar si una regla incluye o excluye ciertos valores. Esto reduce ambigüedad y protege comportamientos críticos.

En el próximo tema veremos datos de prueba simples, claros y mantenibles, porque elegir buenos valores también implica presentarlos de manera legible.