第11章 · 播客 第2集

测试评审方法 · 白盒测试与逻辑覆盖

🎙️ 本集播客第2集:白盒测试为什么又叫结构测试、为什么主要用在单元测试阶段,然后是本章最经典的考点——逻辑覆盖六种标准:语句、判定、条件、判定/条件、条件组合、路径,一个一个从弱到强讲透,包含关系、谁最强谁最弱、条件覆盖和判定覆盖为什么互不包含,全部用判定式一步步演算给你听。 语音由微软 Edge 神经网络语音预生成(女声·晓伊,男声·云希)。点击下方任意对话可直接从该句开始播,当前句朗读时下一句已预先加载,无缝衔接。
🎙️ 第11章播客 第2集
⬇ 下载本集 点击播放
阿明
上一集把单元、集成、系统三个测试阶段过了一遍,白盒黑盒只点了名字。今天钻进白盒?我记得它就是看代码的测试。
小雅
方向对,但表述要精确,选择题就爱抠定义。白盒测试又称结构测试——这个名字就能出道题:问「白盒测试又称什么测试」,选项里混「功能测试」给你,功能测试是黑盒的别名,别选反。它主要用于单元测试阶段,原文在单元测试那节也呼应过一句「单元测试多采用白盒测试技术」,两处互相印证。
阿明
「白盒」这个比喻是说,我能看见盒子里的东西?
小雅
原文的说法是:它的前提是可以把程序看成装在一个透明的白箱子里,测试者完全知道程序的结构和处理算法,按照程序内部逻辑设计测试用例,检测程序中的主要执行通路是否都能按预定要求正常工作。对比着记黑盒:黑盒又称功能测试,主要用于集成测试和确认测试阶段,把软件看作不透明的黑箱子,完全不考虑内部结构和处理算法,只按需求说明书检查功能——这半段下集展开。
阿明
白盒怎么设计测试用例?总不能代码每一行都拿眼睛扫一遍吧。
小雅
靠的不是眼睛,是覆盖率。白盒测试常用的技术是逻辑覆盖,考察用测试数据运行被测程序时,对程序逻辑的覆盖程度。主要的覆盖标准有 6 种,原文顺序是:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合条件覆盖和路径覆盖。两个命名细节:判定/条件覆盖有的书写作「判定-条件覆盖」,是同一个东西;第五种原文叫「组合条件覆盖」,不少教材叫「条件组合覆盖」,是同一种,别当成两种。
阿明
六种名字记住了,可到底谁强谁弱、谁包含谁,我每次都靠死背。
小雅
死背必错,因为这六种里有几对是「互不包含」的,出题人专门在包含关系上挖坑。想真正搞懂,得先分清两个基本单位:判定和条件。判定,就是程序里做决定的地方,比如 if 语句后面那整个括号,它的整体结果只有真和假两种;条件,是组成判定的更小零件,一个判定可以由多个条件用「并且」「或者」连起来。举例说,if 后面写「x 大于 0 并且 y 大于 0」,这一整句是一个判定,里面「x 大于 0」和「y 大于 0」是两个条件。判定看整体真假,条件看每个零件各自的真假——后面所有的强弱之争,全是围绕这两个单位的。
阿明
那第一种语句覆盖,就是让每行代码都跑到?
小雅
原文定义:语句覆盖是指选择足够多的测试用例,使得运行这些测试用例时,被测程序的每个语句至少执行一次。接着原文一句结论原样记住:很显然,语句覆盖是一种很弱的覆盖标准。为什么弱?还拿「x 大于 0 并且 y 大于 0」举例,取 x 等于 1、y 等于 1,判定为真,if 里的语句全部执行,一个用例就语句覆盖达标。可是判定为假的分支呢?条件的真假翻转呢?完全没考察,所以它弱,六种里垫底。
阿明
往上走一级,判定覆盖是把每个判定的真假都跑到?
小雅
对。判定覆盖又称分支覆盖——这个别名常单独出题,「判定覆盖又称分支覆盖」要配对记住。它的含义是,不仅每个语句至少执行一次,而且每个判定的每种可能的结果,也就是分支,都至少执行一次。还是那个例子,我需要两个用例:x 等于 1、y 等于 1 让判定为真,走真分支;x 等于负 1、y 等于 1 让判定为假,走假分支。真分支、假分支都过了,每个语句也都执行了。原文对它的定位是:判定覆盖比语句覆盖强,但对程序逻辑的覆盖程度仍然不高。
阿明
等一下,判定为假的那次,x 是负 1、y 是 1——虽然判定整体翻了真假,但 y 从来没变过假。是不是这个漏洞引出了条件覆盖?
小雅
孺子可教,这正是判定覆盖的盲区:它只看判定的整体结果,不管每个条件的死活。条件覆盖的含义是,不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取得各种可能的结果——x 大于 0 要取到真也取到假,y 大于 0 也要取到真和假。我来设计用例,这个演算你跟着走一遍,它是理解下一考点的基础。
阿明
来,我拿笔记。
小雅
两个用例。用例一:x 等于负 1、y 等于负 1,两个条件都为假;用例二:x 等于 1、y 等于 1。查条件:x 大于 0 有假有真,y 大于 0 有假有真,每个条件都取得了各种可能结果,条件覆盖达标。再算判定整体:用例一两个条件全假,「并且」整体为假;用例二两个条件全真,整体为真——判定恰好也真假各一次。
阿明
这是不是说,条件覆盖达标了,判定覆盖就自动达标?我印象里它们俩关系不一般。
小雅
你这个「自动达标」是全章最毒的坑。原文原话:条件覆盖不一定包含判定覆盖,判定覆盖也不一定包含条件覆盖。双向都不一定!我用判定式给你各造一个反例,这两个反例务必听懂,考的就是这句结论背后的道理。
阿明
先说条件覆盖达到了、判定覆盖却没达到的反例。
小雅
把判定式换成「x 大于 0 或者 y 大于 0」,注意这次是「或者」不是「并且」。取两个用例:用例一 x 等于 1、y 等于负 1,用例二 x 等于负 1、y 等于 1。x 有真有假,y 有真有假,条件覆盖达标。可判定的整体呢?「或者」连接,用例一 x 真,整体真;用例二 y 真,整体还是真——两个用例判定全为真,假分支一次都没走过!条件覆盖达标,判定覆盖没达标。
阿明
条件全翻了面,判定却纹丝不动,全靠「或者」兜底。那反方向呢,判定覆盖达标、条件覆盖没达标?
小雅
回到「并且」判定式,取 x 等于 1、y 等于 1 和 x 等于负 1、y 等于 1。判定整体一次真一次假,判定覆盖达标。可 y 大于 0 两个用例全为真,从来没假过——y 的可能结果没取全,条件覆盖没达标。两个方向的反例都成立,所以原文才下「互不包含」这个结论。练习题里就有一道专门考这个:条件覆盖与判定覆盖的关系,正确答案是「条件覆盖不一定包含判定覆盖,判定覆盖也不一定包含条件覆盖」,说「谁一定包含谁」的干扰项全错。
阿明
那要是我想两边都要呢?判定也翻、条件也翻。
小雅
那就用第四种:判定/条件覆盖。原文定义分两句:同时满足判定覆盖和条件覆盖的逻辑覆盖称为判定/条件覆盖;它的含义是,选取足够的测试用例,使得判定表达式中每个条件的所有可能结果至少出现一次,而且每个判定本身的所有可能结果也至少出现一次,理解成「两条标准取交集」。还拿「并且」判定式:用例一 x 等于 1、y 等于 1,条件全真、判定为真;用例二 x 等于负 1、y 等于负 1,条件全假、判定为假——x 有真有假,y 有真有假,条件覆盖和判定覆盖同时达标,两个用例就够。
阿明
条件组合覆盖,看名字是把条件所有组合都试一遍?
小雅
对。原文定义:条件组合覆盖的含义是,选取足够的测试用例,使得每个判定表达式中条件结果的所有可能组合至少出现一次。两个条件,每个两种结果,组合一共四种:真真、真假、假真、假假。四个用例——x 等于 1 且 y 等于 1 是真真;x 等于 1 且 y 等于负 1 是真假;x 等于负 1 且 y 等于 1 是假真;x 等于负 1 且 y 等于负 1 是假假。四种组合全部出现,达标。顺手验一下它推出什么:x、y 的真假都取全了,条件覆盖满足;判定整体真真为真、其余三种全为假,真假都出现,判定覆盖也满足——判定/条件覆盖自然满足。
小雅
这不是巧合,原文有明文:显然,满足条件组合覆盖的测试用例,也一定满足判定/条件覆盖。因此,条件组合覆盖是上述 5 种覆盖标准中最强的一种。练习题原题问「白盒测试的逻辑覆盖标准中,最强的覆盖标准是」,选项摆着语句覆盖、判定覆盖、条件覆盖、条件组合覆盖,答案条件组合覆盖。注意原文这句话限定「上述 5 种」——语句、判定、条件、判定/条件、条件组合这五种里比高下,路径覆盖不参与这个排名。
阿明
等一下,我有点糊涂。条件组合覆盖已经最强了,那路径覆盖算什么?
小雅
问得好,这正是第五和第六之间最容易缠不清的地方。原文紧跟着补了半句:然而,条件组合覆盖还不能保证程序中所有可能的路径都至少经过一次。为什么?因为组合是按判定式内部穷举的,它管一个判定框里面条件的真假排列,不管程序整体的走向。举例:程序里有两个前后相连的 if 判定,每个判定真假两种走向,整条程序的路径是它们组合出的多条路;条件组合覆盖只保证每个判定内部的组合出现,前后判定怎么衔接、整条路怎么走完,它管不着。所以还需要第六种——路径覆盖。
阿明
路径覆盖就是把程序的每条路都走一遍?
小雅
原文定义:路径覆盖的含义是,选取足够的测试用例,使得程序的每条可能执行到的路径都至少经过一次;如果程序中有环路,则要求每条环路路径至少经过一次——环路这半句要记住,问「有环的程序怎么才算路径覆盖」就答它。原文对它的评价也是两句:路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,因此是一种较强的覆盖标准;但路径覆盖并未考虑判定中的条件结果的组合,并不能代替条件覆盖和条件组合覆盖。这后半句是另一处高频坑:路径覆盖只看每个判定整体真假怎么串成路,至于判定内部条件怎么配对成真——比如「或者」式里 x 真 y 假和 x 真 y 真都让判定为真、走同一条路——它不区分。所以它和条件类覆盖是两个维度,谁也替代不了谁。
阿明
那考试要我把六种强弱排序,标准答案怎么写?
小雅
按原文口径分两层记。第一层,前五种成一条强弱链:语句覆盖最弱,判定覆盖比语句覆盖强,条件覆盖和判定覆盖互不包含,判定/条件覆盖同时包含两者,条件组合覆盖是前五种中最强的,满足它就一定满足判定/条件覆盖。第二层,路径覆盖单独放:它是较强的覆盖标准,但与前五种不在一条包含链上——满足条件组合覆盖不保证路径覆盖,满足路径覆盖也不保证条件覆盖和条件组合覆盖,彼此不能替代。你要是看到选项说「路径覆盖包含条件组合覆盖」或者反过来,都是错的;只有「条件组合覆盖一定满足判定/条件覆盖」这种前五名内部的包含关系才成立。
阿明
听起来条件组合覆盖四个用例就达标,也没多贵,为什么不干脆都按它来?
小雅
因为条件数一多,组合数翻着番涨:两个条件四种组合,三个条件八种,五个条件就三十二种,真实的判定式经常三四个条件起步,用例数量直接爆炸。所以工程上从弱到强按成本取舍,考试上也爱考这个成本意识:覆盖标准越强,所需测试用例一般越多、代价越大。最后把六种串一遍:语句覆盖每个语句至少执行一次,最弱;判定覆盖每个判定的每种可能结果都至少执行一次;条件覆盖让每个条件都取得各种可能结果;判定/条件覆盖两者都要;条件组合覆盖条件结果的所有可能组合至少出现一次,前五种最强;路径覆盖每条可能执行到的路径都至少经过一次,有环路则每条环路路径至少经过一次。
小雅
本集必背清单,六条。一,白盒测试又称结构测试,主要用于单元测试阶段,前提是程序装在透明的白箱子里、测试者完全知道结构和处理算法,按内部逻辑设计用例。二,六种覆盖标准按原文顺序:语句、判定、条件、判定/条件、组合条件、路径;判定覆盖又称分支覆盖;组合条件覆盖也叫条件组合覆盖。三,语句覆盖最弱;判定覆盖比语句强;条件覆盖与判定覆盖互不包含,双向反例要会现造。四,判定/条件覆盖同时满足判定覆盖和条件覆盖;条件组合覆盖一定满足判定/条件覆盖,是前五种中最强。五,路径覆盖是较强标准,考虑判定结果的所有可能组合,但不考虑条件结果的组合,不能代替条件覆盖和条件组合覆盖。六,覆盖越强用例越多、代价越大。
阿明
这回六种谁包含谁,我脑子里是真有那张图了,不是背口诀。下一集该轮到黑盒了吧?
小雅
对,下集讲黑盒测试的四大技术——等价类划分、边值分析、错误推测和因果图,还有缺陷的分类和级别,以及软件评审的规矩。像「哪种黑盒方法用得最多」「无效等价类怎么设计用例」这些考点都在那儿等你,全是送分题,就怕你送不到位。到时候见。