#JavaScript 自动化单元测试
- 为什么要进行自动化测试?
- 什么项目适合做自动化测试?
- 测试运行器 karma
- 测试框架 jasmine
### 为什么要进行自动化测试?
1. 正确性:验证代码的正确性
2. 自动化:一次编写,多次运行
3. 解释性:阅读测试用例,有时比文档说明更清晰
4. 驱动开发:快速反馈提高开发效率
5. 保证重构:测试用例做后盾,就可以大胆的进行重构持续集成
### 什么项目适合做自动化测试?
自动化的收益 = 迭代次数 * (全手动执行成本 - 维护成本) - 首次自动化成本
从三个方面进行权衡
1、需求变动不频繁
测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁,测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本,而脚本的维护本身就是一个代码开发的过程,需要修改、调试,必要的时候还要修改自动化测试的框架,如果所花费的成本不低于利用其节省的测试成本,那么自动化测试便是失败的。
项目中的某些模块相对稳定,而某些模块需求变动性很大。我们便可对相对稳定的模块进行自动化测试,而变动较大的仍是用手工测试。
2、项目周期较长
由于自动化测试需求的确定、自动化测试框架的设计、测试脚本的编写与调试均需要相当长的时间来完成。这样的过程本身就是一个测试软件的开发过程,需要较长的时间来完成。如果项目的周期比较短,没有足够的时间去支持这样一个过程,那么自动化测试便成为笑谈。
3、自动化测试脚本可重复使用
自动化测试脚本的重复使用要考量,测试的项目之间是否很大的差异性;所选择的测试工具是否适应这种差异;测试人员是否有能力开发出适应这种差异的自动化测试框架。
### 测试运行器
- karma: 设置测试需要的框架、环境、源文件、测试文件等,配置完后,就可以轻松地执行测试。
### 测试框架
- Qunit: 该框架诞生之初是为了jquery的单元测试,后来独立出来不再依赖于jquery本身,但是其身上还是脱离不开jquery的影子
- jasmine: Behavior-Drive development(BDD)风格的测试框架,在业内较为流行,功能很全面,自带asssert、mock功能
- mocha: node社区大神tj的作品,可以在node和browser端使用,具有很强的灵活性。
- intern: 看官方介绍该测试框架功能极其全面,似乎囊括了业内跟测试相关的所有功能
### 断言库
- chai:应该是目前组流行的断言库了,支持TDD(assert)、BDD(expect、should)两个风格的断言库
- should.js: TJ的另外一个开源贡献
- expect.js:BDD风格的另外一个断言库,基于should.js,是mini版的BDD库
- assert(node自带核心模块): 可以在node中使用的断言模块
### 测试运行器 karma
Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma。Karma是一个让人感到非常神秘的名字,表示佛教中的缘分,因果报应,这种名字更让人猜不透!
Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具可用于测试所有主流Web浏览器,也可和其他代码编辑器一起使用。这个测试工具的一个强大特性就是,它可以监控(Watch)文件的变化,然后自行执行,通过console.log显示测试结果。
参考资料:
- karma官网:https://karma-runner.github.io/1.0/index.html
- Karma-runner安装步骤: https://karma-runner.github.io/0.12/intro/installation.html
- Karma config file: http://karma-runner.github.io/0.8/config/configuration-file.html
- Karma files: http://karma-runner.github.io/0.8/config/files.html
- Karma和Jasmin自动化单元测试: http://blog.fens.me/nodejs-karma-jasmine/
- AngularJS的UnitTest: https://docs.angularjs.org/guide/unit-testing
### 测试框架 jasmine
#### Jasmine的基础语法
1. TDD(Test Driven Development)测试驱动开发
2. BDD(Behavior Driven Development)行为驱动开发 可以有效的改善设计,并在系统的演化过程中为团队指明前进方向
- Jasmine有四个核心概念:分组(Suites)、用例(Specs)、期望(Expectations)、匹配(Matchers)。
- Suites可以理解为一组测试用例,使用全局的Jasmin函数describe 创建。describe函数接受两个参数,一个字符串和一个函数。
- Specs可以理解为一个测试用例,使用全局的Jasmin函数it创建。和describe一样接受两个参数,一个字符串和一个函数,函数就是要执行的测试代码,字符串就是测试用例的名字。
- Expectations由expect 函数创建。接受一个参数。和Matcher一起联用,设置测试的预期值。
- Matcher实现一个“期望值”与“实际值”的对比,如果结果为true,则通过测试,反之,则失败。每一个matcher都能通过not执行否定判断。
```
expect(a).toBe(true);//期望变量a为true
expect(a).toEqual(true);//期望变量a等于true
expect(a).toMatch(/reg/);//期望变量a匹配reg正则表达式,也可以是字符串
expect(a.foo).toBeDefined();//期望a.foo已定义
expect(a.foo).toBeUndefined();//期望a.foo未定义
expect(a).toBeNull();//期望变量a为null
expect(a.isMale).toBeTruthy();//期望a.isMale为真
expect(a.isMale).toBeFalsy();//期望a.isMale为假
expect(true).toEqual(true);//期望true等于true
expect(a).toBeLessThan(b);//期望a小于b
expect(a).toBeGreaterThan(b);//期望a大于b
expect(a).toThrowError(/reg/);//期望a方法抛出异常
expect(a).toThrow();//期望a方法抛出异常
expect(a).toContain(b);//期望a(数组或者对象)包含b
```
- 为了在复杂的测试用例中更加便于组装和拆卸,Jasmine提供了四个函数:
```
beforeEach(function) //在每一个测试用例(it)执行之前都执行一遍beforeEach函数;
afterEach(function) //在每一个测试用例(it)执行完成之后都执行一遍afterEach函数;
beforeAll(function) //在所有测试用例执行之前执行一遍beforeAll函数;
afterAll(function) //在所有测试用例执行完成之后执行一遍afterAll函数;
```
- 举例:http://ued.fanxing.com/javascriptdan-yuan-ce-shi-kuang-jia-jasmine/
参考资料:
- Jasmine官网:http://jasine.github.io/
- Jasmine github:https://github.com/jasmine/jasmine/