软件测试是描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。软件测试也从客观无关联的角度提供一个关于所测软件的一个概览,从而可以对软件所存在的风险有一个客观的认识。
【红色注释为2015 Feb 06加入】
软件测试的目的是验证产品是否符合用户需求,找到bug并不是它的目的,bug只是软件测试的产品。
软件测试所感兴趣的一些测试属性:
- 是否达到设计需求(包含显性需求跟隐性需求,比如一架洗衣机,需求说明上或许不会说明是否对音噪有要求)
- 对各种输入是否返回正确的值
- 响应时间是否可以接受
- 可用性
- 是否能在预想的环境中正确运行
通常情况,由于所测软件的小的组件、组成部分几乎是无穷的,而软件测试会采用可行的策略,在有限的时间跟资源里面,去选择性地测试。所以,软件测试是为了验证需求而对程序进行选择性针对性的测试。换句话说,软件测试是无法穷尽测试的。
戏言说DeadLine是第一生产力,在测试里最大的矛盾就是时间有限测试无限。所以如何选择性地测试是一个有意义的命题。通常会考虑需求里的核心模块,然后是客户经常用到的模块,总之,是从使用率的角度跟重要性的角度去考虑。所以测试前,要跟客户谈谈心。
在典型的瀑布开发流程中,软件测试在程序可以部分执行的时候就积极引入,比如单元测试。相对而言,在敏捷开发中,需求、编程跟测试通常都是并发进行的。
敏捷开发中,测试是一开始就介入的。其实平时的工作中,在分配任务时,不同的人交替着测试不同的模块,也是有一点敏捷的思想。虽然这样会导致开始的时候进度会慢一些,但是越早落后于进度,则说明你有更多的时间去赶上进度,并且随着时间的推进,这种方法的优势就体现出来,每个人都可以独立地去测试任何模块,并且不会因为惰性而错过一些潜在的bug。
缺陷跟错误(Defects & failures)
不是所有的软件缺陷都是由编码错误造成的。通常缺陷如果所处的位置越处于瀑布的顶端,则造成的损失越大,如需求中的分歧或者不清晰。所以越早发现缺陷越有利于缺陷的改正。需求中的分歧通常是指一些非功能性的需求,如程序的可测性,可维护性,易用性,性能以及安全性。
软件错误(failure, fault, bug)通常是由于程序员的失误造成软件的输出达不到预期要求。但是不是所有的程序错误都会造成软件输出与预期不一致。比如一段永远不会被调用的代码中含有程序错误。还有一种程序错误是运行环境改变造成的,比如你更换了硬件,操作系统等。
组合式输入
软件测试不可能把所有的可能的输入都测试一遍,所以进行有选择性的组合输入是很有必要的。这样可以使得用户用尽量少的测试用例去扩大测试覆盖度。比较常见的输入组合有边界值法,等价类法,决策表法,因果图等。
经济因素
从图表中也很容易看出缺陷或者是错误发现的越早,则修复它所花费的代价越小。反之,发现的越晚,则花费越大。
Cost to fix a defect |
Time detected |
|||||
Requirements |
Architecture |
Construction |
System test |
Post-release |
||
Time introduced |
Requirements |
1× |
3× |
5–10× |
10× |
10–100× |
Architecture |
– |
1× |
10× |
15× |
25–100× |
|
Construction |
– |
– |
1× |
10× |
10–25× |
测试人员
80年代以前,测试人员统称软件测试员(software tester),而之后才有了更加精细的分工。如测试经理,测试组长,测试设计师,测试员,自动化测试员,测试管理员。
历史阶段
- 1956年及以前:面向调试的测试
- 1957-1978:面向证明的测试
- 1979-1982:面向破坏的测试
- 1983-1987:面向评估的测试
- 1988- 现在:面向预防的测试
测试工件
软件测试工程中会产生的工件(产物)。
- 测试计划:测试说明书。
- 文档追踪表:记录测试过程中文档的变动。也做版本控制用
- 测试用例:根据需求而设计的测试一个具体事务的流程。包含了输入跟期望输出。复杂的测试用例可能会包含多个分支,根据不同的前提条件输入,得到不同的结果。
- 测试脚本:用自动化工具,根据测试用例创建的测试脚本,主要用来进行回归测试。
- 测试组:一组测试用例的集合。比如一个模块的测试用例。
- 测试数据
- 测试工具
- 居然忘了最重要的产物----bug