文章目录
软件测试介绍
软件测试是提高软件质量的重要手段。
- 确认是否达到可用级别(用户需求)
- 关注系统的某一侧面的质量特性
即使是最好的测试,也无法达到100%的无错误。
测试分类:单元测试;集成测试;系统测试;验收测试等
静态测试&动态测试
- 静态测试通常是隐式的,如校对,而且当编程工具/文本编辑器检查源代码结构或编译器(预编译器)时,检查语法和数据流作为静态程序分析。
- 动态测试是描述代码动态行为的测试,它实际上使用给定的测试用例执行编程代码。
测试&调试
- 测试:发现是否存在错误
- 调试:识别错误根源,消除错误
黑盒测试&白盒测试
- 白盒测试:对程序内部代码结构的测试
- 黑盒测试:对程序外部表现出来的行为的测试
为什么软件测试比较困难?
- 穷举测试是不可行的
- 靠偶然测试没意义
- 基于样本的统计数据对软件测试意义不大
- 软件件行为在离散输入空间中差异巨大
- 大多数正确,少数点出错
- bug出现往往不符合特定概率分布
- 无统计分布规律可循
测试用例
测试用例:输入+执行条件+期望结果
测试用例是工程项目中的重要资产。
好的测试用例的特点:
- 最可能发现错误
- 不重复,不冗余
- 最有效
- 既不简单也不复杂
测试优先编程
在编写代码前编写测试用例
目的:
- 尽早测试,经常测试
- 先写测试会节省大量的调试时间
- 测试代码将更有成就感
步骤:
- 先写spec
- 再写符合spec的测试用例
- 写代码、执行测试、有问题再改、再执行测试用例,直到通过它
写测试用例,就是理解、修正、完善你的spec设计的过程。
**测试驱动开发(TDD)**是一个依赖于非常短的开发周期重复的开发过程:将需求转换为非常具体的测试用例,然后对软件进行改进,只通过新的测试。
单元测试
针对软件的最小单元模型开展测试,隔离各个模块,容易定位错误和调试。
单元测试通常被认为是编码步骤的辅助测试。(优先测试)
因为一个组件不是一个独立的程序,所以通常必须为每个单元测试开发驱动程序/存根。
- 驱动程序:一个“主程序”,它接受测试用例数据,将这些数据传递给组件(待测试),并打印相关的结果。
- 存根:用于替换待测试组件下属(调用)的模块。
使用JUnit进行自动化单元测试
JUnit是一个被广泛采用的Java单元测试框架。JUnit在测试驱动开发的开发中非常重要,它是单元测试框架家族之一,统称为xUnit。
JUnit单元测试写的方法前面有@Test标记。
单元测试方法通常包含对被测试模块的一个或多个调用,然后使用断言方法如 assertEquals
, assertTrue
, assertFalse
等断言方法检查结果。
使用JUnit进行单元测试的具体内容可以阅读我的另一篇博客:【Junit单元测试总结】http://t.csdn.cn/EmPpA
黑盒测试
黑盒测试介绍
黑盒测试是一种软件测试的方法,它可以检查应用程序的功能,而不需要窥视其内部结构或工作原理。
黑盒测试试图发现以下类型中的错误:
- 不正确或缺失的函数
- 接口错误
- 数据结构或外部数据库访问中的错误
- 行为或性能错误
- 初始化和终止错误
用于黑盒测试的测试用例是围绕规范和要求构建的,即应用程序应该做什么。
用尽可能少的测试用例,尽快运行,并尽可能大的发现程序的错误。
通过等价类划分来选择测试用例
基于等价类划分的测试:将被测函数的输入域划分为等价类,从等价类中导出测试用例。
针对每个输入数据需要满足的约束条件,划分等价类。
等价类:如果一组对象可以通过对称、传递和自反的关系连接起来,那么就存在一个等价类。
基于的假设:相似的输入,将会展示相似的行为。故可从每个等价类中选一个代表作为测试用例即可。
等效类别可根据指导方法进行定义,具体取决于要求的合法输入。
通过边界值分析来选择测试用例
大量的错误发生在输入域的“边界”而非中央。
边界值分析(BVA)已经发展成为一种测试技术,导致了对边界值的测试用例的选择。
边界值分析方法是对等价类划分方法的补充。
- 程序员经常犯一些大小差1的错误
- 某些边界值是“特殊情况”,需要特殊处理
- 程序的行为在边界的地方可能发生“突变”
在等价类划分时,将边界作为等价类之一加入考虑。
覆盖等价类分区的两个极端:
-
笛卡尔积:全覆盖
测试完备,但用例数量多,测试代价高
-
覆盖每个取值:最少1次即可
测试用例少,代价低,但测试覆盖度未必高。
我们通常需要在两个极端间达成妥协。
白盒测试
与黑盒测试不同,黑盒测试完全从函数的spec导出测试用例,不考虑函数内部实现;而 白盒测试要考虑内部实现细节。
一般根据程序执行路径设计测试用例,而且白盒测试一般较早执行。
独立/基本路径测试:对程序所有执行路径进行等价类分,找出有代表性的最简单的路径(例如循环只需执行1次),设计测试用例使每一条基本路径被至少覆盖1次。
测试覆盖度
测试应考虑到程序内部逻辑的测试用例的代码覆盖范围。
代码覆盖是一种用于描述特定测试套件运行时程序源代码执行程度的度量。(已有的测试用例有多大程度覆盖了被测程序)
- 代码覆盖度越低,测试越不充分
- 代码覆盖度越高,需要更多测试用例,测试代价高
判断测试套件的一种方法是询问它对程序的操作程度。这个概念被称为覆盖范围。
- 函数覆盖,语句覆盖,分支覆盖,条件覆盖,路径覆盖
- 测试效果:路径覆盖 > 分支覆盖 > 语句覆盖
- 测试难度:路径覆盖 > 分支覆盖 > 语句覆盖
自动测试和回归测试
自动测试
手工测试的代价太高,最好达到完全的自动化,即自动调用被测函数、自动判定测试结果、自动计算覆盖度。
只是“测试用例的自动执行”,并非“自动生成测试用例”。
回归测试
一旦程序被修改,重新执行之前的所有测试。
一旦发现bug,要马上写一个可重现该bug的测试用例,并将其加入测试库
记录测试策略
测试策略(根据什么来选择测试用例)非常重要,需要在程序中显式记录下来。
目的:在代码评审过程中,其他人可以理解你的测试,并评判你的测试是否足够充分。