软件构造复习第二章 软件测试与测试优先的编程

Software Testing 软件测试

软件测试是什么

软件测试是提高软件质量的重要手段,通过软件测试,来确认软件是否达到可用级别(用户需求),软件测试关注系统的某一侧面的质量特性。
即使是最好的测试,也无法达到100%的无错误
下图为一些典型的残留缺陷率(kloc:1000lines of code)
残留缺陷率
测试跟其他活动的目标相反:破坏、证错、“负能量
再好的测试也无法证明系统里不存在错误
一个好的测试应该具有以下特点

  • 能发现错误
  • 不冗余
  • 具有最佳特性(best of breed)
  • 别太复杂也别太简单

软件测试的分类

测试可以为分

  • 单元测试: 测试代码中特定节的方法(function)
  • 集成测试: 测试多个类,包,组件,子系统组成的程序
  • 系统测试: 测试完全集成的系统是否满足需求
  • 回归测试: 程序出现bug后,重新测试

也可以分为

  • 静态测试 Static testing
    静态测试通常为编程工具检查源程序结构,编译器检查语法,数据流等等
    Reviews, walkthroughs, or inspections are referred to as static testing.
  • 动态测试 Dynamic testing、
    动态测试通常测试程序的动态行为,也就是程序在特定测试用例下的运行情况,可以在程序完成之前就可以开始对特定节的动态测试。
    Typical techniques for this are either using stubs/drivers or execution from a debugger environment.

Testing vs. Debugging

测试Testing是在发现错误,而调试Debugging是更正错误
通过测试发现错误,调试消除错误,再次测试来确保程序没有错误
图示如下
TEST VS DEBUG

Test Case 测试用例

test case = {test inputs + execution conditions+ expected results}
测试用例:输入+执行条件+期望结果
好的测试用例所具有的特点类似于好的测试

  • 最可能发现错误
  • 不重复不冗余
  • 最有效
  • 既不简单也不复杂

Test-First Programming 测试优先的编程

也即 在写代码之前先写好测试
Write the tests before you write the code.
这样的编程模式过程通常为

  • 先写spec(specification 规约)
  • 依据spec,写符合规约的测试用例
  • 写代码、执行测试、有问题再改、再执行测试用例,直到通过它

好处是可以通过写测试用例,理解、修正、完善spec设计。也可以较早的发现spec中可能存在的漏洞。可以节省大量的调试时间

Unit Testing and Automated Unit Testing with Junit 单元测试以及Junit

单元测试: 针对软件的最小单元模型开展测试,隔离各个模块,容易定位错误和调试
可以通过Junit来对程序进行测试
Junit 官网:Junit
Junit 百度百科:Junit_百度百科
一个Junit unit test 以@Test声明开始,通过assertion 方法来测试
下图为示例,测试Math.max()
Junit

Black-box Testing

黑盒测试 用于检查代码的功能,不关心内部实现细节检查程序是否符合规约,用尽可能少的测试用例,尽快运行,并尽可能大的发现程序的错误、

1)Choosing Test Cases by Partitioning

Equivalence Partitioning 等价类划分
基于等价类划分的测试:将被测函数的输入域划分为等价类, 从等价类中导出测试用例,针对每个输入数据需要满足的约束条件,划分等价类
等价类需要满足对称、传递、自反的性质
每个等价类代表着对输入约束加以满足/违反的有效 /无效数据的集合
基于的假设:相似的输入,将会展示相似的行为。故可从每个等价类中选一个代表作为 测试用例,从而降低测试用例数量。
如:

  1. 输入数据限定了数值范围,则有一个有效等价类,两个无效等价类;
  2. 输入数据指明了特定的值,则有一个有效等价类,一个无效等价类
  3. 输入数据确定了一组数值,则有一个有效等价类,一个无效等价类
  4. 输入数据是布尔类型,则有一个有效等价类,一个无效等价类

示例如下
BigInteger.multiply() 该方法返回a*b的值,a和b的值可以是任意的整数
a的等价类可划分为: 0,1,-1,小的正整数,大的正整数,小的负整数,大的负整数,b也如此,
故整个测试可划分为 7*7=49个等价类。
example

2)Include Boundaries in the Partition

大量的错误发生在输入域的边界而非中央,这其中的原因是

  • 程序员经常犯一些大小差1的错误
  • 某些边界值是“特殊情况”,需要特殊处理
  • 程序的行为在边界的地方可能发生 “突变”

边界值分析方法是对等价类划分方法的补充,在等价类划分时,将边界作为等价类之一加入考虑
例如,某个方法的参数为n
设计5个参数用例 n的最小值,略高于最小值,正常值,略低于最大值,最大值
还可以增加 略高于最大值和略低于最小值
如果n介于18-56
则可选取17 18 19 55 56 57

两种极端等价类的划分

  1. 笛卡尔积:全覆盖 多个划分维度上的多个取值,要组合起来,每个组合都要有一个用例,不可能出现的情况不用考虑
  2. 每个维度的每个取值至少被1个测试用例覆盖一 次即可
    如max() max : int × int → int.

如下图的例子
example

  1. 笛卡尔积 共包含 3*5*5 = 75种情况(包含不可能出现的情况)
  2. 覆盖每个取值:最少1次即可 则最少只需要5种测试用例即可
    {a, b} : {0, 0} {-1, 1} {1, -1} {min, max} { max, min}

笛卡尔积:测试完备,但用例数量多,测试代价高
覆盖每个取值:测试用例少,代价低,但测试覆盖度未必高。

White-box Testing

黑盒测试完全从函数spec导出测试用例,不考虑函数内部实现,而白盒测试要考虑内部实现细节根据程序执行路径设计测试用例。

独立/基本路径测试 对程序所有执行路径进行等价类划分,找出有代表性的最简单的路径(例如循环只需执行1次),设计测试用例使每一条基本路径被至少覆盖1次

Coverage of Testing

代码覆盖度 已有的测试用例有多大程度覆盖了被测程序, 代码覆盖度越低,测试越不充分 但要做到很高的代码覆盖度,需要更多的测试用例,测试代价高
覆盖度的种类

  • 函数覆盖 has each function in program been called?
  • 语句覆盖 is every statement run by some test case?
  • 分支覆盖 for every if or while or switch-case or for statement in the program, are both the true and the false direction taken by some test case?
  • 条件覆盖 for every condition in if/while/for/switch-case statement, are both the true/false direction taken by some test case?
  • 路径覆盖 is every possible combination of branches — every path
    through the program — taken by some test case?

测试效果:路径覆盖>分支覆盖>语句覆盖
测试难度:路径覆盖>分支覆盖>语句覆盖

Automated Testing and Regression Testing

Automated Testing
手工测试的代价太高,最好达到完全的自动化,自动调用被测函数、自动判定测试结果、自动计算覆盖度
不同于Automatic test generation

Regression testing
回归测试:一旦程序被修改,重 新执行之前的所有测试
一旦发现bug,要马上写一个可重现该bug的测试用例,并将其加入测试库

Documenting Your Testing Strategy

测试策略(根据什么来选择测试用例)非常重要,需要在程 序中显式记录下来
目的:在代码评审过程中,其他人可以理解你的测试,并评判你的测试是否足够充分

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值