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.
Un valor límite es un valor cercano al punto donde cambia el comportamiento de una regla.
Ejemplos:
No elegimos estos valores al azar. Los elegimos porque están alrededor de una decisión.
Una forma práctica de aplicar valores límite es elegir tres valores:
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.
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.
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.
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 |
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.
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.
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.
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.
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.
Las clases de equivalencia y los valores límite se complementan.
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.
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.
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.
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.
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.
| 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. |
Al aplicar valores límite, revisa:
> y >=.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.