# Caja negra (sistemas)

La prueba de caja negra, test funcional o prueba comportamental, es un tipo de prueba de software directa, cuya finalidad es analizar la compatibilidad entre las interfaces de cada uno de los componentes del software. No tiene en consideración la lógica interna del sistema. Permite la revisión final de las especificaciones y codificación de un programa. La prueba es considerada aceptable cuando su ejecución conlleva una probabilidad elevada de encontrar un error y es satisfactoria cuando lo detecta.
El propósito es reducir el número de casos de prueba, pero manteniendo la efectividad de ésta, es decir, conseguir localizar el mayor número de errores posible. Esto se consigue mediante la exhaustiva elección de las condiciones de entrada y salida válidas y no válidas, que cubren todas las funcionalidades del sistema.
Este tipo de prueba detecta las siguientes tipologías de errores: funciones incorrectas o ausentes, errores de inicialización y terminación, de rendimiento, errores en estructuras de datos o accesos a bases de datos y en la interfaz.
Existen tres técnicas principales: particiones de equivalencia, análisis de valores límites y conjetura de errores. La prueba de caja negra supone un compendio de todos estos métodos.

## Particiones de equivalencia

Se consideran clases de equivalencia a partir de las condiciones de entrada descritas en las especificaciones del sistema. Se considera como clase de equivalencia al conjunto de datos de entrada que se encarga de definir los estados válidos y no válidos del sistema, considerando como clase válida aquella que genera el valor esperado.
Las condiciones de entrada pueden ser estructuras de datos de diversos tipos, tanto un valor específico, como un intervalo, un conjunto de valores o una condición lógica.
El proceso a seguir consta de los siguientes pasos:
* Identificar las clases de equivalencia: por cada condición de entrada se deben identificar clases de equivalencias válidas y no válidas. En función del tipo de entrada, existen una serie de criterios para generar las clases de equivalencia.
| Condición entrada | Clases válidas | Clases no válidas |
| Intervalo | 1 intervalo comprendido en el intervalo inicial | 2 intervalos fuera de rango, uno por debajo y otro por encima |
| Valor específico | 1 clase que posea ese valor | 2 clases, un valor por debajo y otro por encima |
| Conjunto de datos | 1 clase por cada elemento del conjunto | 1 clase de un elemento que no pertenezca al conjunto |
| Condición lógica | 1 clase que cumpla la condición | 1 clase que no cumpla la condición |
* Definir los casos de prueba: los casos de prueba se deben añadir de forma que cubran el mayor número de clases de equivalencia válidas. Por cada clase de equivalencia no válida se debe generar un caso de prueba. Es imprescindible que cada clase esté cubierta en, al menos, un caso de prueba.
Para esclarecer, las particiones de equivalencia aplicadas a un caso de test concreto se visualizan de la forma siguiente: Dada una interfaz sujeta a los vínculos
* x es un entero comprendido entre 5 y 10
* V[ ] es un array de n enteros, n comprendido entre 1 y 5
* C es un conjunto que puede tomar los valores {Rojo, Verde}
Las clases de equivalencia entonces engloban
| Elemento | Clases equivalencia válidas | Clases equivalencia no válidas |
| x | [5,10] | (-$\infty$,4] [11, $\infty$) |
| V[ ] | array que cumpla longitud(V) = n | array tal que longitud(V) != n |
| n | [1,5] | (-$\infty$,0] [6, $\infty$) |
| C | {Rojo} {Verde} | conjunto al que no pertenezca ninguno de los anteriores valores |
Y de esta forma los casos de test se corresponden con
| x | n | V[ ] | C | Validez |
| 7 | 2 | V[1,2] | Rojo | Válido |
| 7 | 2 | V[1,2] | Verde | Válido |
| 1 | 2 | V[1,2] | Rojo | No válido |
| 15 | 2 | V[1,2] | Rojo | No válido |
| 7 | 2 | V[1,2,3] | Rojo | No válido |
| 7 | 0 | V[ ] | Rojo | No válido |
| 7 | 7 | V[1,1,2,1,3,2,1] | Rojo | No válido |
| 7 | 2 | V[1,2] | Amarillo | No válido |

## Análisis de valores límite

Esta técnica se basa en la evaluación de las condiciones límites, es decir, los valores inmediatamente por encima y por debajo de los márgenes de las clases de equivalencia. La base de este argumento se fundamenta en la evidencia experimental de que la probabilidad de aparición de los errores es mayor en los extremos de los campos de entrada.
Las clases de equivalencia siguen el mismo esquema que el proceso anterior. Mientras que los casos de prueba de este método se generan de forma que cubran todas las condiciones límites de las clases de equivalencia.
| Condición de entrada | Casos de prueba válidos | Casos de prueba no válidos |
| Intervalo | 2 casos, uno con el valor máximo y otro con el valor mínimo | 2 casos, uno que ejecuta el valor justo por encima del máximo, y otro justo por encima del mínimo |
| Valor numérico | 1 caso que ejecute el valor concreto | 2 casos, uno justo por encima del valor y otro justo por debajo |
| Estructura de datos | 2 casos que ejecuten el primer y último elemento de la estructura | |
Siguiendo esta evaluación, los casos de prueba del ejemplo anterior se corresponderían con
| x | n | V[ ] | C | Validez |
| 5 | 1 | V[1] | Rojo | Válido |
| 10 | 5 | V[1,3,2,3,2] | Verde | Válido |
| 4 | 1 | V[1] | Rojo | No válido |
| 11 | 1 | V[1] | Rojo | No válido |
| 5 | 0 | V[ ] | Rojo | No válido |
| 5 | 6 | V[1,2,3,1,2,1] | Rojo | No válido |

## Conjetura de errores

Consiste en la elaboración de un listado de errores que no contemplan los métodos anteriores, y que generan a su vez nuevos casos de prueba.
Este caso contempla casos como intentar iniciar sesión con un correo electrónico no registrado, rellenar un formulario o registrar un usuario sin haber completado todos los campos obligatorios, entre otros.