三. 软件工程 --- 单元测试

1. 单元测试(Unit Testing):

是对软件中的最小可测试单元进行检查和验证。单元是构造软件系统的基础,只有使每个单元都得到足够的测试,系统的质量才能有可靠的保证,即单元测试是构筑产品质量的基石。

 

不能把单元测试任务堆积到系统测试阶段,否则大量故障堆积在项目中后期,项目后10%的工作占用了项目90%的时间;而且故障难以定位,开发和测试人员疲于奔命。

2. 单元测试的优点:

验证代码、设计更好、文档化行为、具有回归性

3. 单元测试的内容:

  • 模块接口:对通过所有被测模块的数据流进行测试。
  • 局部数据结构:检查模块中的数据结构是否正确的定义和使用
  • 边界条件:检查数据流或控制流中条件或数据处于边界时的出错可能性
  • 独立路径:  检查由于计算错误、判定错误、控制流错误导致的程序错误。
  • 出错处理:检查可能引发错误处理的路径以及进行错误处理的路径

4. 单元测试的原则:

  • 快速:
  • 独立:某个测试不应为下一个测试设定条件。当测试相互依赖时,一个没通过就会导致一连串的失败,难以定位问题。
  • 可重复:单元测试应该是可以重复执行的,并且结果是可以重现的。
  • 自我验证:单元测试应该有布尔输出,无论是通过还是失败,不应该查看日志文件或手工对比不同的文本文件来确认测试是否通过。
  • 及时:及时编写单元测试代码,最好在开发实际的单元代码前完成单元测试

5. 单元测试过程:

 

6. 单元测试的质量衡量:

①. 测试通过率:在测试过程中执行通过的测试用例所占比例,单元测试通常要求测试用例通过率达到100%

②. 测试覆盖率:用来度量测试完整性的一个手段,通过覆盖率数据,可以了解测试是否充分以及弱点在哪里。代码覆盖率是单元测试的一个衡量标准,但也不能一味地去追求覆盖率。

  • 语句覆盖
  • 判定覆盖
  • 条件覆盖
  • 判定条件覆盖
  • 条件组合覆盖
  • 路径覆盖 

7. 单元测试类型:

①. 静态测试:通过人工分析或程序正确性证明的方式来确认程序正确性

②. 动态测试:通过动态分析和程序测试等方法来检查和确认程序是否有问题

8. 测试用例:

为了一个特定的目标而设计的一组测试输入、执行条件和预期结果,目的是测试某个程序路径是否正确或何时程序是否满足某个特定需求。

8.1. 测试用例的优点:

  • 降低软件测试成本
  • 保证测试工作质量:
  • 评估和检测测试效果
  • 帮助完善软件的质量
  • 可以用于衡量测试人员的工作量、进度和效率

8.2. 测试用例的内容:

  • 测试用例值:完成被测软件的某个执行所需的输入值
  • 预期结果:当且仅当程序满足其预期行为,执行测试时产生的结果
  • 前缀值:将软件置于合适的状态来接受测试用例值的任何必要输入
  • 后缀值:测试用例值被发送后,需要被发送到软件的任何输入
    • 验证值:查看测试用例值结果所要用到的值
    • 结束命令:终止程序或返回到稳定状态所要用到的值
示例:测试移动电话软件

- 测试用例值:电话号码

- 期望结果:接通(或未接通)

- 前缀值:电话开启并进入拨号界面

- 后缀值:按下“呼叫”或“取消”按钮

测试集是指测试用例值的集合。

8.3. 测试用例需考虑的因素:

  • 具有代表性和典型性
  • 寻求系统设计和功能设计的弱点
  • 既有正确输入也有错误或异常输入
  • 考虑用户实际的诸多使用场景

 

9. 单元测试设计方式:

9.1. 黑盒测试(Black Box Testing):

又称功能测试,它将测试对象看做一个黑盒子,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。

 9.1.1 等价类划分:

将输入域划分成尽可能少的若干子域,在划分中要求每个子域两两互不相交,每个子域称为一个等价类。

  • 同一输入域的等价类划分可能不唯一
  • 用同个等价类中的任何输入对软件进行测试时,软件都会输出相同结果。因此只需从每一个等价类中选取一个输入作为测试用例,就可以构成软件一个完整的测试用例集。
  • 对于相同的等价类划分,不同测试人员选取的测试用例集可能是不同的

a. 等价类类型:

  • 有效等价类:是对规格说明有意义、合理的输入数据构成的集合,能够检验程序是否实现了规格说明中预先规定的功能和性能。
  • 无效等价类:是对规格说明无意义、不合理的输入数据构成的集合,以检查程序是否具有一定的容错性。

设计测试用例时需同时考虑这两种等价类。

示例:

①. 取值范围:

程序的输入参数x是小于100大于10的整数,则

  • 1个有效等价类:10 < x < 100
  • 2个无效等价类:x <= 10 和 x >= 100

②. 字符串规则:

姓名是长度不超过20的飞控字符串,且只由字母组成,数字和其他字符都是非法的,则

  • 1个有效等价类:满足上述所有条件得字符串
  • 3个无效等价类:
    • 空字符串
    • 长度超过20的字符串
    • 包含了数字或其他字符的字符串(长度不超过20)

③. 变量:

假设某程序的输入是一个整数数组int oper[3],则

  • 1个有效等价类:所有合法的数组,如{-10, 20}
  • 2个无效等价类:
    • 空数组
    • 所有大于期望长度的数组

b. 等价类组合

测试用例生成:测试对象通常有多个输入参数,如何对这些参数等价类进行组合测试,来保证等价类的覆盖率,是测试用例设计首先需要考虑的问题。

  • 所有有效等价类的代表值都集成到测试用例中,即覆盖有效等价类的所有组合。任何一个组合都将设计成一个有效地测试用例,也称正面测试用例。
  • 无效等价类的代表值只能和其他有效等价类的代表值(随意)进行组合。因此,每个无效等价类将产生一个额外的无效测试用例,也成负面测试用例。

示例:判断三角形类型

输入三个整数a, b, c,分别作为三角形的三条边,现通过一个程序判断这三条边构成的三角形类型,包括等边三角形、等腰三角形、一般三角形(特殊的还包括直角三角形)以及构不成三角形。

现在要求输入的三个整数a,b,c,必须满足以下条件:

条件1: 1 <= a <= 100

条件2:    1 <= b <= 100

条件3:  1 <= c <= 100

条件4:  a < b + c

条件5:  b < a + c

条件6:  c < a + b

等价类划分:按输入取值划分{0, >0, <0} ; 按输出的几何特性划分{等腰且非等边三角形,等边三角形,一般三角形,非三角形}

对于三角形判断这个程序,从输出域的角度划分是最简单的:

 

 

9.1.2 边界值分析:

边界值分析是对输入或输出的边界值进行测试的一种方法,通常作为等价类划分法的补充,这种情况下的测试用例来自等价类的边界。

选取正好等于、刚大于或刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值。

边界值分析法是基于可靠性理论中称为“单故障”的假设,即有两个或两个以上故障同时出现而导致失效的情况很少。

示例:

 

 

 

9.1.3 健壮性测试:

是作为边界值分析的一个简单的扩充,除了对变量的边界值分析取值外,还要增加一个略大于最大值和略小于最小值的取值,检查超过极限值时系统的情况。

9.1.4 错误推测法:

是人们根据经验或直觉推测程序中可能存在的各种错误,列举出来从而有针对性地编写检查这些错误的测试用例的方法。

9.2. 白盒测试(White Box Testing):

又称结构测试,它把测试对象看做一个透明盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。

 

10. 编写单元测试的方法:

被测模块可能调用下层模块,本身被上层模块调用。

 

单元测试得保证被测模块是独立的,且构成可运行的程序。可以通过编写驱动模块来调用被测模块且判断被测模块的返回值是否与预期的对应,被测模块所需的下层模块可以通过编写桩模块来模拟。

Mock方法:

Mock测试是在测试过程中对于某些不易构造或者不容易获取的对象,用一个虚拟的对象(即Mock对象)来创建以便测试的方法。

①. Mock测试适合的场景:

  • 真实对象具有不可确定的行为(产生不可预测的结果)
  • 真实对象很难被创建(如具体的Web容器)
  • 真实对象的某些行为很难触发(如网络错误)
  • 真实情况令程序的运行速度很慢
  • 真实对象有用户界面
  • 测试需要询问真实对象它是如何被调用的
  • 真实对象实际上并不存在

11. 单元测试的工具:

①. xUnit通常适用于以下场景的测试:

  • 单个函数、一个类或者几个功能相关类的测试
  • 尤其适用于纯函数测试或者接口级别的测试

②. xUnit无法适用于复杂场景的测试:

  • 被测对象依赖关系复杂,甚至无法简单创建出这个对象
  • 对于一些失败场景的测试
  • 被测对象中涉及多线程合作
  • 被测对象通过消息与外界交互的场景

 

 

posted on 2023-07-02 20:57  可乐+  阅读(223)  评论(0编辑  收藏  举报