前 言
本书是一本面向软件开发者的软件测试教材,旨在从开发者的角度介绍软件测试理论、方法和实践。本书从测试基础概念出发,结合概率统计和图论基础建立软件测试理论分析框架;然后从多样性、故障假设、图分析三个方面构建开发者视角的系统性软件测试方法;最后介绍开发者测试实践的三部曲,即单元测试、集成测试和回归测试。同时,本书穿插讲解了部分智能化软件测试的最新研究成果。本书以软件测试理论为主线,阐述了开发者测试方法背后的内在联系和主要区别,以启发读者思考。全书共分为9章,第1~3章主要介绍软件测试理论,第4~6章介绍软件测试方法,第7~9章介绍软件测试实践。软件测试工具、测试案例和实践内容请参阅本书配套线上资源。本书主要面向具有一定编程基础的高年级本科生,教师可以根据自己的习惯编排教学次序。本书导读与教学建议如图1所示。
图1 本书导读与教学建议
第1章是快速入门,通过一个简单的三角形程序Triangle,介绍了软件测试的基本内容。1.1节介绍了多样性测试原则,包括随机测试、等价类测试和组合测试。1.2节介绍了故障假设测试原理,包括常见软件故障、边界故障假设和变异故障假设。1.3节介绍了图分析测试方法,包括图生成方法、图结构测试和图元素测试。通过学习本章,读者可以对软件测试常用方法有一个初步的了解。
第2章是基础概念。2.1节简要介绍了软件测试的基础概念,包括常用术语和测试理论框架,并基于理论框架重新审视了软件测试三大基本问题,包括测试生成、测试预言和测试终止问题,这三大问题贯穿全书,成为软件测试理论与方法的核心。本章为后续章节的深入学习奠定了基础。2.2节介绍了开发者测试常用工具, 包括静态测试工具、动态测试工具和DevOps相关工具。2.3节介绍了软件测试教材常用的三个待测程序示例,包括三角形程序 Triangle(输入三个边,输出三角形的类型)、日期程序NextDay(输入某一天的年月日,输出后一天的年月日)和均值方差程序 MeanVar(输入一组数字,计算其算术平均值 Mean 和方差 Var),这三个待测程序贯穿全书,但后续章节也会引入一些更加复杂的软件项目作为示例。
第3章是Bug理论基础,介绍了Bug的概念、分类和生命周期等。3.1节首先简要介绍了软件Bug的历史,名词概念的借鉴和延伸是工程技术领域的常用手段。本节还介绍了PIE模型,建立执行-感染-传播的基本分析框架,为Bug的准确定义和统一概念提供基础。3.2节深入分析了Bug的四大性质。首先介绍Bug的反向定义,即通过执行测试的动态分析和故障修复来定义Bug。这样的反向定义势必带来Bug的不确定性。对于任意程序和失效测试,存在不同的修复方法使得测试通过,从而可以派生出不同的Bug定义。本节还介绍Bug的非单调性定义,以及它给测试和修复带来的障碍。借鉴物理波的相长干涉和相消干涉概念,本节定义Bug间的干涉,并分析干涉给测试和调试带来的诸多挑战。在PIE模型的基础上,3.3节介绍了软件调试三部曲,即面向失效的Bug理解、面向错误的Bug定位、面向故障的Bug修复,从而衔接了开发者的测试与调试。本章可帮助读者更好地理解软件测试中Bug的本质和处理方法。
第4章是多样性测试。4.1节介绍了多样性测试理论与方法,包括随机测试、非均匀的随机测试、反馈引导距离极大化的自适应随机测试以及路径遍历引导性随机测试。等价类假设策略及其常用方案包括等价类划分策略、等价类划分和随机测试相结合的理论与方法。组合测试基本思路包括经典的t-强度组合测试准则、约束组合测试准则和可变强度组合测试准则,采用基于随机贪心的经典组合测试策略AETG等方法来完成测试生成优化。4.2节介绍开发者多样性测试,代码多样性测试要求程序在测试运行时实现对其程序结构的覆盖遍历;组合多样性测试通过分支组合覆盖测试实现分支条件的组合枚举和测试生成;行为多样性测试通过将路径行为特征提取和聚类抽样相结合,适应不同规模的开发者测试要求。本章为开发者提供了基础且丰富的测试方法选择。
第5章是故障假设测试,5.1节介绍了如何基于故障假设进行测试,以及故障假设测试的方法和技巧。5.2节首先介绍最常用的边界故障假设,包括输入边界、中间边界和输出边界;然后介绍了变异故障假设,包括变异分析的基本概念、变异算子选择方法及其相关理论性质,还介绍了变异分析在逻辑控制密集型的安全攸关软件中的应用,包括将程序逻辑抽象成布尔范式进行故障建模;最后介绍的逻辑故障假设集中考虑逻辑相关的故障假设。本章可帮助开发者掌握另外一种简单有效的软件测试策略。
第6章是图分析测试,介绍了图分析测试的基本概念、方法和技术。图被广泛应用于软件测试覆盖准则的定义和分析。6.1节介绍图测试理论方法和传统的结构化测试方法。图测试要求测试人员覆盖图的结构或元素,通过遍历图的特定部分完成测试目标。图测试理论方法可以来自任何软件抽象图,而不仅是控制流图、数据流图和事件流图。6.2节将传统的结构化测试方法分为三大类:L-路径测试、主路径测试和基本路径测试。其中,L-路径测试是根据图中路径长度进行简单延伸的策略;主路径测试主要针对循环带来L-路径测试的无限问题;基本路径测试通过引入独立路径的概念,覆盖最大独立路径集合,这些路径对应了这个线性空间的基向量。6.3节中的数据流测试关注变量的定义和使用元素测试形式,逻辑覆盖准则则以DC、CC、CoC、MCDC为代表,通过示例说明各个准则直接的强弱蕴涵关系,强调MCDC在工业应用中的价值。本章为读者提供了一种基于图论的软件测试方法。
第7章是单元测试,针对软件的最小可测试单元进行讨论。7.1节首先介绍单元测试的概述与最佳实践,特别强调了自动化测试;然后介绍模拟单元测试常用方法和单元测试评估方法,并阐述了全国大学生软件测试大赛的评估策略META。7.2节介绍自动化单元测试三部曲:执行、生成和演化。以JUnit为例阐述了单元测试执行框架,介绍了启发式搜索覆盖结合变异分析的生成方法、常用工具EvoSuite及其智能化改进思路,并结合大模型从修复的角度进行测试演化以满足质量保障
需求。
第8章是集成测试,检测组件之间交互的正确性,发现组件间可能存在的接口问题,提高整体软件系统的质量。8.1节首先介绍集成测试的目标与基本流程,以及常用策略和分析评估方法。8.2节介绍集成测试的核心内容:接口测试。首先介绍接口测试的常用方法与最佳实践,阐述接口测试的应用案例。然后介绍接口测试的常用自动化方法和工具:Postman用于API接口测试,Selenium用于Web接口测试,JMeter用于性能接口测试。最后强调了从自动化到智能化的结合。
第9章是回归测试,验证在修改或添加新功能后新系统能否仍然正常运行。9.1节首先介绍回归测试的目标与基本概念,回归测试的一个评估分析框架以及四个评估标准(完备性、准确性、效率和通用性),测试优先级以及APFD度量准则。9.2节介绍常用程序分析辅助手段程序切片,讨论如何基于程序切片实现回归测试,测试用例约简的理论与常用方法,并结合执行剖面聚类分析失效混合回归测试方法。9.3节介绍聚类抽样回归测试,记录特定的执行剖面进行聚类测试选择,包括动态聚类抽样策略ESBS、加权聚类抽样策略WAS和半监督聚类方法SSKM的成对约束策略。
本书适合作为软件工程、计算机科学与技术、信息安全等专业的教材,也可供从事软件研发和测试的工程师、研究人员参考。通过学习本书,读者可以掌握开发者视角的软件测试基本知识和实践技能,并且深入思考软件测试的理论和方法。期待本书能够成为广大读者的良师益友,帮助读者在软件测试领域取得更好的成果。
编者