### 【1.27】从狭义的软件测试到广义的软件测试(7 分钟) > **口播**:同学们,前面我们讲了软件缺陷带来的惨痛代价。从这一页开始,我们要回答一个更基础的问题:软件测试到底测什么?先看一个很常见的误解——很多人一说测试,脑子里出现的画面就是:程序写完了,运行起来点一点,看看有没有报错。这就是最狭义的软件测试,一句话概括:软件测试等于程序测试。但请注意,软件不只是可执行的程序。按照软件工程的观点,需求、设计、代码这三样东西,都属于软件的组成部分。需求说清楚要做什么,设计决定怎么做,代码才是最后的实现。既然这三样都是软件,那它们出了问题,是不是软件缺陷?当然是。而检查这三样东西有没有问题,靠的不是把程序跑起来,靠的是评审——需求评审、设计评审、代码审查。这些评审工作有一个统一的名字,叫静态测试。 > > 那么问题来了:为什么过去我们不觉得评审算测试?因为早期观念里,只有"运行程序、看到结果"才算测试。可是大家想一想,如果在需求阶段就发现"这个功能压根没写清楚",你还需要等代码写完再跑一遍去发现吗?完全不需要。所以,当业界正式提出"动态测试"这个词的时候,其实已经从反面承认了:还有一类不需要运行程序的测试,也就是静态测试。于是软件测试的范围扩大了——软件测试既包含静态测试,也包含动态测试,这就是广义的软件测试。 > > 为什么一定要强调"广义"?因为它直接决定成本。有一句话请大家记牢:测试进行得越早,成本越低;反过来,缺陷发现得越迟,研发成本越高。你早一步在评审桌上指出需求里的二义性,代价可能只是改一句话;等系统上线了才发现,改的就是代码、接口、文档,甚至用户的信任。这笔账具体怎么算,我们看下一页的成本曲线。 **板书**:狭义:软件测试=程序测试 → 广义:软件=需求+设计+代码 → 对需求/设计/代码的评审=静态测试 → 软件测试=静态测试+动态测试 → 测试越早,成本越低 **提问**:如果一个功能的需求文档里写"系统应快速响应用户请求",这条需求本身有没有问题?它属于静态测试还是动态测试的检查对象? **预设回答**:①答"没问题,写得挺清楚"——要追问:多快算快?1 秒还是 10 秒?谁来判断达标?指出"快速"是二义性需求,测试无法据此判定通过与否。②答"这是需求问题,应该让开发去改"——要强调这正是测试人员的活:需求评审就是静态测试的战场,测试要在需求阶段就把不可测的词挑出来。③答"属于动态测试"——纠偏:需求文档不运行程序,属于静态测试。点评要点:能在需求阶段发现二义性,就是最便宜的缺陷修复。 **易错点 / 考点**:常见混淆是把"软件测试"等同于"程序测试"(狭义),漏掉对需求、设计的静态测试。考点多以判断题出现:"只有运行程序才能叫测试"——错。判断三步法:一看对象(需求/设计/代码/程序)→ 二看是否运行程序(不运行即静态测试,运行即动态测试)→ 三看时机(越早越便宜)。 **过渡**:既然早发现能省钱,那到底能省多少?我们把成本曲线摊开来看。 --- ### 【1.28】广义的软件测试可以极大地降低研发成本(8 分钟) > **口播**:大家看这张图。横轴是软件开发的时间轴——需求、设计、编码、测试、上线运维;纵轴是修复一个缺陷所要付出的成本。图上这条曲线,请特别注意它的形状:它不是一条斜着往上的直线,而是一条越往右越陡的曲线。这就是我们反复强调的四个字:非线性增长。 > > 什么叫非线性?打个比方。装修房子的时候,你在图纸阶段跟设计师说"这面墙我想敲掉",设计师改一张图纸,几分钟的事,成本几乎为零。等到水电都铺好了你才说要敲墙,得重新布线、重新贴砖,又花钱又费时。要是房子已经住进去三年了才想起来要敲,那要搬家具、要临时找住处,成本翻好几倍。软件是一模一样的道理,而且软件更狠,因为软件是"牵一发而动全身"的。 > > 具体怎么个牵动法?一个缺陷在需求阶段被发现,你改的是文档上的一句话,成本就是一次讨论。到了设计阶段,你得改设计文档、改接口定义,上下游同事都要跟着对齐。到了编码阶段,你要改代码,还要改相应的单元测试。到了测试阶段才发现,代码要改、已经跑过的测试要重跑、相关模块要回归。要是等产品上线、用户已经用起来了才爆出来,那就不只是改代码的问题了:要紧急发版,要写公告,要处理用户投诉,严重的话还要赔偿、丢客户、丢口碑。这就是为什么这条曲线在后期会陡得吓人。 > > 所以我们说,广义的软件测试之所以能极大地降低研发成本,道理就在这里:它把测试这件事从"最后一道关"变成了"贯穿始终的一条线"。需求评审、设计评审、代码审查这些静态测试,做的是最左边、最便宜的那一段;动态测试在中间和右边兜底。左边的成本压下去了,整个项目的总成本才降得下来。 **板书**:缺陷发现越迟 → 修复成本越高,且非线性增长(曲线左低右陡)→ 成本构成:改文档/改设计/改代码+回归/发版+公告+投诉+赔偿 → 广义测试=把测试铺满全过程,压住最左端 **提问**:同样一个"登录后跳转错误"的缺陷,在需求评审时发现,和在产品上线后被用户发现,修复成本差在哪里?请至少说出三项差异。 **预设回答**:①只说"花的钱不一样多"——要追问具体差在哪,引导说出:改动对象(文档/设计/代码/已上线系统)、连带工作(重测与回归范围)、外部影响(用户投诉、公告、口碑与赔偿)。②答"反正都要改代码,成本差不多"——典型错误,纠偏:越早发现,越可能只改文档或设计,根本不进代码。③答"上线后发现问题更严重所以贵"——肯定方向,补充"非线性"这一层:不是贵一点,而是成倍地贵,因为回归范围随系统规模扩大。点评:把三者串成一句——发现越迟,要动的东西越多、要重做的验证越多、要面对的外部人越多。 **易错点 / 考点**:易错是把成本增长理解成线性,认为"晚发现无非多花一点时间"。考点:给一个事故情境问"该缺陷本应在哪个阶段被发现,能省下哪些成本"(案例分析)。记忆口诀:早一步在文档上改一句话,晚一步在系统里改一圈。 **【思政落点 1】**:讲国外真实事故——Therac-25 放疗仪因软件缺陷导致患者受到过量辐射致死,骑士资本因交易系统缺陷在 45 分钟内亏损约 4.6 亿美元。这些代价背后共同的一点是:缺陷在最贵的那一段才被发现。要让学生先估算损失量级,再对照真实数据,体会"没有测试把关就交付"意味着什么。落到职业观:测试人员的质量责任不是口号,你手里那张用例表,可能对应着使用者的生命安全与公众利益。 **过渡**:知道了成本曲线,我们再把镜头拉远,看看软件测试这门学科是怎么一步步走到今天的。 --- ### 【1.29】软件测试学科的发展(8 分钟) > **口播**:这一页讲软件测试学科的发展脉络,四个阶段、四个关键词,请大家把年份和"导向"对应起来记。 > > 第一个阶段,1957 到 1978 年,以功能验证为导向。这个时期大家对测试的理解是:测试就是证明软件是正确的。注意这句话背后的思维方式,是正向思维——我先相信软件是对的,测试的任务是把这个"对"证明出来。所以做法通常是跑一遍功能,看看结果跟预期是否一致,一致就算通过。 > > 第二个阶段,1978 到 1983 年,以破坏性检测为导向。这是一个观念上的转折点。人们发现,你按说明书跑一遍功能、跑通了,并不能说明软件没问题——你只是没找到问题而已。于是测试的目的变了:测试是为了找到软件中的错误。这是逆向思维:先假定软件有错,然后想尽办法把它找出来。 > > 第三个阶段,1983 到 1987 年,以质量评估为导向。这一时期,测试的意义又被抬高了:它不只是找错,还要提供产品的评估和质量度量。也就是说,测试要回答"这个产品现在到底处于什么质量水平"——缺陷有多少、严重程度如何、哪些模块风险高。测试开始从"找 bug 的手艺"变成"提供质量信息的工作"。 > > 第四个阶段,1988 年起,以缺陷预防为导向。测试是为了展示软件符合设计要求,发现缺陷、预防缺陷。请注意最后两个字:预防。发现缺陷是治已病,预防缺陷是治未病——通过分析缺陷的分布和模式,回头去改需求和开发的流程,让同一类缺陷不再反复出现。 > > 四个阶段连起来,是一条很清晰的线:证明对 → 找出错 → 评估质量 → 预防缺陷。测试的地位,也从"事后挑毛病"一路升到"过程改进的引擎"。 **板书**:1957–1978 功能验证(正向:证明正确)→ 1978–1983 破坏性检测(逆向:找错误)→ 1983–1987 质量评估(提供质量度量)→ 1988– 缺陷预防(发现+预防缺陷) **提问**:这四个阶段里,哪些阶段的测试目标已经超出了"找缺陷"本身?它们分别多做了什么? **预设回答**:①只答"第四个,1988 年起"——部分正确,要追问:第三个阶段其实也超了,它提供的是"质量度量",回答的是产品处于什么质量水平。②答"第二阶段最重要,因为开始找错了"——肯定其转折意义,但提醒:找错仍是"治已病",第四个阶段才引入预防。③答"都差不多,就是找 bug"——纠偏:四个阶段的目标从"证明正确"到"预防缺陷",思维方式和工作产出都不一样,后期还要出质量度量和缺陷模式分析。点评:答案要落在"质量评估(提供信息)"和"缺陷预防(改流程)"这两级上。 **易错点 / 考点**:易错是把 1957–1978 的"正向思维"与后面 Myers 的反向思维混为一谈;把"质量评估"当成"质量保证"。考点:年份与导向的匹配(选择题)、"测试目的的演变"(简答)。记忆口诀:证明—找错—度量—预防,四步走。 **过渡**:这是一种划分方法。同样这段历史,换一个观察角度,还能切成三个阶段。 --- ### 【1.30】不同的阶段划分(7 分钟) > **口播**:刚才我们用"导向"把软件测试的历史切成了四段,这一页换成另一种切法,按学科成熟度切成三个阶段。两种切法讲的其实是同一段历史,只是观察角度不同,考试里两种都要认得。 > > 初级阶段,1957 到 1971 年。这个阶段最典型的特征是一句话:测试通常被认为是对产品进行事后检验。什么叫事后检验?就是产品做完了,拉出来检一遍,合格就交付。它跟工厂里质检员拿卡尺量零件是一个思路。而且这个阶段缺乏有效的测试方法——没有系统的用例设计方法,没有覆盖率的说法,靠的是个人经验和直觉。所以这个阶段的测试,地位低、效果差,还经常背锅。 > > 发展阶段,1972 到 1982 年。这十年里有一个标志性事件:1972 年召开了第一次关于软件测试的正式会议。为什么一次会议这么重要?因为在这之前,测试是每个程序员各自的手艺活,没有统一的术语、没有公认的方法、也没有交流的平台。有了正式会议,大家开始把测试当成一个值得研究的对象:怎么设计用例、怎么评价测试是否充分、测试和开发怎么分工。这些问题被摊到桌面上讨论,软件测试才真正开始"长学问",也促进了它的发展。 > > 成熟阶段,1983 年到现在。标志是国际标准 Std 829-1983 的发布。这个标准把测试文档规范了下来——测试计划、测试说明、测试用例、测试报告该写什么、怎么写,都有了统一要求。有了标准,测试就从"手艺"变成了"专业":它可以被教学、被检查、被审计、被认证。于是软件测试形成一门独立的学科和专业,成为软件工程学科中的一个重要组成部分。 > > 三个阶段连起来:事后检验的手艺 → 有交流、有方法的研究对象 → 有标准、有分工的独立专业。这也解释了为什么今天的企业会设专门的测试部门、测试岗位和测试职级。 **板书**:初级阶段 1957–1971:事后检验,缺有效方法 → 发展阶段 1972–1982:1972 年第一次软件测试正式会议,促进发展 → 成熟阶段 1983–:国际标准 Std 829-1983,独立学科与专业,软件工程重要组成部分 **提问**:为什么说 1972 年的第一次软件测试正式会议,是测试从"手艺"走向"学科"的关键一步? **预设回答**:①答"因为开会很重要"——空话,要追问:会议到底提供了什么?引导说出"统一术语、交流方法、形成研究共同体"。②答"因为这个会议发布了标准"——纠偏:Std 829-1983 是成熟阶段的标志,1983 年才发布,不要张冠李戴。③答"因为从此测试有了专门的人做"——肯定,补充:有了交流平台,个人经验才能沉淀成可传授的方法,方法才能变成标准和专业分工。点评:一次会议的价值,在于把个人经验变成公共知识。 **易错点 / 考点**:易错是把两种阶段划分的年份和标志事件搞混(尤其 1972 年会议与 1983 年标准),以及把初级阶段的"事后检验"误记成"缺陷预防"。考点:阶段—年份—标志事件三连线(选择/填空)。记忆三步:先定时段(1957–1971/1972–1982/1983–)→ 再定标志(事后检验/首次正式会议/Std 829-1983)→ 最后定地位(缺方法/促发展/独立学科)。 **过渡**:历史的脉络清楚了,接下来进入 1.3.2,看一个至今还在争论的问题:测试到底是为了证明对,还是为了找出错? --- ### 【1.31】1.3.2 正反两方面的争辩(4 分钟) > **口播**:我们进入 1.3.2 节,正反两方面的争辩。 > > 先解释一下这个标题。软件测试从诞生到现在,围绕"测试的目的到底是什么",一直有两种针锋相对的观点。一种说:测试是为了证明软件能正常工作,让用户和开发团队对它建立信心。另一种说:测试是为了证明程序有错,你要是没找到错,那说明这次测试做得还不够狠。这就是所谓的正向思维和反向思维。 > > 大家可能会问:这不就是个定义之争吗?咬文嚼字有什么意义?意义很大。因为你怎么理解测试的目的,直接决定你怎么设计用例、怎么判断测试做完了没有。 > > 如果按正向思维,你的动作是:把需求说明书上的功能一条一条跑一遍,全都通过了,就认为测试完成、可以交付。如果按反向思维,你的动作完全不同:你要专门去想"这个功能在什么情况下会出错"——边界值、异常输入、并发、断网、极端数据,你要主动去攻击这个系统,直到想不出新的攻击方式为止。同样一个登录功能,两种思维写出来的用例,数量和质量都天差地别。 > > 所以这一节我们不是死记概念,而是要搞清楚三件事:两种思维方式各自长什么样、各自出自谁的观点、它们的价值分别在哪里。最后我们还要落到一个更实际的结论——它们不是二选一,而是要在不同场景下配合使用。接下来两页,我们先分别认识两位代表人物。 **板书**:1.3.2 正反两方面的争辩 → 正向思维:验证软件"能工作",跑遍功能直至全部通过 → 反向思维:假定软件有错,"找出错",攻击薄弱点直至找不出问题 → 认知决定用例怎么设计、何时算测完 **提问**:如果只允许你用一句话向新人解释"测试的目的",你会站正向还是反向?为什么? **预设回答**:①站正向:"测试就是确认功能都对"——追问:功能都通过了,能保证没有隐藏问题吗?引导认识"通过≠无错"。②站反向:"测试就是找 bug"——肯定这是 Myers 的经典立场,再追问:一个查不出 bug 的测试就等于失败吗?引导到"测试的价值也在于提供质量信息"。③答"看情况"——这个答案最有前途,顺势引导到下一页的结论:两种思维各有适用场景,工程上要结合使用。点评:先让学生亮明立场,再用后面的内容让他们自己修正立场。 **易错点 / 考点**:易错是把"正向思维"理解成"积极的态度"、把"反向思维"理解成"消极的态度"——两者说的是方法论立场,不是工作态度。考点:给出一段测试行为描述,判断属于正向还是反向思维。 **过渡**:先看正向思维的代表人物和他的原话。 --- ### 【1.32】软件测试的正向思维(8 分钟) > **口播**:这一页是正向思维的代表,Bill Hetzel 博士。请大家把他的名字和"正向思维"绑在一起记,这是考点。 > > 先看他最核心的一句话:软件测试就是为程序或系统能够按预期设想运行而建立信心的过程。请注意这句话的落点——"建立信心"。在 Hetzel 看来,测试的产出不只是"发现了几个问题",更是"让相关的人相信这个系统能按预期跑起来"。如果测试做完了,大家对这个系统能不能上线还是心里没底,那测试就没达到目的。 > > 他还有一句更书面、更像定义的表述:软件测试是一系列活动,以评价一个程序或系统的特性或能力,并确定是否达到预期的结果。这句话里有三个动作,请大家拆开来记:第一,它是"一系列活动",不是随手点几下;第二,它的对象是"特性或能力",比如性能、可靠性、易用性;第三,它的结论是"是否达到预期的结果"——也就是说,测试要给出一个有依据的判断。 > > 接着看第三句:测试是为了验证软件是否符合用户需求,即验证软件产品是否能正常工作。这句话把"预期"的来源点清楚了——预期不是开发人员自己拍脑袋定的,而是用户需求。所以正向思维的本质,是拿需求当尺子去量产品。 > > 我们用一个生活场景来体会。你去餐厅点了一份牛排,要求七分熟。菜端上来,你切开看一眼,确实是七分熟,于是你满意了。这个"看一眼、确认符合要求"的过程,就是正向思维。它回答的问题是:该做的,做到了吗? > > 但大家马上能想到一个问题:我看这一眼,只能证明这一块牛排是七分熟,不能证明后厨没有别的隐患——比如食材新不新鲜、有没有交叉污染。也就是说,正向思维能验证"符合要求",但它天然不擅长发现"没想到的问题"。这个短板,就是下一页反向思维要补的。 **板书**:正向思维代表:Bill Hetzel → 测试=为"按预期运行"建立信心的过程 → 测试=一系列活动,评价特性/能力,确定是否达到预期结果 → 测试=验证软件是否符合用户需求 → 回答:该做的,做到了吗? **提问**:按 Hetzel 的说法,"测试是一系列活动以评价特性或能力并确定是否达到预期结果"。这句话里的"预期结果"应该由谁提供? **预设回答**:①答"开发人员"——纠偏:预期来自用户需求,开发人员自己的假设不能当尺子。②答"测试人员自己判断"——追问:测试人员的个人判断如果和需求不一致怎么办?引导到"以需求文档、规格说明为依据,需求不清就回到需求阶段解决"。③答"用户需求"——正确,追问:如果需求文档本身就写得含糊呢?正好呼应前面讲的静态测试——需求二义性要在评审阶段挑出来。点评:测试的尺子是需求,尺子本身不准,量出来的结论就没有意义。 **易错点 / 考点**:易错是把"建立信心"理解成"测试就是走个过场让人放心"。考点:Hetzel 与 Myers 各自观点与人名的对应(选择题/连线题);"测试是为了验证软件是否符合用户需求"出自谁的观点。判断三步法:看落点——落在"符合预期/建立信心"是正向,落在"发现错误/证伪"是反向。 **过渡**:正向思维把测试当"确认",反向思维则把测试当"进攻"。我们看 Myers 怎么说。 --- ### 【1.33】软件测试的反向思维(8 分钟) > **口播**:这一页是反向思维的代表,Glenford J. Myers。如果说 Hetzel 的落点是"建立信心",Myers 的落点就是四个字:证明有错。 > > 先看他的第一句话,也是最有冲击力的一句:测试是为了证明程序有错,而不是证明程序无错误。按常识,我们做测试不就是为了确认软件没毛病吗?Myers 说不。他的逻辑是:你把软件跑一遍没发现问题,只能说明这一次没找到,不能证明软件没有问题;而只要你能找到一个错误,你就确凿地证明了"这个程序有错"这件事。所以从逻辑上讲,测试能够证明的是"有错",不能证明的是"无错"。 > > 再看第二句:一个好的测试用例在于它能发现至今未发现的错误。这一句把"好用例"的标准给改了。过去我们评价用例,看的是它覆盖了哪个功能、写得规不规范;Myers 说,这些都不是关键,关键是你这条用例有没有真的抓到过问题。一条跑一万遍都通过的用例,和一条抓出严重缺陷的用例,价值完全不一样。这个观点直接催生了后来的一整套用例设计方法——等价类、边界值、错误推测,全都是为了让用例"更容易抓到错"。 > > 第三句更彻底:一个成功的测试,是发现了至今未发现的错误的测试。注意"成功"这两个字的位置——测试的成功不在于"全部通过",恰恰在于"逮到了问题"。这就带来一个推论:如果一轮测试下来一个缺陷都没发现,这轮测试到底算成功还是失败?按 Myers 的立场,得先怀疑是不是做得太软了。 > > 生活里也有类似的场景:安检员一天下来什么都没查出来,我们不会觉得他工作很成功,反而会担心他是没认真查。所以反向思维的本质是:先假定系统有问题,再带着"我要把它找出来"的心态设计测试。正向和反向到底谁对?下一页我们用一张表把两者摆在一起看。 **板书**:反向思维代表:Glenford J. Myers → 测试是为了证明程序有错,而不是证明程序无错误 → 好的测试用例=能发现至今未发现的错误 → 成功的测试=发现了至今未发现的错误 → 回答:怎么能把它弄坏? **提问**:按 Myers 的观点,如果一轮测试执行完毕,一个缺陷也没有发现,你该如何评价这轮测试? **预设回答**:①答"说明软件质量很好"——最典型的错误,纠偏:也可能说明用例设计得太弱、只跑了主流程、没有攻击边界和异常。②答"说明这轮测试不合格"——太绝对,追问:如果用例已覆盖边界、异常、组合,仍然没发现缺陷,那它的价值在哪里?(提供质量信息,说明该范围的缺陷密度低。)③答"要看用例是怎么设计的"——最成熟的回答,肯定并总结:先看测试的充分性,再谈软件的质量。点评:把"没发现缺陷"当成需要解释的现象,而不是结论。 **易错点 / 考点**:易错是把"Myers 说测试是为了证明程序有错"误解成"测试人员的工作就是挑刺、和开发对立"——它说的是方法论,不是人际关系。考点:Myers 三句名言的填空与理解;"成功的测试"的判断(易出判断题,选项常写成"测试全部通过即成功"——错)。记忆口诀:Hetzel 建信心,Myers 找错误。 **过渡**:两种思维摆在一起,差别就一目了然了。看这张对比表。 --- ### 【1.34】认知决定着行为(9 分钟) > **口播**:这一页的标题叫"认知决定着行为",它把正向和反向两种思维放在一张表里对照。为什么要对照?因为这张表要证明一件事:你怎么认知测试,就直接决定你手上敲出来的用例长什么样。 > > 我们先看表的上半部分。左边一路是正向思维:它的前提是验证软件正常工作;对应的行为描述是——在设计规定的环境下运行软件的所有功能,直至全部通过。请注意这里面的两个关键词:"所有功能"和"全部通过"。正向思维追求的是覆盖面加通过率,它是一张清单式的做法:需求上有多少功能,我就跑多少功能,跑完都绿了,收工。右边一路是逆向思维:它的前提是假定软件有错误;对应的行为描述是——寻找容易犯错误的地方和系统的薄弱环节,试图破坏系统,直至找不出问题。 > > 两句话一对比,差别非常清楚。正向是"遍历清单",逆向是"攻击弱点":一个按需求文档往下走,一个按风险和经验去找。正向问"这个功能正常吗",逆向问"我怎么能把它弄坏"。 > > 再往上看一点,这里还并列了两句关于测试的说法:一句是"评价一个程序或系统的特性或能力并确定是否达到预期的结果",另一句是"测试是为发现错误而针对某个程序或系统的执行过程"。这两句话各自代言一种思维,最后都指向同一个词——软件测试。所以这一页真正想告诉大家的是:软件测试这个概念本身就同时包含两层含义,既有度量的成分,也有证伪的成分。它不是非此即彼,而是一体两面。 > > 那工程上应该怎么用?我的建议是分场景:对安全攸关的系统,比如医疗设备、金融交易,要更多用逆向思维——漏掉一个缺陷的代价不可承受;对需求明确、迭代快速的普通业务系统,正向思维能保证基本功能可靠,但也不能只做正向,否则线上一定会被"没想到的路径"教育。 **板书**: | 认知(前提) | 行为(做法) | 终止条件 | |---|---|---| | 正向:验证软件正常工作 | 在设计规定的环境下运行软件的所有功能 | 直至全部通过 | | 逆向:假定软件有错误 | 寻找容易犯错误的地方和系统的薄弱环节,试图破坏系统 | 直至找不出问题 | → 结论:软件测试=度量+证伪,一体两面 **提问**:同样测一个"转账"功能,正向思维和逆向思维分别会写出什么样的用例?请各举一条。 **预设回答**:①正向举例:"输入正确账号和金额 100 元,点击转账,检查余额扣减 100 元"——典型的按规格验证,肯定它。②逆向举例:"余额刚好等于转账金额""金额输入 0 或负数""转账过程中断网""并发两笔同时扣款"——这正是对薄弱环节的攻击,表扬。③答"逆向就是随便乱输"——纠偏:乱输不叫逆向思维,逆向是有目的地找易错处(边界、异常、并发、状态),错误推测法也是讲方法的。追问:这两条用例哪一条更可能在真实项目里抓到线上事故?引导学生体会逆向用例的价值。 **易错点 / 考点**:易错是把正向思维等同于某种用例设计方法(如等价类)、把逆向思维等同于错误推测法——两两相关但不等同,正向/逆向是目的层面的立场。考点:给出行为描述判断思维类型;简答"为什么说软件测试是一体两面"。判断三步法:看前提(假设软件对/错)→ 看动作(遍历功能/攻击薄弱点)→ 看终止条件(全部通过/找不出问题)。 **过渡**:认知讲完了,接下来要落到最关键、也是考得最多的一件事:给软件测试下一个严谨的定义。进入 1.3.3。 --- ### 【1.35】1.3.3 软件测试的定义(4 分钟) > **口播**:我们进入 1.3.3,软件测试的定义。 > > 可能有同学会想:前面都讲了两节课了,怎么到现在才讲定义?这恰恰是有意安排的。因为"软件测试"这四个字在不同人嘴里含义差别很大——有人指跑一遍程序,有人指找 bug,有人指评估质量,还有人把它和质量保证混在一起。如果不在前面把历史、把静态动态、把正反思维讲清楚,直接甩一个定义给大家,大家只会背下来,不会真正理解。 > > 所以这一节的任务是:先看看大家心里默认的定义是什么,再用国际标准给出的定义把这个概念框住,最后用"软件测试的价值"来收口,回答"它到底给项目带来什么"。 > > 我先给大家透个底:这一节里的定义来自 IEEE 和 ISO/IEC 29119 相关标准,都是英文原文加中文翻译。看到英文不要怕,我们逐句拆,重点是把定义里的每个要素抠出来——在什么条件下、对什么东西、做什么动作、得到什么结果。定义之所以是定义,就是因为这些要素缺一不可。以后你们写测试计划,实际上就是在回答这几个要素:条件是什么、对象是什么、动作是什么、结果怎么评价。 > > 另外提醒一句,这一节后面还有"软件测试的价值",那四点请大家务必记牢。它不仅是考试内容,更是你们在课程设计答辩时被问到"你这个测试有什么意义"时的标准答案。待会儿看到英文原文也别跳过——考试里定义要素的识别,就藏在那句话的每一个词里面。 **板书**:1.3.3 软件测试的定义 → 为什么放到现在讲:先有历史/静态动态/正反思维 → 依据:IEEE、ISO/IEC 29119(对应 ISO/IEC 24765 词汇)→ 收口:软件测试的价值 **提问**:在看标准定义之前,请你用自己的话说一句"软件测试是什么"。你觉得你的说法里,缺了哪个要素? **预设回答**:①"软件测试就是运行程序找 bug"——缺"在特定条件下""观察或记录结果""做出评价"这几个要素。②"软件测试就是确认软件没问题"——这是正向思维的口径,缺"评价"和"发现差别"的成分。③"软件测试就是保证质量"——把测试和质量保证混了:测试提供质量信息,不"保证"质量。点评:把学生的答案先写在黑板上,讲完标准定义再回头对照,让他们看到自己漏了哪几个词,这是最有效的定义教学法。 **易错点 / 考点**:易错是把"软件测试"和"质量保证"当成同义词。考点:标准定义中要素的识别;"测试能不能保证质量"(判断题:不能,测试只能提供质量信息)。 **过渡**:那我们先来看,大家心里想的那些答案,究竟哪个才算是软件测试。 --- ### 【1.36】什么是软件测试?(8 分钟) > **口播**:这一页是一张图,图上的问题很直白:什么是软件测试?然后列了一串大家脑子里的答案,我们一个一个过,看看哪些对、哪些不全对。 > > 第一个答案:检查、检验,Check。这个说法很朴素,就是"看一眼有没有毛病"。它对,但太笼统——检查什么?怎么检查?检查到什么程度算够?都没回答。 > > 第二个:验证软件能否正常运行。这就是我们前面说的正向思维口径,它的短板也很清楚:正常运行只说明主流程没问题,异常路径、边界情况都没碰到。 > > 第三个:发现问题,Detect error。这是反向思维口径,抓问题、找错误。但它只讲了测试的一个动作,没讲测试还要给结论。 > > 第四个:证明是对的,Correction proof。这个说法最危险。因为软件测试在逻辑上做不到"证明软件无错"——你测过的路径是有限的,没测过的路径是无限的。所以严格讲,测试不能证明正确,只能提供证据。 > > 第五个:质量评估,Quality evaluation。这个说法往前迈了一大步:测试要给出对质量的判断,比如缺陷密度、严重程度分布、风险模块。这是 1983 到 1987 年那个阶段的成果。 > > 第六个:质量保证,Quality Assurance。注意,这个最容易混淆。质量保证管的是过程——规范、评审、度量、流程改进,从源头上让缺陷少产生;测试管的是产品——验证和确认,提供质量信息。测试是质量保证的重要手段之一,但测试不等于质量保证。 > > 所以你看,这六个答案从"看一眼"一路走到"保证质量",本身就是一个认知不断升级的过程。它们不是互相否定,而是层层包含:检查是动作,找错是目标,评价是结论,而质量保证是更大的范畴。下一步,我们就用国际标准的定义,把这些零散的认知收成一个完整、严谨的说法。 **板书**:什么是软件测试?→ 检查/检验 Check?→ 验证能否正常运行?→ 发现问题 Detect error?→ 证明是对的 Correction proof?→ 质量评估 Quality evaluation?→ 质量保证 Quality Assurance?→ 六者层层包含,最后用标准定义收口 **提问**:这六个答案里,哪一个说法在逻辑上最站不住脚?为什么? **预设回答**:①选"证明是对的"——正确,追问为什么:测试只能执行有限条路径,无法穷尽,所以只能提供证据,不能给出证明。②选"质量保证"——也抓住了要点,但要说清它不是"站不住脚"而是"范畴混淆":质量保证包含测试,不能说测试就是质量保证。③答"检查、检验"——可以讨论:它不算错,只是太笼统。点评:要区分两类问题——逻辑错误(证明正确)与概念混用(测试 vs 质量保证)。 **易错点 / 考点**:易错是认为"测试通过"就等于"软件没有缺陷";把质量评估与质量保证混为一谈。考点:给出一句关于测试的说法,判断是否正确并说明理由(高频简答)。记忆口诀:查→找→评→保,四层递进;但"证明正确"这一层永远做不到。 **过渡**:大家心里的答案过完了,下面看权威标准怎么定义。 --- ### 【1.37】软件测试 IEEE/ISO29119 的定义(8 分钟) > **口播**:这一页是权威定义,出自 ISO/IEC 24765《系统和软件工程词汇》,也是 IEEE 与 ISO/IEC 29119 采用的口径。英文原文我先读一遍,再逐要素拆。 > > 原文是:An activity in which a system or component is executed under specified conditions, the results are observed or recorded, and an evaluation is made of some aspect of the system or component. > > 中文译文是:在特定的条件下运行系统或组件,观察或记录结果,对系统或组件的某个方面做出评价。 > > 这个定义每个词都有讲究,我们拆成四个要素。 > > 第一,它是一项活动。这提醒我们:测试是有组织、有计划的过程,不是随手点两下;是活动,就意味着有输入、有步骤、有产出。 > > 第二,在特定的条件下运行。这个"特定条件"太重要了。测试绝不是"随便跑跑",你必须先想清楚:用什么数据、什么环境、什么配置、什么前置状态。条件不明确,结论就没有意义。反过来说,测试用例的本质,就是把"特定条件"固化下来。 > > 第三,观察或记录结果。这里的关键词是"记录"。光看见不行,要有可追溯的记录:实际结果是什么、截图在哪、日志在哪。这也是为什么我们课程实验要求大家截图留证。 > > 第四,对系统的某个方面做出评价。注意两点:一是"做出评价",测试必须给判断,不能只报现象;二是"某个方面",说明测试是有侧重的,一次测试通常只针对功能、性能、兼容性这类特定方面,不可能一口气覆盖全部。 > > 四个要素连起来,就是完整的测试活动:明确条件下运行 → 观察并记录结果 → 对特定方面做出评价。以后写用例、写测试报告,都可以拿它来检查有没有漏。 **板书**:ISO/IEC 24765(IEEE、ISO/IEC 29119 口径)→ 四要素:①Activity 一项活动 ②executed under specified conditions 特定条件下运行 ③results observed or recorded 观察或记录结果 ④evaluation of some aspect 对某个方面做出评价 **提问**:这个定义里,哪个要素是很多同学做实验时最容易忽略的?漏了它会有什么后果? **预设回答**:①答"记录结果"——最常见,追问后果:没有记录就无法复现、无法证明缺陷存在,开发一句"我这边没问题"就能把缺陷打回去。②答"特定条件"——也很好,追问:条件不写清楚,别人照你的用例跑不出同样结果,用例就没有可重复性。③答"做出评价"——提醒:只报"点了一下没反应"是现象,不是评价,要说清"这违反了哪条需求、严重程度如何"。点评:把要素落到课程设计的具体动作上——用例要有前置条件、步骤、预期结果、实际结果、截图和结论。 **易错点 / 考点**:易错是把定义背成"运行软件找错误",漏掉"特定条件""记录""评价"三个要素。考点:定义的填空与要素识别;判断某段工作是否属于测试活动(如"只运行不记录、不评价"——不完全符合定义)。记忆四要素口诀:有条件、要运行、留记录、给评价。 **过渡**:这条定义讲的是"运行和评价",下一页的续讲,补上定义的另一半——测试到底在比较什么。 --- ### 【1.38】软件测试 IEEE/ISO29119 的定义 – 续(8 分钟) > **口播**:这一页是上一条定义的续,它回答了一个更本质的问题:测试在做比较的时候,到底拿什么跟什么比? > > 先看英文:Testing is comparing what the test item does with what it is expected to do. 翻译过来就是:测试就是把测试项实际做的事情,和它被期望做的事情进行比较。这句话是全章最该记住的一句话之一。它把测试的动作抽象成了一个"比较"。 > > 这个比较有两边。左边是"实际表现"——被测对象真实跑出来的行为,由运行环境、输入数据和代码逻辑决定,是客观、可观察的。右边是"期望表现"——需求规格、设计文档、接口契约、用户预期所规定它应该有的行为。测试要做的,就是设法让这两边对齐,然后找出它们的差。 > > 第二条表述更正式:分析某个软件项,以发现现存的和要求的条件之差别(即错误),并评价此软件项的特性。请注意这里的括号——"差别(即错误)"。也就是说,缺陷的定义可以直接从这句话推出来:所谓错误,就是实际的条件和要求的条件之间的差别。这一下就把"缺陷"的判定标准讲清楚了:有差别才有缺陷,没有要求就没有差别,也就无从判定缺陷。这就是为什么需求不清楚的项目没法测——你连比较的右边都画不出来。 > > 还有一个词不能漏:评价此软件项的特性。前面说找差别,这里说评特性。说明测试的输出有两类:一类是具体缺陷,一类是对特性水平的整体评价,比如性能达到什么量级、可靠性处于什么水平。它们对应两种报告:缺陷单和质量报告。 > > 最后强调一点:既然是比较,测试的严谨程度就取决于两块——测得够不够全(左边取样够不够),拿来比的标准对不对(右边尺子准不准)。这两条正是后面要展开的测试用例设计与测试需求分析。 **板书**:Testing=comparing what the test item does(实际)with what it is expected to do(期望)→ 分析软件项,发现现存的条件与要求的条件之差别(即错误),并评价此软件项的特性 → 缺陷=实际与要求的差别 → 输出:缺陷单+质量报告 **提问**:按照"测试是实际与期望的比较"这一定义,如果一个项目的需求文档写得很笼统,会直接导致什么后果? **预设回答**:①答"测试做不了"——方向对,要具体化:没有明确的"要求条件",就没有比较的右边,无法判定通过或失败,测试结论只能靠个人感觉。②答"那就按开发说的算"——纠偏:拿开发的口头说明当标准,等于让被测方给自己定标准,独立性丧失。③答"先测着,发现问题再说"——追问风险:漏掉的问题无从发现,也无法度量测试充分性。点评:这正是测试人员必须尽早参与需求评审的原因——把不可判定、二义性的需求在评审阶段挑出来。 **易错点 / 考点**:易错是把"缺陷"理解成"程序崩溃"这类明显故障,漏掉"与要求不符"这个判定核心(界面与设计稿差两像素、日志格式不符要求,同样是缺陷)。考点:由定义推导缺陷定义(简答);"没有需求文档能不能测"(判断/案例)。判断三步法:找到"要求"→ 找到"实际"→ 两者有差别即缺陷。 **过渡**:定义和比较都清楚了,最后我们回答一个务实的问题:投入这么多做测试,究竟换回了什么? --- ### 【1.39】软件测试的价值(8 分钟) > **口播**:这一页是本节前一部分的收口:软件测试的价值。课件给了四条,我一条一条讲,并且告诉你们每一条在实际项目里对应什么动作。 > > 第一条,全面评估产品质量,获得有关产品质量的全面、客观的信息。注意"全面"和"客观"这两个词。全面,是说测试不能只盯功能,还要看性能、兼容性、易用性、可靠性这些方面;客观,是说结论要有数据支撑,不能凭感觉说"我觉得差不多"。这一条对应的产出,是测试报告里的质量评估部分。 > > 第二条,发现问题,督促问题解决,提高产品质量。这一条强调"督促"。测试人员找到缺陷只是第一步,缺陷不修,测试的价值就等于零。所以测试工作里有一大块是缺陷跟踪:确认缺陷被受理、被修复、被验证关闭。这也是我们课程设计要求大家写缺陷单、跟踪缺陷状态的原因。 > > 第三条,持续提供质量反馈、及时揭示质量风险,有助于控制项目风险,提高构建的质量。这一条最容易被忽略,但项目经理最看重。软件测试像什么?像汽车仪表盘。它不能替你开车,但它告诉你油量、水温、车速,让你在抛锚之前做出决策。测试就是在每个版本、每个迭代,把"当前质量到了什么程度、哪些模块风险高"这个信息交给决策者。没有这条信息,项目管理者就是在盲开。 > > 第四条,通过缺陷分析,获得缺陷模式,有助于缺陷预防。这是最高层次的价值:把已经发生的缺陷归类、统计、找规律——比如某一类缺陷反复出现在某几个模块,或者集中在某个开发阶段——然后回头去改流程,让这一类缺陷不再产生。发现缺陷是治已病,缺陷预防是治未病。 > > 四条连起来看,测试的价值是层层递进的:给信息 → 促修复 → 控风险 → 防缺陷。这也正好呼应了我们前面讲的学科发展四个阶段,说明测试早就不只是"最后一道检验工序"了。 **板书**:软件测试的价值:①全面评估产品质量,获得全面、客观的质量信息 ②发现问题、督促解决、提高质量 ③持续质量反馈、及时揭示风险、控制项目风险、提高构建质量 ④缺陷分析→缺陷模式→缺陷预防 → 层层递进:给信息→促修复→控风险→防缺陷 **提问**:这四条价值里,哪一条最容易被团队忽略,但对项目风险控制最关键?为什么? **预设回答**:①答"第三条,持续提供质量反馈"——正确,追问:如果测试只在最后出一份报告会怎样?项目管理者在中间做不了决策,风险只能到最后一起爆。②答"第二条,督促问题解决"——可以讨论,补充:督促偏"事后",而第三条是"过程性"的,价值在于及时。③答"第一条,评估质量"——提醒:评估是基础,但如果没有持续反馈,评估结果来得太晚,只能"验尸"。点评:测试真正的价值是让风险早暴露,而不是让报告更漂亮。 **易错点 / 考点**:易错是把"测试的价值"说成"保证软件没有缺陷"——测试不保证无缺陷,它提供质量信息、降低风险。考点:四条价值的记忆与排序(简答);结合案例说明缺陷预防的价值。记忆口诀:评质量、促修复、控风险、防缺陷。 **【思政落点 2】**:讲国产游戏《血狮》(1997)——宣传声势远超其实际被验证的质量,交付后口碑崩塌;再对照波音星际客机因测试未做到端到端而出问题。两个方向一个共同点:把"没测到"当成了"没问题"。联系知识点:测试的价值在于四点,而缺陷预防是最高一层。落到价值观:测试是替用户把最后一道关,如实记录缺陷、不隐瞒不利结果,是从业者的职业底线与质量责任;家国情怀要靠过硬的质量来承载。 **过渡**:到这里,"测试是什么、为什么值得做"已经讲清楚了。带着这四条价值,我们从"为什么测"转向"怎么测",继续沿着教材的思路往下展开。