转载自:聊一聊前端自动化测试
- 前沿
- 测试工具
- 持续测试
前言
为什么要测试
首先,我们要清楚为什么要测试。说白了就是检验我们写的代码是否有错误或者是需要优化的地方,从而提高我们的代码质量。要有自动化测试就需要写测试用例,在发布之前跑一遍测试用例,可以保证测试用例覆盖的地方是没有bug。
自动化测试另一个好处就是效率高,比如一个按钮的功能交给测试人员去测,需要找到页面点击对应按钮然后根据才能知道这个功能是否有问题。那交给机器,通过脚本去跑程序来判断是否正确要更快更准确,而且每次改动代码之后可以马上接入自动化测试检查是否有错误。总之,机器测试的效率肯定是要去人测试快多啦。
既然测试这么好,那是不是所有代码都要有测试用例支持呢
我认为测试覆盖率还是要和测试成本结合起来,比如一个不会经常变的公共方法就尽可能的将测试覆盖率做到趋于100%。而对于一个完整项目,我建议前期先做最短的时间覆盖80%的测试用例,后期再慢慢完善。
经常做更改的活动页面我认为没必要必须趋近100%,因为要不断的更改测试永用例,维护成本太高。
测试工具
- 测试框架:Mocha、Jasmine等等,主要是提供了清晰简明的语法来描述测试用例,测试分组以及测试不通过报错,具体哪报的错,什么原因报错等等。测试框架通常提供BDD(行为驱动开发)和TDD(测试驱动开发)两种测试语法来编写测试用例。Mocha支持两种,而Jasmine只支持BDD,下面会以Mocha的BDD为例。
- 断言库:Should.js、chai、expect.js等等,断言库提供了多少语义化的方法提供各种情况的判断。当然也不可以不用断言库,nodejs本来也有assert断言模块,下面会以Should.js为例。
- 代码覆盖率:Istanbul是本地测试代码覆盖率常用的工具之一,它提供了一系列代码覆盖率的测试指标,可以清晰的知道哪方面的代码没有覆盖到。
下面以一个最简单nodejs项目为例
目录结构如下
.
├── LICENSE
├── README.md
├── index.js
├── node_modules
├── package.json
└── test
└── test.js
首先需要安装测试框架和断言库:
npm install mocha should --save-dev
测试用例
然后在index.js中编写一行代码
'use strict'
module.exports = () => 'hello world!';
那么在test中就需要写一个测试用例来判断index.js输出的值是否是'hello world!'
'use strict'
require('should');
const exp = require('../index');
describe('test', function () {
it('should get "hello world!"', function () {
exp().should.be.eql('hello world!');
})
});
在package.json文件中加入命令
"scripts": {
"test": "mocha"
},
然后就可以在终端中运行
npm test
测试结果:
如果测试通过就可以看到 1 passing
如果没有测试通过就可以看到 1 failing,通过也可以看到报错信息啦
mocha还有很多配置项
一种是直接更改 package.json 中的 test 命令,例如
"scripts": {
"test": "mocha --require should"
},
这样mocha就会在每个文件中自动引入should不用自己引入了。
还有一种写法就是在test文件夹中新建 mocha.opts 配置文件,并写入
--require should
效果和第一种一样
代码覆盖率
首先需要安装istanbul:
npm install istanbul --save-dev
Node.js端做代码覆盖率测试很简单,只需要用istanbul启动Mocha即可
修改test命令
"scripts": {
"test": "istanbul cover mocha -- --delay"
},
当使用istanbul运行Mocha时,istanbul命令自己的参数放在--之前,需要传递给Mocha的参数放在--之后
运行完成后,项目下会多出一个 coverage 文件夹,这里就是放代码覆盖率结果的地方
接入Karma
Karma 是一个测试集成框架,可以方便地以插件的形式集成测试框架、测试环境、覆盖率工具等等。首先需要使用npm安装一些依赖:
- karma:框架本体
- karma-mocha:Mocha测试框架
- karma-coverage:覆盖率测试
- karma-spec-reporter:测试结果输出
- karma-chrome-launcher:Chrome环境
- karma-firefox-launcher:Firefox环境
安装完成之后,我们把之前的项目该删除的删除,只留下源文件和测试文件,并增加一个 karma.conf.js 文件:
.
├── karma.conf.js
├── package.json
├── src
│ └── index.js
└── test
└── test.js
karma.conf.js是karma的配置文件。
持续测试
开源的持续集成
开源比较出名的持续集成测试服务器当属Travis了,而代码覆盖率则通过Coveralls,只要有GitHub账号,就能接入Travis和Coveralls了。
Travis会读取项目下的 travis.yml 文件,一个简单的例子:
language: node_js
sudo: true
node_js:
- "6"
addons:
firefox: "latest"
chrome: "stable"
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
before_install:
npm install karma-cli -g
after_success:
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
karma.conf.js 文件在这个例子里面,它大致是这样的
module.exports = function(config) {
var configuration = {
basePath: '',
frameworks: ['mocha'],
files: [
'https://cdn.bootcss.com/jquery/2.2.4/jquery.js',
'node_modules/should/should.js',
'test/**.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
singleRun: true,
concurrency: Infinity
};
if(process.env.TRAVIS){
configuration.browsers = ['Chrome_travis_ci'];
}
config.set(configuration);
}
这些配置都是什么意思呢?这里挨个说明一下:
frameworks: 使用的测试框架,这里依旧是我们熟悉又亲切的Mocha
files:测试页面需要加载的资源,上面的test目录下已经没有test.html了,所有需要加载内容都在这里指定,如果是CDN上的资源,直接写URL也可以,不过建议尽可能使用本地资源,这样测试更快而且即使没网也可以测试。这个例子里,第一行载入的是断言库Should.js,第二行是src下的所有代码,第三行载入测试代码
preprocessors:配置预处理器,在上面files载入对应的文件前,如果在这里配置了预处理器,会先对文件做处理,然后载入处理结果。这个例子里,需要对src目录下的所有资源添加覆盖率打点(这一步之前是通过gulp-istanbul来做,现在karma-coverage框架可以很方便的处理,也不需要钩子啥的了)。后面做React组件测试时也会在这里使用webpack
plugins:安装的插件列表
browsers:需要测试的浏览器,这里我们选择了PhantomJS、FireFox、Chrome
reporters:需要生成哪些代码报告
coverageReporter:覆盖率报告要如何生成,这里我们期望生成和之前一样的报告,包括覆盖率页面、lcov.info、coverage.json、以及命令行里的提示
最后将package.json中test命令改为:
{
"scripts": {
"test": "karma start --single-run"
}
}
项目接入持续集成在多人开发同一个仓库时候能起到很大的用途,每次push都能自动触发测试,测试没过会发生告警。如果需求采用Issues+Merge Request来管理,每个需求一个Issue+一个分支,开发完成后提交Merge Request,由项目Owner负责合并,项目质量将更有保障
总结
这里介绍的只是前端自动化测试的表面,还有很多可以深入研究的东西。还有很多更加高效的自动化测试方法等待我们去深入挖掘。