Los predicados de diseño son un método inventado por Thomas McCabe [1] para cuantificar la complejidad de la integración de dos unidades de software. Cada uno de los cuatro tipos de predicados de diseño tiene una calificación de complejidad de integración asociada. Para las partes de código que aplican más de un predicado de diseño, las calificaciones de complejidad de integración se pueden combinar.
La suma de la complejidad de integración de una unidad de código, más uno, es el número máximo de casos de prueba necesarios para ejecutar la integración por completo. Aunque un ingeniero de pruebas normalmente puede reducir esto cubriendo tantos predicados de diseño previamente descubiertos como sea posible con cada nueva prueba. Además, algunas combinaciones de predicados de diseño pueden ser lógicamente imposibles.
La unidad A siempre llama a la unidad B. Esto tiene una complejidad de integración de 0. Por ejemplo:
unidadA::funcionA() { unidadB->funcionB();}
La unidad A puede o no llamar a la unidad B. Esta integración tiene una complejidad de 1 y necesita dos pruebas: una que llama a B y otra que no.
unidadA::funcionA() { Si (condición) unidadB->funcionB();}
Esto es como la sentencia switch de un lenguaje de programación . La unidad A llama exactamente a una de varias unidades posibles. La complejidad de integración es n - 1, donde n es la cantidad de unidades posibles a las que se puede llamar.
unidadA::funcionA() { cambiar (condición) { Caso 1: unidadB->funcionB(); romper; caso 2: unidadC->funcionC(); romper; ... por defecto: unidadN->funcionN(); romper; }}
En una llamada iterativa, la unidad A llama a la unidad B al menos una vez, pero quizás más. Esta integración tiene una complejidad de 1. También requiere dos pruebas: una que llama a la unidad B una vez y otra que la llama más de una vez.
unidadA::funcionA() { hacer { unidadB->funcionB(); } mientras (condición);}
Cualquier integración particular puede combinar varios tipos de llamadas. Por ejemplo, la unidad A puede o no llamar a la unidad B; y si lo hace, puede llamarla una o más veces. Esta integración combina una llamada condicional, con su complejidad de integración de 1, y una llamada iterativa, con su complejidad de integración de 1. La complejidad de integración combinada totaliza 2.
unidadA::funcionA() { si (algunNumero > 0) { para ( i = 0 ; i < algúnNúmero ; i++ ) { unidadB->funcionB(); } }}
Dado que la cantidad de pruebas necesarias es la complejidad total de la integración más uno, esta integración requeriría 3 pruebas. En una, donde someNumber no es mayor que 0, no se llama a la unidad B. En otra, donde someNumber es 1, se llama a la unidad B una vez. Y en la última, donde someNumber es mayor que 1, se llama a la unidad B más de una vez.