HIT 软件构造第二章总结

Testing and Test-First Programming(测试和测试优先编程)

一、软件测试

1.1 软件测试是提高软件质量的重要手段

  1. 软件测试是一个以找bug为目的的过程,并且检验该软件是否达到可用级别(用户需求)。
  2. 软件测试只关注某一侧面的特性,比如该软件主要执行的功能是什么,我们就要集中精力在这个主要功能上,让它尽可能避免出错。
  3. 软件测试是提高软件质量的重要手段,但并非唯一、决定性手段,软件测试只能提高正确性。

1.2 即使是最好的测试,也可能出错

残留缺陷率(defects/kloc) 来进行评判: 每一千行代码出现的错误个数 。其评判标准如下:

  1. 1-10 defects/kloc: Typical industry software.(典型行业软件)
  2. 0.1-1 defects/kloc: High-quality validation. The Java libraries might achieve this level of correctness.
  3. 0.01-0.1 defects/kloc: The very best, safety-critical validation. NASA and companies like Praxis can achieve this level.
    即使是再好的测试,也不能达到百分之一百无错误,也无法证明系统里不存在错误。

1.3 什么是好的测试

  1. 能发现错误
  2. 不冗余(不会重复去测试一些已经测试过的数据或者同类的数据)
  3. 重点关注软件的最佳特性
  4. 别太复杂也别太简单

1.4 测试的种类

  1. 单元测试(unit testing) : 通常是指验证测试特定代码部分的功能,在功能层面。对每个类、或者是每个类中的方法进行测试。
    单元测试的层面为:function / class
    单元测试的工具为:JUnit

  2. 集成测试(integration testing): 针对若干个类或若干个包或若干个组件。两个或多个类、包、组件、子系统的组合执行
    集成测试的层面为:classes / packages / components / subsystems

  3. 系统测试(system testing)测试完全集成的系统,以验证系统是否满足其要求,从而在最终配置中执行软件。 也指在不同的系统上测试,比如程序员一般是开发端,然后开发好后,能在开发端正常运行,但不一定能在用户端正常运行,此时就要在用户端进行一波测试。系统测试的层面为:system

  4. 验收测试:在上述三者之后
    在这里插入图片描述

  5. 回归测试
    在这里插入图片描述

  6. 静态测试(Static testing): 在没有实际执行程序的情况下执行。Reviews, walkthroughs, or inspections(评审,走查,检查)属于静态测试。静态测试通常是隐式的,而且当编程工具/文本编辑器检查源代码结构或编译器(预编译器)时,检查语法和数据流作为静态程序分析

  7. 动态测试(Dynamic testing): 描述了动态行为的测试代码,它实际上执行具有给定集合的编程代码的测试用例。动态测试可以在程序100%完成之前开始,以测试特定的特定部分,并应用于离散函数或模块。

1.5 测试与调试

  • 测试: 发现是否存在错误
  • 调试: 识别错误根源,消除错误。
  • 先有测试,发现存在错误了,然后才能去找错误根源并且消除错误。

1.6 黑盒测试与白盒测试

  • 白盒测试: 对程序内部代码结构的测试

  • 黑盒测试: 关注程序外部功能。对程序外部表现出来的行为的测试

1.7 测试难点所在

  1. 不可能暴力穷举完所以可能的测试案例
  2. 单纯靠偶然测试是没有意义的
  3. 基于样本的统计数据对软件测试意义不大。比如工厂里测试一批产品合不合格,那就抽样检测,样品中不合格率小于百分之一则该批产品合格,但这对软件测试是没有意义的。
  4. 对于离散的输入,软件行为差异巨大。 大多数正确,少数点出错。
  5. 无统计分布规律可循

二、测试用例

  • 测试用例 = 输入 + 执行条件 + 期望输出
  • 好的测试用例
    1. 最可能发现错误
    2. 不重复、不冗余
    3. 最有效
    4. 既不简单也不复杂

三、测试优先编程(编写代码前编写测试)

3.1 过程

  1. 先写规范(spec)
  2. 再写符合spec的测试用例
  3. 写代码、执行测试、有问题再改、再执行测试用例,直到通过它

3.2 测试驱动开发(TDD)

测试驱动开发(TDD)是一个开发过程,依赖于非常短的开发周期的重复:需求被转化为非常具体的测试用例,然后软件经过改进以通过新的测试。

因此,TDD反对的是允许添加未经证明满足需求的软件的软件开发。即没有被事先证明正确的软件不应该被加入

四、黑盒测试

  • 用于检查代码的功能
  • 不关心内部实现细节

4.1 黑盒测试发现的错误种类

  1. 不正确或者缺失的功能
  2. 接口错误
  3. 数据类型的错误或者外部数据库中访问的错误
  4. 行为或性能错误
  5. 初始化和终止时的错误

4.2 黑盒测试的检测样例

黑盒测试的检测样例应该基于规约、要求和外部描述。但是黑盒测试的用例无法覆盖所有的功能要求,用尽可能少的测试用例,尽快运行,并尽可能大的发现程序的错误。

4.3 测试用例的等价类划分

4.3.1 测试用例的等价类划分的概念

  • 基于等价类划分的测试: 将被测函数的输入域划分为等价类,从等价类中导出测试用例。
  • 等价类: 代表着对输入约束加以满足/违反有效/无效数据的集合。包括无效等价类和有效等价类

4.3.2 为什么用等价类

  • 基于的假设:相似的输入,将会展示相似的行为。所以可以从每个等价类中选一个代表作为测试用例即可。从而可以降低测试用例数量。
  • 在这里插入图片描述

4.3.3 等价类划分例子

在这里插入图片描述

  • 需要考虑输入数据的特殊情况:a or b is 0, 1, or -1
  • 考虑输入的上限:很大的数是否仍正确?所以我们肯定也应该尝试非常大的整数,大于最大的整数
  • 对于其他一些例子,需要考虑边界检测(大量的错误发生在输入域的“边
    界”而非中央)
    在这里插入图片描述
  • 测试样例的选择:选择每个方框中的一例作为代表
    在这里插入图片描述

4.4 测试用例的覆盖

由于输入通常是多维的,每一个维度都具有等价类划分,由此引出两种关于测试用例的选取。两种方法各有优劣。

  1. 笛卡尔乘积法(全覆盖)
    概念: 多个划分维度上的多个取值,要组合起来,每个组合都要有一个用例
    例子: 假如有两个输入,第一个输入对应的等价类划分为{1,2,其它值},第二个输入对应的等价类划分为{5,6,其它值},则测试用例至少选3*3种,有(1,5),(1,6),(1,其它值),(2,5),(2,6),…,(其它值,其它值)。
    优缺点 : 这种方法的优点是覆盖完备,缺点是测试用例多,代价大。
    注意: 虽然看起来是全排列,但是可能存在组合后互相矛盾的情况。
  2. 部分覆盖
    概念 : 每个维度的每个取值至少被1个测试用例覆盖一次即可
    例子: 再以上例为例,只要我们选了(1,任意值)的测试用例,则第一个输入的第一个维度就考虑结束了,不必还要继续选(1,5)或(1,6)等等。
    优缺点 : 这种方法优点测试用例少,代价小,缺点是覆盖度未必高。

五、白盒测试

  • 根据程序执行路径设计测试用例
  • 白盒测试一般较早执行
    在这里插入图片描述
  • 独立/基本路径测试:对程序所有执行路径进行等价类划分,找出有代表性的最简单的路径(例如循环只需执行1次),设计测试用例使每一条基本路径被至少覆盖1次

六、测试覆盖

6.1 代码覆盖度

  • 概念: 已有的测试用例有多大程度覆盖了被测程序(通常用百分比衡量覆盖度)。
  • 代码覆盖度越低,测试越不充分但要做到很高的代码覆盖度,需要更多的测试用例,测试代价高
  • 各种覆盖:
    1. 函数覆盖
    2. 语句覆盖
    3. 分支覆盖
    4. 条件覆盖
    5. 路径覆盖:覆盖程序中的每条路径(路径数量巨大,难以全部覆盖)
  • 测试效果: 路径覆盖>分支覆盖/条件覆盖>语句覆盖>函数覆盖
  • 测试难度: 路径覆盖>分支覆盖>语句覆盖

6.2 自动/回归测试

  • 自动测试: 自动调用被测函数、自动判定测试结果、自动计算覆盖度
  • 回归测试: 一旦程序被修改,重新执行之前所有的测试

6.3 记录测试策略

  • 目的:在代码评审过程中,其他人可以理解你的测试,并评判你的测试是否足够充分
    在这里插入图片描述

七、总结

  • 学习内容:
    • 测试优先编程。在编写代码之前,请先编写测试。
    • 为系统地选择测试用例的划分和边界。
    • 白盒测试和声明覆盖范围,以填写一个测试套件。
    • 单元-尽可能地测试每个模块,进行隔离。
    • 自动回归测试,以防止bug返回。
    • 防止错误。测试是在代码中查找bug,测试优先编程是在引入它们之后尽早找到它们。
  • 认识到了测试的重要性,学会了利用等价类划分来思考和编写覆盖度高的测试用例,并且学习了基于junit框架的自动化单元测试,对编程的规范性有很大提升。
  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值