Saltar al contenido

Pruebas de software

Caja blanca y caja negra, los cuatro niveles de prueba, las estrategias de integración, las pruebas de regresión, alfa y beta, las no funcionales y las herramientas más citadas.

Caja blanca y caja negra

La primera clasificación de las pruebas atiende a cuánto se conoce del interior de lo que se prueba. En la prueba de caja blanca se conoce el código y el detalle del algoritmo, e interesa lo que ocurre dentro: qué caminos recorre la ejecución y si todos ellos se han ejercitado. En la prueba de caja negra el interior no se mira: solo se comprueba que, para unas entradas dadas, salgan las salidas esperadas por la interfaz.

AspectoCaja blancaCaja negra
Qué se conoceEl código y la estructura internaSolo la especificación: entradas y salidas
Qué se buscaQue se recorran todos los caminos, ramas y condicionesQue el comportamiento observable sea el esperado
Quién suele hacerlasEl propio desarrolladorUn probador o el usuario, sin ver el código
También llamadaEstructural o de cristalFuncional o de comportamiento

Las técnicas típicas de caja blanca son la prueba de flujo de control, que sigue el orden en que se ejecutan las sentencias; la prueba de bifurcación o de decisión, que exige que cada condición se evalúe al menos una vez a verdadero y una vez a falso; y la prueba del camino básico, que calcula el número mínimo de caminos independientes que hay que recorrer para cubrir el grafo del programa.

  • Cobertura de sentencias: que cada línea se ejecute al menos una vez. Es la más débil.
  • Cobertura de decisiones o de ramas: que cada bifurcación se tome por sus dos salidas.
  • Cobertura de condiciones: que cada condición simple dentro de una decisión compuesta se pruebe a verdadero y a falso.
  • Camino básico: el número de caminos independientes coincide con la complejidad ciclomática de McCabe, que se calcula como el número de decisiones más uno.
  • Clases de equivalencia (caja negra): se agrupan las entradas en conjuntos que el programa debería tratar igual y se prueba un representante de cada uno.
  • Análisis de valores límite (caja negra): se prueban los extremos de cada clase, porque es donde se concentran los errores de comparación.

Caja blanca y caja negra no son excluyentes ni rivales: se complementan. La caja blanca puede recorrer todos los caminos de un algoritmo equivocado, y la caja negra puede dar por bueno un programa con código muerto que nunca se ejecutó.

Para el examen

  • Caja blanca: mira el código y sus caminos

  • Caja negra: solo entradas y salidas

  • Relación: no son rivales: se complementan

Los niveles de prueba

La segunda clasificación atiende a qué tamaño de pieza se prueba y en qué momento. Se recorre de dentro hacia fuera: primero cada componente por separado, luego las piezas conectadas entre sí, luego el sistema completo y por último el sistema en manos de quien lo va a usar.

NivelQué se pruebaQuién lo hace
UnitariasCada componente de forma individual y aislada del restoEl desarrollador, normalmente automatizadas
IntegraciónEl ensamblaje entre componentes: que se entienden entre ellosEl equipo de desarrollo
SistemaEl sistema completo y las interfaces entre subsistemas, en un entorno parecido al realUn equipo de pruebas independiente
AceptaciónQue el sistema hace lo que el usuario espera, desde su punto de vista funcionalEl usuario o el cliente, que firma la aceptación

Los cuatro niveles, en orden, son unitarias, integración, sistema y aceptación. La distinción que más falla: las unitarias aíslan una pieza y las de integración comprueban precisamente lo que ocurre entre dos piezas.

Métrica 3 añade a esta escalera un nivel más, las pruebas de implantación, que se hacen ya sobre el sistema integrado de hardware y software en su entorno real de operación, comprobando que funciona con la infraestructura, los datos y las comunicaciones de verdad. Van entre las de sistema y las de aceptación.

Para el examen

  • Los cuatro, en orden: unitarias, integración, sistema y aceptación

  • Unitarias: aíslan una pieza

  • Integración: comprueban lo que ocurre entre dos

Estrategias de integración

Cuando llega el momento de juntar los componentes hay que decidir en qué orden se ensamblan. La primera decisión es si se hace poco a poco o todo de golpe.

EstrategiaEn qué consisteQué hace falta
Incremental descendente (top-down)Se empieza por los módulos de más alto nivel y se van añadiendo los de abajoMódulos falsos que simulen a los inferiores todavía no escritos (stubs)
Incremental ascendente (bottom-up)Se empieza por los módulos de más bajo nivel y se subeProgramas conductores que llamen a los módulos ya listos (drivers)
Incremental combinada o sándwichSe atacan a la vez los extremos y se juntan por el medioStubs y drivers, pero menos de cada uno
No incremental (big-bang)Se prueba cada módulo por separado y después se conecta todo de una vezNada auxiliar, pero localizar un fallo se vuelve muy difícil

La ventaja de la integración incremental es que, si algo falla al añadir un módulo, el culpable es casi siempre ese módulo. En big-bang todo aparece a la vez y el fallo puede estar en cualquier parte.

Para el examen

  • Integración incremental: si algo falla al añadir un módulo, el culpable es casi siempre ese módulo

  • Big-bang: todo aparece a la vez y el fallo puede estar en cualquier parte

Pruebas de regresión, alfa y beta

Las pruebas de regresión comprueban que un cambio no ha roto nada de lo que ya funcionaba. Consisten en volver a pasar las pruebas que antes pasaban, sobre partes que ni siquiera se han tocado, porque un cambio en un módulo puede alterar el comportamiento de otro que dependa de él.

No son un nivel más, sino una prueba que se hace en todos los niveles cada vez que hay una modificación: correctiva, evolutiva o incluso una refactorización que en teoría no cambia nada. Por eso son la primera candidata a automatizarse: hacerlas a mano después de cada cambio no es sostenible, y ese es justamente el motivo por el que existe la integración continua.

Regresión no significa probar lo nuevo, sino volver a probar lo viejo. Confundirla con las pruebas de la funcionalidad recién añadida es el fallo más repetido.

PruebaDónde se haceCon quién
AlfaEn un entorno controlado, en las instalaciones del desarrolladorUn usuario prueba y el desarrollador observa y toma nota
BetaEn el entorno de trabajo real del usuarioEl usuario solo, sin observadores; los fallos los reporta él

Para el examen

  • Regresión: volver a probar lo VIEJO, no lo nuevo

  • Para qué: comprobar que sigue funcionando

  • Alfa y beta: en casa del fabricante y con usuarios reales

Pruebas no funcionales

Las pruebas funcionales comprueban qué hace el sistema. Las no funcionales comprueban cómo lo hace: con qué rapidez, en qué condiciones, con qué seguridad y con qué comodidad para el usuario. Un sistema puede pasar todas las funcionales y ser inservible porque tarda treinta segundos en responder.

  • Rendimiento: tiempos de respuesta y consumo de recursos con una carga determinada. De ahí salen las de carga, que llevan el sistema al volumen previsto, y las de estrés, que lo pasan a propósito para ver cómo se degrada.
  • Seguridad: si el sistema resiste intentos de acceso indebido o de manipulación de datos.
  • Usabilidad: si una persona real consigue hacer su tarea sin ayuda ni frustración.
  • Compatibilidad: si funciona en los navegadores, sistemas operativos, dispositivos y versiones previstos.
  • Otras habituales: disponibilidad, escalabilidad, portabilidad y mantenibilidad.

Hay además un corte transversal a todo lo anterior: las pruebas estáticas examinan el producto sin ejecutarlo, mediante revisiones, inspecciones de código y análisis automático de fuentes; las dinámicas requieren poner el programa a funcionar. Y una prueba muy usada en la práctica es la de humo, un conjunto rápido y superficial que se lanza sobre cada nueva versión para decidir si merece la pena probarla a fondo o si está tan rota que se devuelve.

Para el examen

  • Funcionales: comprueban QUÉ hace el sistema

  • No funcionales: comprueban CÓMO: rendimiento, carga, seguridad y usabilidad

  • Estáticas frente a dinámicas: no ejecutan el programa frente a sí ejecutarlo

  • Prueba de humo: decide si la versión merece probarse a fondo

Herramientas de prueba

Cada tipo de prueba tiene su familia de herramientas, y en examen se pregunta emparejando la herramienta con lo que prueba. Conviene fijarse en que las de análisis estático no ejecutan nada: leen el código fuente.

Para quéHerramientas habituales
Pruebas unitariasJUnit en Java, NUnit en .NET y TestNG
Simular dependencias en pruebas unitariasMockito, que sustituye por objetos falsos lo que el componente necesita
Pruebas funcionales, simulando lo que hace el usuarioSelenium, SoapUI, Watir y WatiN
Pruebas de carga y rendimientoJMeter, LoadRunner y LoadUI
Análisis de código estáticoSonarQube, PMD, Checkstyle y FindBugs

Un objeto simulado (mock) permite probar un componente sin arrastrar todo lo que hay debajo. Es lo que hace que una prueba unitaria sea de verdad unitaria y no una prueba de integración disfrazada.

Para el examen

  • Objeto simulado (mock): permite probar un componente sin arrastrar lo que hay debajo

  • Por qué importa: es lo que hace que una prueba unitaria sea de verdad unitaria