Particiones de equivalencia: Pruebas de caja negra

La división en particiones de equivalencia, también llamadas clases de equivalencia, es una técnica de pruebas de caja negra en la que las entradas del programa se clasifican en clases. Considera como perteneciente al dominio de entrada a todas las entradas que puedan tener efecto en la salida de la prueba, positivo o negativo.

Todos los miembros de cada clase de equivalencia comparten ciertas características en común que no son compartidas con miembros de otras clases.

Particiones de equivalencia
Particiones de equivalencia

Cada clase se llama partición de equivalencia porque todos elementos en la clase prueban la misma cosa. Si uno de los elementos de una clase provoca un error, todos los de esa clase probablemente lo harán. La idea principal de esta técnica es identificar los casos de prueba usando un elemento de cada clase de equivalencia.

Identificar particiones de equivalencia

Para identificar las particiones de equivalencia es necesario examinar cada condición de entrada, que si has sido prudente estarán en las especificaciones de requerimientos del programa o aplicación. Ten en cuenta que existen dos clases de equivalencia:

  • Clases válidas: valores de entrada válidos. No quiere decir que tu programa no vaya a fallar con estas entradas, sino que no debería fallar.
  • Clases no válidas: valores de entrada no válidos. Representan los valores de entrada que son erróneos y a los que el programa debería responder o bien rechazándolos o manejando una excepción.

Establecer las particiones de equivalencia puede ser un proceso subjetivo, por lo que dos personas podrían obtener clases de equivalencia distintas. La clave está en elegir las relaciones que determinan esas clases.

Definir particiones de equivalencia

Las clases de equivalencia se definen según una serie de directrices:

  • Rangos: si una entrada está condicionada a un rango de valores (por ejemplo, edades comprendidas entre 18 y 65 años ambos inclusive), se define una clase de equivalencia válida para todos los valores pertenecientes al rango y dos no válidas, una para los valores menores al límite inferior del rango y otra para los mayores al límite superior.
  • Valor específico: análoga a la anterior, solo que el rango quedaría restringido a un único valor (la edad es de 18 años). Se siguen creando igualmente 1 clase de equivalencia válida y dos no válidas.
  • Número de valores: también como las anteriores, pero teniendo en cuenta el número de valores introducidos (1 a 5 pasajeros sería la clase válida, 0 pasajeros y más de 5 pasajeros las no válidas).
  • Perteneciente a un conjunto: cuando un valor es válido si pertenece a un conjunto (días de la semana en minúscula: «lunes», «martes»…) se define una clase de equivalencia válida para cada uno de los valores del conjunto, además de una no válida, para aquellos valores que no pertenecen a él.
  • Valor lógico: se corresponde a la evaluación de una condición (por ejemplo, la edad debe ser mayor o igual a 18). Se establece una clase de equivalencia válida (se cumple la condición) y otra no válida (no se cumple).

Ejemplo 1: Días de la semana en formato numérico

La condición de entrada reflejaría que sólo se podrían introducir números del 1 al 7, ambos inclusive. Identificaríamos 2 clases:

  • Clase válida: 1 <= día <= 7
  • 2 clases no válidas: una cuando día < 1 y otra para día > 7

Ejemplo 2: Colores RGB en formato String minúscula

El valor de entrada sólo puede corresponder a uno de los colores RGB escrito en minúscula: «red», «green», «blue». Se supone que cada una de esas entradas se debería manejar de formas distintas en el programa.

  • 3 clases de equivalencia válidas, una para cada uno de los valores de entrada «red», «green» y «blue».
  • Una clase inválida que incluiría aquellos colores no especificados en la condición.

Ejemplo 3: Nombre con primera letra con mayúscula

  • Clase válida para cadenas cuya primera letra es una mayúscula (se cumple la condición)
  • Clase no válida para valores que no cumplen la condición: cadenas que comienzan en minúscula.

Pruebas mediante particiones de equivalencia

Definidas las clases hay que definir casos de prueba que cubran todas las particiones establecidas. Sin embargo no podemos combinar clases inválidas en casos de prueba individuales, es decir, hay que probarlas partición a partición. Esto es debido a que una condición inválida para una partición podría acarrear enmascarando otra condición posterior (el programa acaba, se lanza una excepción, etc. y no se alcanza el código que llega a usar la otra partición).

En nuestros ejemplos, no serviría de nada evaluar en el mismo caso de prueba a la vez como entrada el color «yellow» y que el nombre de usuario empiece por minúscula, porque la que fallara antes haría que la otra no se ejecutara.

Es por esto que a veces el generar casos de prueba correctos implica realizar múltiples combinaciones de particiones de equivalencia para las distintas entradas. En esos casos puede resultarte útil seguir los siguientes consejos:

  • Nombra cada clase de equivalencia creada con un identificador único. Puedes, por ejemplo, establecer tu propia nomenclatura, y suponiendo los casos anteriores nombrar las respectivas clases de la siguiente forma: v_dia, nv_dia_menor, nv_dia_mayor, v_color_g, v_color_r, v_color_b, nv_color, v_mayúsculas, nv_mayúsculas.
    Ten en cuenta que cuantas más entradas tengas más te ayudará el crear estos identificadores únicos. Por supuesto, puedes crear tu propio sistema de nomenclatura.
  • Elabora una tabla de clases de equivalencia:
EntradaTipoClases VálidasIDClases no VálidasID
Día de la semanaRango1 <= día <= 7v_diadía < 1nv_dia_menor
día > 1nv_dia_mayor
ColoresConjuntocolor = "red"v_color_rcolor distinto de los válidosnv_color
color = "green"v_color_g
color = "blue"v_color_b
Nombre de usuarioCondición lógicaEmpieza por mayúsculav_mayúsculaNo empieza por mayúsculanv_mayúscula
Ejemplo de definición de particiones de equivalencia
  • A partir de la tabla anterior podemos generar otra tabla usando los IDs de las clases para realizar todas las posibles combinaciones:
Caso de PruebaClases de equivalenciaCondiciones de EntradaResultado esperado
DíaColorNombre
CP1v_dia, v_color_r, v_mayúscula3redUserR1
CP2v_dia, v_color_g, v_mayúscula1greenUSERR2
CP3v_dia, v_color_b, v_mayúscula7blueUseRR3
CP4nv_dia_menor, v_color_r, v_mayúscula0redUserE1
CP5nv_dia_mayor, v_color_r, v_mayúscula8redUserE2
CP6nv_dia_menor, v_color_g, v_mayúscula-1greenUSeRE1
..................
Ejemplo de generación de casos de uso

Cuando elabores la tabla de casos de prueba trata de tener en cuenta lo siguiente:

  • Siempre que puedas, trata de utilizar todos los valores límite de tus clases válidas y si es posible de las inválidas. De esta forma estas matando dos pájaros de un tiro.
  • Cubre mediante los casos de prueba válidos tantas clases de prueba como sea posible. En el caso del ejemplo era obligatorio hacer un mínimo de 3 casos de prueba, debido al conjunto de la entrada ‘color’. Si eliges bien los valores, el número obligatorio puede ser el número máximo de casos de prueba necesarios.
  • Nunca lo olvides: los casos de prueba para clases no válidas únicamente pueden cubrir una de estas a la vez, si no puede que enmascares posibles errores.