第11章 · 播客 第1集

测试评审方法 · 测试基础与测试阶段

🎙️ 本集播客第1集:从「没发现 bug 的测试算不算成功」这个反直觉问题开场,把 IEEE 的错误与缺陷、测试用例的构成、三个测试计划分别订在哪个阶段、驱动模块与桩模块的分工、非渐增式与渐增式集成、确认测试与验收测试、Alpha 与 Beta 的受控与否——全是选择题直接取材点,一次拆清。 语音由微软 Edge 神经网络语音预生成(女声·晓伊,男声·云希)。点击下方任意对话可直接从该句开始播,当前句朗读时下一句已预先加载,无缝衔接。
🎙️ 第11章播客 第1集
⬇ 下载本集 点击播放
小雅
阿明,开讲第十一章之前,先来个思想实验:你跑完一轮测试,一个错误都没发现,这轮测试算成功还是失败?
阿明
当然算成功啊,程序稳得一批,皆大欢喜。
小雅
恰恰相反,这是全章最反直觉的一句。原文写得明明白白:一次成功的测试,是发现了至今为止尚未发现的错误(缺陷)的测试。一个错误都没发现,说明这轮测试基本白干。整章的口径都建立在这句话上:测试是为了发现错误,不是为了证明程序没有错误。
阿明
行,那我认栽。这章到底讲什么?
小雅
测试评审方法。先背总起句:软件测试与评审是软件质量保证的主要手段之一,是在软件交付给客户之前所必须完成的步骤。为什么必须?因为软件的正确性证明尚未得到根本的解决,测试与评审仍是发现软件错误(缺陷)的主要手段。整章五个方面:测试方法、评审方法、验证与确认、测试自动化、面向对象的测试。今天第一集打地基:测试基础概念加三个测试阶段。
阿明
那先把概念抠准。标题里一会儿「错误」一会儿「缺陷」,这俩是一回事吗?
小雅
不是,这是第一组必考辨析。根据 IEEE 的定义,「错误」error 主要针对软件开发过程,「缺陷」fault 主要针对软件产品。再说因果关系:开发人员在开发过程——主要是分析、设计和编码过程——中所出现的「错误」,是导致软件产品「缺陷」的原因;反过来说,「缺陷」是「错误」的结果和表现形式。
阿明
所以一句话:错误在过程中,缺陷在产品上,错误是因,缺陷是果。
小雅
对,这句就是答题句。考试问「根据 IEEE 的定义,错误和缺陷分别针对什么」,就答错误针对开发过程、缺陷针对软件产品;问关系,就答错误导致缺陷、缺陷是结果和表现形式。接着是测试的目的:在软件投入生产性运行之前,尽可能多地发现软件产品——主要是指程序——中的错误(缺陷)。注意措辞是「发现错误」,从来不是「证明软件正确」。
阿明
那靠什么去发现?总不能拿手瞎点吧。
小雅
靠测试用例。测试用例由测试数据和预期结果构成——这个构成要背,判断题爱挖「测试用例只包括输入数据」的坑。一个好的测试用例,是极有可能发现至今为止尚未发现的错误(缺陷)的测试用例。高效的测试,是用少量的测试用例发现被测软件尽可能多的错误;软件测试追求的目标,就是以尽可能少的时间和人力,发现软件产品中尽可能多的错误。
阿明
概念齐了。测试具体分几个阶段?
小雅
原文一句话:从测试阶段上分,软件测试通常可分为单元测试、集成测试和系统测试。先说单元测试,英文 unit testing,也称模块测试,通常可放在编程阶段,由程序员对自己编写的模块自行测试,检查模块是否实现了详细设计说明书中规定的功能和算法。三个要点:主要发现编程和详细设计中产生的错误;测试依据是详细设计说明书;单元测试计划应该在详细设计阶段制定——最后这条是高频考点。
阿明
等等,测试在编程阶段做,计划却提前到详细设计阶段订?
小雅
对,计划永远早于执行,这章有三个这样的配对,这是第一个。单元测试期间,着重从五个方面检查模块:模块接口、局部数据结构、重要的执行通路、出错处理通路和边界条件。接口、数据、通路、出错、边界,五个词记全,多选简答都够用。再补一句设计层面的:模块的内聚程度高可以简化单元测试过程——每个模块只完成一种功能,需要的测试方案数目明显减少,错误也更容易预测和发现。
阿明
五个方面记下了。单元测试有个我一直糊的东西——驱动模块和桩模块,谁调用谁?
小雅
这是本章必考第一题。测试一个模块时,需要为该模块编写一个驱动模块和若干个桩模块。驱动模块用来调用被测模块:它接收测试者提供的测试数据,把这些数据传送给被测模块,然后从被测模块接收测试结果,并以某种可以看见的方式——例如显示或打印——返回给测试者。所以驱动模块站在被测模块的上层,扮演调用方。
小雅
桩模块,英文 stub,用来模拟被测模块所调用的子模块:它接受被测模块的调用,检验调用参数,以尽可能简单的操作模拟被调用的子程序模块功能,把结果送回被测模块。它站在下层,扮演被调用方的替身。判断窍门就一个动词:调用被测模块的是驱动模块;被被测模块调用的替身是桩模块。题目问「用来调用被测模块的模块称为」,四个选项是驱动模块、桩模块、主模块、测试模块,答案是驱动模块。主模块和测试模块是凑数的干扰项,桩模块才是那个真正的坑。
阿明
驱动在上调用、桩在下被调。那是不是每个模块测试时两种都得写?
小雅
不一定,原文专门给了一对特例:顶层模块测试时不需要驱动模块,因为上面没有东西调用它;底层模块测试时不需要桩模块,因为下面没有子模块可模拟。顶无驱动、底无桩,判断题也爱考这句。接下来第二个阶段:集成测试,英文 integration testing,也称组装测试,是对由各模块组装而成的程序进行测试,主要目标是发现模块间的接口和通信问题。
小雅
原文举了五类典型问题:数据穿过接口可能丢失;一个模块对另一个模块可能由于疏忽造成有害影响;子功能组合起来可能不产生预期的主功能;个别看来可以接受的误差积累到不能接受的程度;全程数据结构可能有问题。再看它的定位:集成测试主要发现设计阶段产生的错误,而单元测试发现的是编程和详细设计中产生的错误——「发现哪个阶段的错误」是单元与集成的分界线。最要背的一句来了:集成测试计划应该在概要设计阶段制订。
阿明
这题我见过真题:问集成测试计划在哪个阶段制订,选项是需求分析、概要设计、详细设计、编码,答案是概要设计。但为什么偏偏是概要设计?
小雅
因为概要设计定的是软件总体结构和模块间接口,恰好是集成测试的对象——对象一确定,计划就能订。记忆口诀把三个串成一行:需求分析订系统测试计划,概要设计订集成测试计划,详细设计订单元测试计划,考试单抽任何一个问都从这行里答。总原则是:计划订在测试对象被设计出来的阶段,而不是执行测试的阶段,「编码阶段」这类干扰项全靠它排掉。
阿明
三条线对齐了。集成测试怎么把模块拼起来?总不能一口气全拼上吧。
小雅
还真有一口气全拼的做法。集成的方式可分为非渐增式和渐增式两大类。非渐增式集成是先测试所有的模块,然后一下子把所有模块集成到一起,把庞大的程序作为一个整体来测试。它图「一步到位」,但测试者面对众多错误现象,往往难以分清哪些是「真正的」错误、哪些是由其他错误引起的「假性错误」,诊断定位和改正错误十分困难。原文给的适用范围:非渐增式只适合一些非常小的软件。
小雅
渐增式集成是将单元测试和集成测试合并到一起:根据模块结构图,按某种次序选一个尚未测试的模块,同已经测试好的模块组合在一起测试,每次增加一个模块,直到所有模块被集成在程序中。它比较容易定位和改正错误,原文的定性是:目前集成测试已普遍采用渐增式。两组对比记牢——非渐增式适合非常小的软件、真假错误难分;渐增式普遍采用、易定位改正。
阿明
渐增式还能再往下分吧?我记得有自顶向下和自底向上两种。
小雅
对。自顶向下集成先测试上层模块,再测试下层模块;测试下层模块时它的上层模块已测试过,所以不必另外编写驱动模块——上层的真模块顶替了驱动的位置。自底向上集成先测试下层再测试上层;同样,测试上层模块时它的下层模块已测试过,所以不必另外编写桩模块。原文还给了评价:两种方法各有利弊,一种方法的优点恰好对应另一种方法的缺点,可根据软件特点及进度安排灵活选用,也可混合使用。
阿明
配套关系好记:自顶向下省驱动,自底向上省桩。那第三个阶段,系统测试呢?
小雅
系统测试是软件测试中的最后的、最完整的测试,在单元测试和集成测试的基础上进行,从全局来考察软件系统的功能和性能要求。计划时机接着串:系统测试计划应该在需求分析阶段制订——因为系统测试对照的是需求,需求一出来计划就能订,它是三条线里订得最早的。通常,系统测试包括确认测试和验收测试,这两个词后面全是考点。
阿明
确认测试确认什么?名字看着就虚。
小雅
原文的界定很实:确认测试,主要依据软件需求说明书检查软件的功能、性能及其他特征是否与用户的需求一致——依据是软件需求说明书,对照的是「需求」。它还有另一项重要内容,叫软件配置复查:目的是保证软件配置的所有成分齐全,质量符合要求,文档与程序完全一致,具有完成软件维护所必需的细节。功能对不对、配置齐不齐,这是确认测试的两条腿。
阿明
确认完就该交付了吧?验收测试是客户来验?
小雅
分两种情况。如果一个软件是为某个客户定制的,最后还要由该客户来实施验收测试,以便确认其所有需求是否都已得到满足;而且由于软件系统的复杂性,验收测试可能会持续到用户实际使用之后的相当长的一段时间——这句本身就能出判断题。反过来,如果软件是作为产品被许多客户使用的,不可能也没必要由每个客户进行验收测试。
阿明
作为产品的软件怎么发现只有最终用户才能发现的错误?
小雅
原话是:绝大多数软件开发商都使用被称为 Alpha 测试和 Beta 测试的过程,来发现那些看起来只有最终用户才能发现的错误。两个词各配三要素:谁测、在哪、受不受控。Alpha 测试由用户在开发者的场所进行,并且在开发者的指导下进行测试,开发者负责记录发现的错误和使用中遇到的问题——也就是说,Alpha 测试是在「受控的」环境中进行的。
小雅
Beta 测试是在一个或多个用户的现场由该软件的最终用户实施的,开发者通常不在现场,用户负责记录发现的错误和使用中遇到的问题并把这些问题报告给开发者——也就是说,Beta 测试是在「不受控的」环境中进行的。背诵对子:Alpha 用户在开发方场所、开发者指导、受控;Beta 用户现场、开发者不在场、不受控。
阿明
考题怎么下套我大概能猜到——把 Beta 的「不受控」安到 Alpha 头上。
小雅
猜得很准。真题问「Alpha 测试的特点是」,四个选项:在用户现场由最终用户实施、开发者不在场——那是 Beta;在不受控的环境中进行——那也是 Beta;在开发者场所进行、由用户在开发者指导下测试——这才是 Alpha,选它;由开发人员自行进行测试——错,Alpha 是用户来测,开发者在场只是指导并记录。每个选项都对应一种错法,四要素背全就是送分。最后补一句:经过系统测试之后的软件通常就可以交付使用了。
阿明
三个阶段走完一个软件就出门了。这集密度不小,帮我收个尾吧。
小雅
必背清单:一,IEEE 定义错误针对开发过程、缺陷针对软件产品,错误是因、缺陷是果;二,测试目的是投入生产性运行前尽可能多地发现错误,成功的测试是发现了至今未发现的错误的测试;三,测试用例由测试数据和预期结果构成;四,三阶段是单元、集成、系统,计划时机口诀——需求分析订系统测试计划、概要设计订集成测试计划、详细设计订单元测试计划;五,驱动模块调用被测模块、桩模块模拟被调子模块,顶层免驱动、底层免桩;六,集成分非渐增式和渐增式,渐增式普遍采用,自顶向下省驱动、自底向上省桩;七,系统测试含确认测试和验收测试,确认依据软件需求说明书、另有软件配置复查;八,Alpha 在开发者场所受控、Beta 在用户现场不受控。
阿明
八条都在。不过有个词今天一直没出现——单元测试设计用例,用黑盒还是白盒?
小雅
问对了,这正是下一集的主菜。原文把测试从方法上分成白盒和黑盒:白盒又称结构测试,主要用于单元测试阶段,核心是六种逻辑覆盖,从最弱的语句覆盖排到最强的条件组合覆盖,谁包含谁是判断题重灾区;黑盒又称功能测试,主要用于集成和确认测试阶段,等价类划分、边值分析、错误推测、因果图四大技术,哪个用得最多、无效等价类怎么设计用例,全是直接选择题。下一集把六种覆盖的强弱排序一次讲透。
阿明
那我先把这八条背熟,等下一集的逻辑覆盖。