文章目录
Chapter8:Software Testing
8.1 What testing is for?
Testing过程:看看这个program是否做了它应该做的事情。用到artificial data(即test cases 测试用例)
Testing目的:揭示程序的问题,而不是说程序好好好。
【 努力挑刺的领导来检查工作做的怎么样,而且不是纸上谈兵光看,他还要跑程序来对比实际结果和预期】
8.1.1 testing & static validation
testing & static validation 都是 verification and validation(是通用活动)的一部分。
testing:通过执行程序来挑毛病。
static validation:通过桌面审查(文档、源代码等)来挑毛病。
两者是互为补充的validation方法。
8.1.2 Testing的2个目标
-
向developer和customer表明:开发的软件满足之前提出的需求**【本职工作】**
(1)对custom software:对requirement document中的每一个requirement都要进行测试
(2)对generic software : there should be tests for all of the system features, plus combinations of these features.
-
发现异常行为、软件缺陷 【精益求精】
有时候,有缺陷存在,但也能完全满足1。这时候我们不能将就,因为这带来了潜在的威胁。
8.2 How to test ?
8.2.1 Verification vs Validation (V&V)
-
test说到底就是为了检查system好不好,属于 Verification vs Validation 的范畴。
-
Verification:
right修饰building,构建过程中的验证,软件应该遵从它的定义
针对:软件过程中各个环节
-
Validation:
right修饰product,确认这是一个好的软件,软件确实是用户需要的
针对:产出的软件产品
8.2.2 Inspections and Testing
- 为了完成V&V,我们有2类主要的活动:
(1)分析静态系统(文档and源代码),来发现问题。【 Inspections 】
(2)动态执行程序(测试用例),来发现问题。【 Testing 】
-
Inspections and Testing 的关系
两者是互补的关系。两者都属于 V&V process
Inspections :检验软件和开发过程中的各种定义是否一致
testing:检查和客户的真正需求是否一致,检验NFR
8.3 Software Inspections
-
检查源文档,来发现异常anomalies and 缺陷defects.
-
不执行程序的【所以也叫、软件审查、桌面审查】
-
advantages:
testing的时候,一般出现了一个错误,可能就屏蔽掉了其他的错误,即:一次只能发现一种错误。
而inspection呢,一次能发现好多错误
还可以检验一些软件的质量因素,比如是否遵从了一些标准?代码规范?从而影响可维护性。
-
代码静态分析的自动分析工具
8.4 Testing
8.4.1 流程
(1)设计test cases (2)准备test data (3)Run program with test data(4)compare results
最后产生 测试报告 test report
8.4.2 test data & cases
test data: 是一组输入数据
test cases:是一组输入数据 + 预期输出(the predicted outputs)
8.4.3 choosing test case
-
Black-box testing:黑盒测试
把程序看成一个不透明的黑盒,based on the system specification
-
While-box testing:白盒测试
把程序看成一个透明的盒子,based on the program structure
可以根据程序本身的结构、具体算法等,来帮助产生测试用例。
8.4.4 stages of testing
这版英文教材分为3个阶段:开发阶段测试、发布版本测试、用户测试
中文教材一般划分为4个阶段:单元测试、子系统测试、系统测试、确认测试。
但其实总体差不多。
-
development test :
在程序开发过程中的,开发团队来进行。从小到大三个层面。
(1)Unit :单个程序/类,聚焦于方法/功能,通常由程序员自己进行测试
(2)Componen :1个Component由一堆Units组成的,自然就需要很多接口,要对接口等进行测试
(3)System :多个components组成1个完整的system,对整体system的功能进行测试
-
release test:
由一个单独的测试团队来承担,一个完整的程序版本交付给用户之前,进行的测试
-
User test:
系统的Users,在自己的环境下进行的测试
8.4.5 class的test coverage【测试覆盖】
- 对 object class 的测试属于 development test --> Unit test
- 需要包括如下:
- 举例:对Weather station系统的identifier类进行测试
8.5 Automate testing
-
Automate testing
为了提高效率,我们会采用一些自动测试工具。
在 Unit testing 中十分实用。
比如 Junit【eclipse里就有】 就是一个 测试 Java 代码的 一个 test automation framework
*具体举例见ppt25
-
a test automation framework 一般分为三个部分
(1)A setup part:定义测试用例,人为地给定 inputs & predicted ouputs
(2)A call part:定义要被测的 程序方法,也就是 f(),用来产生 outputs
(3)An assertion part :将测试执行的结果,即outputs,和预期的输出,即 predicted outputs 进行比较
-
对Unit、component、system的其他测试工具
Selenium :Browse testing
QTP(HP QuickTest Professional software ): for regression testing
WinRunner: for function testing
Rational robot: integrated testing tools
Advent Qengine: for web application
LoadRunner: load testing
8.6 test cases【重点】
- 当我们确定要测试哪些东西后【即确定了要测试的unit、component、system后】,我们就得来设计 test cases 了
- 前面我们提到过,Black-box & White-box 。现在我们讲讲具体的 strategies。
8.6.1 Testing strategies
两种:Partition testing & Guideline-based testing
(1)Partition testing:因为 inputs 可以是无限个,我们不可能说穷举无限个inputs。于是,我们将 inputs 划分为 n 个等价类,从每个等价类里面抽取1个来进行测试。
(2)Guideline-based testing:在以往的test中,我们会积累不少的经验,可以总结出一些高频的错误,我们就根据这个指导,来选一些 【极容易发生错误的】test cases
8.6.2 Partition testing 等价类划分测试
-
总体过程描述:
根据 inputs 和outputs 来划分不同的 测试数据组
每一类,称之为:一个等价类 equivalence partition
对每一个等价类来讲,程序的行为都是一样的。
test cases就从每个等价类里面挑。
一般我们划分2个: 有效的输入 、 非法的输入。然后继续细分。
-
图形描述:
左边 4 个 inputs 组, 右边 2 个 ouputs 组,那么我们通常需要进行组合。
这是一个黑盒测试过程,即:我们不需要知道 f( ) ,只需要根据输入输出来设计测试用例
-
equivalence partition 例子:
除了 6 个 等价类之外,通常还需要加上对 **边界值 **的测试用例。
*例2 听ppt
8.6.3 Guideline-based testing
-
依据经验,给出一些 test cases
选择inputs,使能够:强制系统产生错误信息
选择inputs,使能够:引起 buffer 产生溢出
大量重复输入,看看会不会出错
选择inputs,使能够:产生 invalid ouputs
选择inputs,使能够:产生 过大/小 的 outputs
8.6.4 Structural testing 结构测试 【白盒】
白盒测试——结构测试
特点:每条语句都能执行一遍。
-
Test data 测试数据
可以从 Component code 里面导出来。
-
Path testing
要实现语句覆盖,我们要做到的就是:Path testing 路径测试。
设计一组测试用例,能确保,程序的每一条path都能执行一次。
Path testing 路径测试的起点是一个 Program flow graph 程序流图,其中显示了代表程序决策的node 节点和代表控制流的 arch 弧。
-
Program flow graphs
反应了一个程序的控制流。 -
cyclomatic complexity
可以计算一个指标:cyclomatic complexity 环路复杂性【即:我们要测试的路径数量】
cyclomatic complexity 越大,意味着,复杂的循环和分支语句越多,越难以维护。
cyclomatic complexity 和 edge边 的数量成正比,和 node节点 的数量成反比。
通过 Program flow graphs 计算得到的 cyclomatic complexity = 路径的数量 = 测试用例的数量
cyclomatic complexity 这个指标很有用,但是这并不意味着有了足够的测试。
尽管所有的路径都执行到了,但是没有考虑到路径组合的情况,所以,这只是最基础的测试,我们至少要做到这一点。
-
例子:二分查找
我们在设计 test data 的时候,是知道详细的代码的,如图。
之后我们分析:Program flow graphs ,如图。【1可以并入2中,8可以并入9。只有循环分支结构,才会增加环路复杂度】本图,至少需要4个path testing 或者叫测试用例【3分支+1循环】
8.7 Component testing
-
Component testing
前面讲的都是 Unit test 单元测试,现在讲讲 Component testing 组件测试。
组件是由一系列的,交互的对象,构成的。组件之间主要通过 interface 交互。
组件测试,也是【黑盒测试】
是在已经完成了 Unit test 单元测试的基础上完成的。
-
Interface testing
关注点:components 对外的 Interface 。test cases 根据 interface 来生成。
-
Interface errors
-
Interface testing guidelines
设计测试,调用过程的参数,应该选择极限值。【边界值分析】
测试指针参数的时候,一定要包括空指针。
要有 能导致组件 fail ,的用例用例
通过 压力测试,测试并发能力。
如果是共享内存的系统,应该变换,对组件访问的顺序
8.8 System testing
在 Component testing 完成后,把所有的 compnents 合起来,给 system 进行测试。
The focus in system testing is :testing the interactions between components.
8.8.1 Use-case testing & The sequence diagram
每一个 use-case 都会包含几个 system components,所以 测试 use-cases 就是测试组件间的交互。
The sequence diagram 描述 组件 or 对象间的交互,也能帮助我们进行 system testing
例子:Collect weather data sequence chart
所以:对 use-case 的测试,测试的就是 对象【小系统】 or 组件【大系统】之间的交互。
8.8.2 Testing policies
8.9 Test-driven development 【Agile Method】
8.9.1 Test-driven development process
-
回顾:
我们前面讲的:Unit / Component / System testing ,都属于开发测试,都是系统开发阶段的测试。完成这样的一种测试过程,就形成了完整的系统。
-
本节:
我们在 Agile Method 里面讲过,敏捷方法,是一种 test-driven development 。
Tests are written before code
在编码前就写测试框架,是一种测试和编码过程交替进行的过程。是增量式的开发过程。
先写测试框架,再写开发代码,只有通过这一次的测试,才会进行下一次的增量开发。
8.9.2 Benefits of test-driven development
1)Code covergae:
代码覆盖【每条代码都要覆盖到,即 Path testing 路径测试】
2)Regression testing:
对修改后的程序进行的测试,当一个程序在开发时,回归测试的组件也就增量开发了。【测试驱动开发通常会采用自动测试工具来测试,在代码写好前,先弄完 test code,当程序修改之后,test code 不需要再写】
3)Simplified debugging:
简化了调试【因为测试驱动开发,都是很小的增量。当问题发生,很容易被修改】
4)System documentation:
系统文档【测试本身也可以作为文档的一部分】
8.10 Release testing
-
What is Release testing ?
Release testing,版本测试。指的是:经历了 Unit / Component / System testing 后,准备发布这个版本了,发布之前的最后一次测试(不通过开发团队),一旦通过,就交付给用户使用。
-
特点:
通常是 Black-box 黑盒测试,根据 system specification 导出测试用例。
有些教材中,Release testing 版本测试 归于 System test 系统测试。
版本测试,是开发团队最后检查系统的功能、性能,测试通过后,就交付给用户使用。
-
Release testing 对比 System testing
System testing:是开发团队完成的,为了发现系统的错误。
Release testing:不是由开发团队完成的,是为了检验系统是否满足最终用户需求。要检验:每一个需求,为每一个需求进行测试。基于system specification 。
*例子见ppt
-
Scenario testing
通过设计典型的使用场景,基于场景来设计测试用例。
*例子见ppt
-
Performance testing
-
User testing
-
The acceptance testing process
-
Agile methods and acceptance testing