Критерием, который решает эти и некоторые другие проблемы, является комбинаторное покрытие условий. Он требует создания такого числа тестов, чтобы все возможные комбинации результатов условия в каждом решении и во всех точках входа выполнялись, по крайней мере, один раз. Например, в приведенной ниже последовательности операторов существуют четыре ситуации, которые должны быть протестированы:
NOTFOUND = ’1’ В;
/* поиск в таблице */
DO I=1 ТО TABSIZE WHILE (NOTFOUND);
/* последовательность операторов, реализующая
процедуру поиска */
END;
1. I£TABSIZE и NOTFOUND есть «истина».
2. I£TABSIZE и NOTFOUND есть «ложь» (обнаружение необходимого искомого значения до достижения конца таблицы).
3. I>TABSIZE и NOTFOUND есть «истина» (достижение конца таблицы без обнаружения искомого значения).
4. I>TABSIZE и NOTFOUND есть «ложь» (искомое значение является последней записью в таблице).
Легко видеть, что набор тестов, удовлетворяющий критерию комбинаторного покрытия условий, удовлетворяет также и критериям покрытия решений, покрытия условий и покрытия решений/условий.
По этому критерию в программе на рис. 6.5 должны быть покрыты тестами следующие восемь комбинаций:
1. A > 1, B = 0
2. A > 1, B ≠ 0
3. A ≤ 1, B = 0
4. A ≤ 1, B ≠ 0
5. А = 2, Х > 1
6. A = 2, X ≤ 1
7. A ≠ 2, Х > 1
8. A ≠ 2, X ≤ 1
Заметим, что комбинации 5–8 представляют собой значения второго оператора IF. Поскольку Х может быть изменено до выполнения этого оператора, значения, необходимые для его проверки, следует восстановить исходя из логики программы с тем, чтобы найти соответствующие входные значения.
Для того чтобы протестировать эти комбинации, необязательно использовать все восемь тестов. Фактически они могут быть покрыты четырьмя тестами. Приведем входные значения тестов и комбинации, которые они покрывают:
A=2, B=0, Х=4 — покрывает 1, 5;
А=2, B=1, Х=1 — покрывает 2, 6;
А=1, B=0, Х=2 — покрывает 3, 7;
A=1, B=1, X=1 — покрывает 4, 8.
То, что четырем тестам соответствуют четыре различных пути на рис. 6.5, является случайным совпадением. На самом деле, представленные выше тесты не покрывают всех путей, они пропускают путь acd. Например, требуется восемь тестов для тестирования следующей программы:
IF ((X=Y) & (LENGTH(Z)=0) & EPS) THEN J=1;
ELSE I=1;
хотя она покрывается лишь двумя путями. В случае циклов число тестов для удовлетворения критерию комбинаторного покрытия условий обычно больше, чем число путей.
Таким образом, для программ, содержащих только одно условие на каждое решение, минимальным является критерий, набор тестов которого
1) вызывает выполнение всех результатов каждого решения, по крайней мере, один раз и
2) передает управление каждой точке входа (например, точке входа, ON-единице), по крайней мере, один раз (чтобы обеспечить выполнение каждого оператора программы, по крайней мере, один раз).
Для программ, содержащих решения, каждое из которых имеет более одного условия, минимальный критерий состоит из набора тестов, вызывающих выполнение всех возможных комбинаций результатов условий в каждом решении и передающих управление каждой точке входа программы, по крайней мере, один раз.