软件测试与评审是软件质量保证的主要手段之一,也是在将软件交付给客户之前所必须完成的步骤。目前,软件的正确性证明尚未得到根本的解决,软件测试与评审仍是发现软件错误(缺陷)的主要手段。软件测试的目的就是希望能以最少的人力和时间发现潜在的各种错误和缺陷。
明确“错误”(error)和“缺陷”(fault)的概念。根据IEEE的定义,“错误”主要针对软件开发过程,“缺陷”主要针对软件产品。软件开发人员在软件开发过程(主要是分析、设计和编码过程)中所出现的“错误”是导致软件产品“缺陷”的原因,反过来说,“缺陷”是“错误”的结果和表现形式。
测试原则
- 应尽早、不断地进行测试。
- 测试工作应该避免由原开发软件的人或小组承担
- 在设计测试方案时,不仅要确定输入数据,而且要根据系统功能确定预期输出结果。
- 在设计测试用例时,不仅要设计有效、合理的数据,也要包含不合理、失效的数据
- 在测试程序时,不仅要检验程序是否做了该做的事,还要检验程序是否做了不该做的事
- 严格按照测试计划来进行,避免测试的随意性。
- 妥善保存测试计划、测试用例,作为软件文档的组成部分,为维护提供方便。
- 测试例子都是精心设计出来的,可以为重新测试或追加测试提供方便
- 修改后应进行回归测试
- 尚未发现的错误数量与该程序已发现错误数成正比
语句覆盖、判定覆盖、条件覆盖、条件判定覆盖、条件组合覆盖、路径覆盖等,发现错误的能力呈由弱至强的变化。
语句覆盖每条语句至少执行一次
判定覆盖每个判定的每个分支至少执行一次
条件覆盖每个判定的每个条件应取到各种可能的值
判定/条件覆盖同时满足判定覆盖条件覆盖
条件组合覆盖每个判定中各条件的每一种组合至少出现一次
路径覆盖使程序中每一条可能的路径至少执行一次
测试过程
- 制订测试计划
- 编制测试大纲
- 根据测试大纲设计和生成测试用例,产生测试设计说明文档
- 实施测试
- 生成测试报告
具体实现算法细节和系统内部结构的相关情况为根据可分黑盒测试、白盒测试和灰盒测试。
黑盒测试:
- 定义:黑盒测试也称为功能测试或数据驱动测试。测试者在测试过程中不涉及软件的内部结构和代码,仅关注软件的输入和输出。
- 特点:
- 测试者不需要了解软件内部的工作原理和结构。
- 测试用例的设计基于软件的功能需求。
- 通过输入模拟数据,观察输出结果是否符合预期。
- 优点:
- 可以发现软件的外部功能问题。
- 有利于测试软件的用户界面。
- 不需要编程技能。
- 适用场景:适用于功能需求明确的软件,尤其是用户界面和用户体验测试。
- 黑盒测试用例:将程序看做一个黑盒子,只知道输入输出,不知道内部代码,由此设计出测试用
例,分为下面几类:
(1)等价类划分:把所有的数据按照某种特性进行归类,而后在每类的数据里选取一个即可。等价类测试用例的设计原则:设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止;计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。
(2)边界值划分:将每类的边界值作为测试用例,边界值一般为范围的两端值以及在此范围之外的与此范围间隔最小的两个值,如年龄范围为0-150,边界值为0,150,-1,151四个。
(3)错误推测:没有固定的方法,凭经验而言,来推测有可能产生问题的地方,作为测试用例进行测试。
(4)因果图:由一个结果来反推原因的方法,具体结果具体分析,没有固定方法。白盒测试:
- 定义:白盒测试也称为结构测试或逻辑驱动测试。测试者需要了解软件的内部逻辑和结构,包括代码、数据结构、算法等。
- 特点:
- 测试者需要具备软件工程和编程知识。
- 通过分析软件内部结构,设计测试用例以覆盖所有代码路径。
- 检查代码中的逻辑错误、性能问题和边界条件。
- 优点:
- 可以发现软件内部实现问题。
- 有助于提高软件的质量和性能。
- 可以确保软件的逻辑正确性。
- 适用场景:适用于需要深入了解软件内部实现的测试,通常由开发人员或具有编程技能的测试人员执行。
白盒测试用例:知道程序的代码逻辑,按照程序的代码语句,来设计覆盖代码分支的测试用例,
覆盖级别从低至高分为下面几种:
(1)语句覆盖SC:逻辑代码中的所有语句都要被执行一遍,覆盖层级最低,因为执行了所有的
语句,不代表执行了所有的条件判断。
(2)判定覆盖DC:逻辑代码中的所有判断语句的条件的真假分支都要覆盖一次。
(3)条件覆盖CC:针对每一个判断条件内的每一个独立条件都要执行一遍真和假。
(4)条件判定组合覆盖CDC:同时满足判定覆盖和条件覆盖。
(5)路径覆盖:逻辑代码中的所有可行路径都覆盖了,覆盖层级最高。
灰盒测试:
- 定义:灰盒测试结合了黑盒测试和白盒测试。测试者在测试过程中了解部分软件的内部结构和代码,但不是完全了解。
- 特点:
- 在设计测试用例时,既考虑软件的功能需求,也考虑部分实现细节。
- 结合了功能测试和结构测试的优点,可以在较少的内部知识下进行更全面的测试。
- 优点:
- 可以在不完全了解内部结构的情况下,设计出更具针对性的测试用例。
- 结合了内外部测试的优点,测试更加全面。
- 适用场景:适用于在功能测试过程中需要对特定实现细节进行验证的情况,或者在白盒测试中遇到无法完全覆盖的情况时使用。
传统软件的测试策略
有效的软件测试实际上分为 4 步进行,即单元测试、集成测试.系统测试。
单元测试(unit testing)
单元测试也称为模块测试,测试的对象是可独立编译或汇编的程序模块、软件构件或面向对象软件中的类(统称为模块),其目的是检查每个模块能否正确地实现设计说明中的功能、性能、接口和其他设计约束等条件,发现模块内可能存在的各种差错。
1. 阶段与执行者
- 阶段:贯穿编程阶段,与代码开发同步进行。
- 执行者:由程序员(开发者)自主完成,属于白盒测试范畴(需了解代码逻辑)。
2. 核心目标
- 验证模块是否符合详细设计说明书的功能、算法要求。
- 发现两类错误:
- 编程错误:如语法错误、逻辑漏洞(如循环条件错误)。
- 设计错误:如算法不合理、接口定义错误。
3. 计划制定时机
- 在详细设计阶段制定单元测试计划,确保测试覆盖设计细节。
单元测试的五大测试重点
测试维度 具体关注点 示例 1. 模块接口 - 参数传递的正确性(类型、数量、顺序)
- 返回值的合理性
- 输入输出格式验证函数接收整数参数却传入字符串,导致程序崩溃;API 接口返回数据格式错误。 2. 局部数据结构 - 变量初始化、作用域正确性
- 数据类型匹配性
- 数据溢出 / 下溢风险数组越界访问(如声明长度为 5 的数组,写入第 6 个元素);未初始化变量导致脏数据。 3. 重要执行通路 - 正常逻辑路径覆盖
- 异常分支覆盖(如条件判断的真 / 假分支)
- 循环边界测试分支语句中某条件分支未被测试;循环仅执行一次就退出,未覆盖多次迭代场景。 4. 出错处理通路 - 错误提示的准确性
- 异常恢复机制有效性
- 资源释放合理性文件读取失败时未捕获异常,程序直接崩溃;数据库连接未关闭导致资源泄漏。 5. 边界条件 - 输入数据的边界值(如最小值、最大值、空值)
- 数据结构极限状态(如空列表)整数取值范围边界(如 int 类型的 ±2147483647);搜索空字符串时程序报错。 测试辅助模块:驱动模块与桩模块
测试一个模块时,可能需要为该模块编写一个驱动模块和若干个桩模块。驱动模块用来调用被测模块,它接收测试者提供的测试数据,并把这些数据传送给被测模块,然后从被测模块接收测试结果,并以某种可见的方式将测试结果返回给测试人员;桩模块用来模拟被测模块所调用的子模块,它接受被测模块的调用,检验调用参数,并以尽可能简单的操作模拟被调用的子程序模块功能,把结果送回被测模块。顶层模块测试时不需要驱动模块,底层模块测试时不要桩模块。
1. 驱动模块(Driver)