即Modified Condition/Decision Coverage,缩写为MC/DC。
其中判定是指决定if或者循环语句是否执行的那个逻辑表达式。
基本思路。逻辑与表达式测试所有条件为真的情况,然后分别测试每个条件为假,其他条件都为真的情况。逻辑或表达式测试所有条件为假的情况,然后分别测试每个条件为真,其他条件为假的情况。
MC/DC效果和多重条件覆盖效力相同,但是用例数显著减少。
有n个条件的逻辑表达式时,多重条件覆盖需要2的n次方个用例,MC/DC覆盖只需要n+1个测试用例。
对于每一个原子条件X,至少在一个测试中,判定结果会随着原子条件X是否为真而改变;同时,至少在一个测试中,判定结果会随着原子条件X是否为假而改变。原子条件X是这种组合中的关键因素,这个时候可以说原子条件X是有效为真或者有效为假。
例1:
(condition1 && condition2) || (condition3 && condition4)
多重条件覆盖需要16个测试用例。
MC/DC分析:
第一层
condition1 && condition2和condition3 && condition4都为假。
只有Condition1 && condition2 为真。
只有Condition3 && condition4为真。
总共3种情况
第二层
condition1 && condition2为真时,只有condition1和condition2都为真这一种情况。不用增加用例。
condition1 && condition2为假时,需要覆盖只有condition1为假和只有condition2为假两种情况。condition1 && condition2作为关键因素为假的情况在第一层中只有一种。所以要增加1个用例。
condition3 && condition4道理相同,需要增加1个用例。
所以总共就只需要5个测试用例。
例2:
(condition1 || condition2) && (condition3 || condition4)
多重条件覆盖需要16个测试用例。
MC/DC分析:
第一层
condition1 || condition2和condition3 || condition4都为真。
只有condition1 || condition2为假。
只有condition3 || condition4为假。
三种情况。
第二层
condition1 || condition2为假时,只有condition1和condition2都为假这一种情况。不用增加用例。
condition1 || condition2为真时,需要分别覆盖只有condition1为真和只有condition2为真两种情况。condition1 || condition2作为关键因素为真的情况,第一层中只有一种,所以要增加一个用例。
condition3 || condition4同理,需要增加1个用例。
所以总共就只需要5个测试用例。
实际中的复杂例子:
Quagga0.9.18 BGP_route.c line 2200 bgp_update_main()中
(afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST
&& (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED
|| (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
|| CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
条件为真时检查下一跳的可达性。
总共有8个原子条件。多重条件覆盖需要256个测试用例。
逻辑表达式分析:
第一层是逻辑与。三个子表达式依次称为part1、part2、part3。
part1的两个子表达式依次称为part11、part12
part3又分为两层。其中第一层逻辑或表达式的四个子表达式依次称为part31、part32、part33、part34。part33下面又有一层逻辑与表达式,两个子表达式依次称为part331、part332。
所以上面的逻辑表达式符号化为:
(part11 || part12) && part2 && (part31 || part32 || (part331 && part332) || part34)
MC/DC分析:
第一层:
part1、part2、part3都为真。
part1、part2、part3依次为假,其它条件为真。
这是4个用例。
第二层:
part1为假时,只有part11、part12都为假这一种情况,不用增加用例。
part1为真时,要测试只有part11为真和只有part12为真两种情况,第一层中part1有效为真只有1个用例,所以需要增加1个用例。
part3为假时,只有part31、part32、part33、part34都为假这一种情况,不用增加测试用例。
part3为真时,要测试part31为真、或者part32为真、或者part33为真、或者part34为真,其它都为假,这四种情况。第一层中part3作为关键因素为为真的情况,只有一种。所以要增加3个用例。
第三层:
part33为真时,只有part331和part332一种情况。不用增加用例。
part33为假时,需要测试只有part331为假和只有part332为假两种情况。第二层的用例中part33作为关键因素为假情况,只有一种。所以需要增加1个用例。
所以至多9个测试用例。
从上面的分析来看,即使是比较复杂的表达式,要满足更改的判定条件覆盖,案例数也是非常有限的。
规律:每多出一个part。外层就需要增加一个测试用例。如果这个part需要拆分。子层需要n+1个用例。因为子层能且只能和part合并一种真的情况和一种假的情况。所以要增加1+(n+1)-2=n个用例。比如多出一个有3个条件组成的part。则需要增加3个用例。
所以不管逻辑表达式如何嵌套,用例总数总是等于条件数+1。
列出上面最后一个例子的真值表
首先列出所有简单逻辑表达式的真值表。然后用内层真值表中的列替换外层的真值表中相应的关键因素,达到合并的效果。注意,非关键因为不能替换。内层未能替换合并的列,扩展外层关键因素。
对于非关键因素的part进行合并。使表更易读。执行用例时尽量使用不同的组合。
表中:灰色表示非关键因素。为了方便读者跟踪变换过程,我尽量保持列的位置不变。
第一步:分别列出所有part分别满足MC/MD时的真值表 | |||||||||||||||
part11 |
|
|
|
|
|
|
|
| F | T | F | T | F | T | T |
part12 |
|
|
|
|
|
|
|
| F | F | T | ||||
part2 |
|
|
|
|
|
|
|
|
|
|
| T | T | F | T |
part31 |
|
|
| F | T | F | F | F |
|
|
| T | T | T | F |
part32 |
|
|
| F | F | T | F | F |
|
|
| ||||
part331 | T | F | T | F | F | F | T | F |
|
|
| ||||
part332 | T | T | F |
|
|
| |||||||||
part34 |
|
|
| F | F | F | F | T |
|
|
| ||||
result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第二步:将part33合并进part3,将part1合并进最外层后 | |||||||||||||||
part11 |
|
|
|
|
|
|
|
|
|
| F | T | F | T | T |
part12 |
|
|
|
|
|
|
|
|
|
| T | F | F | ||
part2 |
|
|
|
|
|
|
|
|
|
| T | T | T | F | T |
part31 |
|
| F | F | T | F | F | F |
|
| T | T | T | T | F |
part32 |
|
| F | F | F | T | F | F |
|
| |||||
part331 |
|
| T | F | F | F | T | F |
|
| |||||
part332 |
|
| F | T | T |
|
| ||||||||
part34 |
|
| F | F | F | F | F | T |
|
| |||||
result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第三步:将part3合并进最外层,得到最终的真值表。 | |||||||||||||||
part11 |
|
|
| T |
|
| T | T |
|
| F | T | F | T | T |
part12 |
|
|
|
|
|
|
| T | F | F | |||||
part2 |
|
|
| T |
|
| T | T |
|
| T | T | T | F | T |
part31 |
|
|
| F |
|
| F | F |
|
| T | F | T | T | F |
part32 |
|
|
| F |
|
| F | F |
|
| F | T | F | ||
part331 |
|
|
| F |
|
| T | F |
|
| F | F | T | ||
part332 |
|
|
| T |
|
| T |
|
| F | |||||
part34 |
|
|
| F |
|
| F | T |
|
| F | F | F | ||
result |
|
|
| F |
|
| T | T |
|
| T | T | F | F | F |
列出真值表后,发现可以合并成8种情况。比上面分析的结果,还少了一种。因为存在一处3重合并(从右边数第四列)。而上面分析时,只考虑了两重合并。