¦---+------------------+-------------------+--------------------¦
¦ 1 ¦ I = 0 ¦ OptionStr(0) = 0 ¦ OptionStr(0) = 0 ¦
¦ ¦ ¦ ¦ ¦
¦---+------------------+-------------------+--------------------¦
¦ 2 ¦ I = 1 ¦ OptionStr(0) = 0 ¦ OptionStr(0) = 0 ¦
¦ ¦ (ParStr[i] in ¦ ¦ ¦
¦ ¦ OptDelim) = true¦ ¦ ¦
¦---+------------------+-------------------+--------------------¦
¦ 3 ¦ I = 1 ¦ OptionStr(0) = 8 ¦ OptionStr(0) = 8 ¦
¦ ¦ (ParStr[i] in ¦ ¦ ¦
¦ ¦ OptDelim)=false ¦ ¦ ¦
¦---+------------------+-------------------+--------------------¦
¦ 4 ¦ I = 11 ¦ OptionStr(0) = 0 ¦ OptionStr(0) = 0 ¦
¦ ¦ (ParStr[i] in ¦ ¦ ¦
¦ ¦ OptDelim) = true¦ ¦ ¦
¦---+------------------+-------------------+--------------------¦
¦ 5 ¦ I = 11 ¦ OptionStr(0) = 0 ¦ OptionStr(0) = 0 ¦
¦ ¦ (ParStr[i] in ¦ ¦ ¦
¦ ¦ OptDelim)=false ¦ ¦ ¦
L===¦==================¦===================¦====================-
Хотя применение критерия покрытия условий на первый
взгляд удовлетворяет критерию покрытия решений, это не всегда
так. Если тестируется решение
if A and B then ...
то при критерии покрытия условий требовались бы два теста:
A = true, B = false и A = false, B = true. Но в этом случае
не выполнялось бы then-предложение оператора if.
Существует еще один критерий, названный покрытием реше-
ний/условий. Он требует такого достаточного набора тестов,
чтобы все возможные результаты каждого условия в решении вы-
полнялись по крайней мере один раз, все результаты каждого ре-
шения выполнялись по крайней мере один раз и каждой точке вхо-
да передавалось управление по крайней мере один раз.
Недостатком критерия покрытия решений/условий является не-
возможность его применения для выполнения всех результатов
всех условий; часто подобное выполнение имеет место в следст-
вии того, что определенные условия скрыты другими условиями.
Например, если условие AND есть ложь, то никакое из последую-
щих условий в выражении не будет выполнено. Аналогично, если
условие OR есть истина, то никакое из последующих условий не
будет выполнено. Следовательно, критерии покрытия условий и
покрытия решений/условий недостаточно чувствительны к ошибкам
в логических выражениях.
Критерием, который решает эти и некоторые другие пробле-
мы, является комбинаторное покрытие условий. Он требует созда-
ния такого числа тестов, чтобы все возможные комбинации резу-
льтатов условия в каждом решении и все точки входа выполня-
лись по крайней мере один раз.
Рассмотрим правило CheckTreeNil в модуле TmObejct объекта
Main.
procedure Main.CheckTreeNil;
var
tn : boolean;
begin
tn := (GetPtrOfClass(SCl)=nil) and
(GetPtrOfClass(UCl)=nil) and
(GetPtrOfClass(ACl)=nil);
if tn then Error('не найден ни один нетерминал');
end;
Алгоритм процедуры:
--------------------¬
¦ Начало ¦
L---------T----------
¦
/\
/ \
/ \
/ G(SCl)=nil \
/ и \ нет
/ G(UCl)=nil \-----------¬
\ и / ¦
\ G(ACl)=nil / ¦
\ / ¦
\ / ¦
\ / да ¦
¦ ¦
--------------------+------------------¬ ¦
¦ Error('не найден ни один нетерминал')¦ ¦
L-------------------T------------------- ¦
+<----------------------
----------+---------¬
¦ Конец ¦
L--------------------
Рис 2.3.
Для того, чтобы протестировать эту процедуру необходимо
восемь тестов, хотя она покрывается всего двумя путями.
Табл. 2.3.
г===T===========================T============T============¬
¦ N ¦ Входные данные ¦ Ожидаемый ¦ Полученный ¦
¦ ¦ ¦ результат ¦ результат ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) = nil ¦ ¦ ¦
¦ 1 ¦ GetPtrOfClass(UCl) = nil ¦ tn = true ¦ tn = true ¦
¦ ¦ GetPtrOfClass(ACl) = nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) <> nil ¦ ¦ ¦
¦ 2 ¦ GetPtrOfClass(UCl) = nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) = nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) = nil ¦ ¦ ¦
¦ 3 ¦ GetPtrOfClass(UCl) <> nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) = nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) <> nil ¦ ¦ ¦
¦ 4 ¦ GetPtrOfClass(UCl) <> nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) = nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) = nil ¦ ¦ ¦
¦ 5 ¦ GetPtrOfClass(UCl) = nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) <> nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) <> nil ¦ ¦ ¦
¦ 6 ¦ GetPtrOfClass(UCl) = nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) <> nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) = nil ¦ ¦ ¦
¦ 7 ¦ GetPtrOfClass(UCl) <> nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) <> nil ¦ ¦ ¦
¦---+---------------------------+------------+------------¦
¦ ¦ GetPtrOfClass(SCl) <> nil ¦ ¦ ¦
¦ 8 ¦ GetPtrOfClass(UCl) <> nil ¦ tn = false ¦ tn = false ¦
¦ ¦ GetPtrOfClass(ACl) <> nil ¦ ¦ ¦
L===¦===========================¦============¦============-
В случае циклов число тестов для удовлетворения критерию
комбинаторного покрытия условий обычно больше, чем число пу-
тей.
Легко видеть, что набор тестов, удовлетворяющий критерию
комбинаторного покрытия условий, удовлетворяет также и крите-
риям покрытия решений, покрытия условий и покрытия решений/ус-
ловий.
Таким образом, для программ, содержащих только одно усло-
вие на каждое решение, минимальным является критерий, набор
тестов которого:
- вызывает выполнение всех результатов каждого решения по
крайней мере один раз;
- передает управление каждой точке входа (например, опера-
тор CASE).
Для программ, содержащих решения, каждое из которых имеет
более одного условия, минимальный критерий состоит из набора
тестов, вызывающих всех возможных комбинаций результатов усло-
вий в каждом решении и передающих управление каждой точке вхо-
да программы по крайней мере один раз.
В свете всего вышеизложенного, можно изобразить алгоритм
выбора минимального критерия, по которому необходимо тестиро-
вать программу (см. рис. 2.4.).
--------------------¬
¦ Начало ¦
L---------T----------
--------------------------------->+
¦ ----------+---------¬
¦ ¦ Выбрать оператор ¦
¦ ¦ условного перехода¦
¦ L---------T----------
¦ /\
¦ / \
¦ / \ нет
¦ /Это оператор\ ---------¬
¦ \ IF / ¦
¦ \ / ¦
¦ \ / ¦
¦ \/да ¦
¦ ¦ ¦
¦ /\ ¦
¦ / \ ¦
¦ да /Условие \ нет ¦
¦ ----------/ содержит \--------->+
¦ ¦ \более одного/ ¦
¦ ¦ \ комп-та/ ¦
¦ ¦ \ / ¦
¦ ¦ \/ ¦
¦ ----------------+---------------¬ ----------------+-------------¬
¦ ¦ Набор тестов, вызывающий все ¦ ¦ Набор тестов, вызывающий ¦
¦ ¦ возможные комбинации резуль-в ¦ ¦ выполнение всех результатов ¦
¦ ¦ условий в каждом решении не ¦ ¦ каждого решения не менее ¦
¦ ¦ менее одного раза. ¦ ¦ одного раза. ¦
¦ L---------------T---------------- L---------------T--------------
¦ L--------------->T<----------------
¦ /\
¦ /Это \
¦ нет /последн.\
L---------------------------/ оператор \
\ условного /
\перехода/
\ /
\/да
----------+---------¬
¦ Конец ¦
L--------------------
Рис 2.4.