一、测试有哪些分类
1、黑白测试
- 根据代码的思路写测试叫白盒测试
- 不知道代码的思路测试叫黑盒测试(大部分人工测试都是这个)
2、规模(小->大)
- 单元测试(最小的测试是函数,也是白盒测试)
- 模块测试(根据API测试)
- 功能测试
- 集成测试(多个系统端对端测试E2E,也是黑盒测试)
二、单元测试的必要性
- 你不一定一辈子当前端
- 开发库(公司里的库必须要有),没有单元测试公司很难有优质代码的积累
- 测试驱动开发
三、前端业务代码是否需要测试
- 不需要
- 业务代码中的共用代码才需要测试:比如表单验证(抽离出组件,测组件)
- 然后做高质量的组件,输出给团队用
四、什么才算是好的单元测试
- 测试覆盖率>90%,基本上都是好的测试
- 测试内容:语句、分支、函数、行
五、测试工具介绍
- 这里使用Karma + Mocha做单元测试,TravisCI做持续集成
- Karma([ˈkɑrmə] 卡玛)是一个测试运行器,它可以呼起浏览器,加载测试脚本,然后运行测试用例
- Mocha([ˈmoʊkə] 摩卡)是一个单元测试框架/库,它可以用来写测试用例
- Sinon(西农)是一个 spy / stub / mock 库,用以辅助测试
- karma-coverage 来设置 Karma 的代码覆盖率
- chaijs 提供了dscribe it断言
除此之外了解两个词语:
- BDD 行为驱动开发 Behavior Driven Development
- TDD 测试驱动开发 Test Driven Development
五、安装工具及配置
1、创建karma 配置
- 安装依赖
npm add -D karma karma-chrome-launcher karma-mocha karma-sourcemap-loader karma-spec-reporter karma-webpack chai sinon sinon-chai
安装成功:
- 创建 karma.config.js
//frameworks引入'mocha', 就会拥有descibe it函数,frameworks引入'sinon-chai',就会有sinon.fake(),expect函数
//files 检索 tests/**/*.spec.js文件
//browsers 使用的是ChromeHeadless,无头浏览器
var webpackConfig = require('@vue/cli-service/webpack.config.js')
module.exports = function (config) {
config.set({
frameworks: ['mocha'],
files: [
'tests/**/*.spec.js'
],
preprocessors: {
'**/*.spec.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
reporters: ['spec'],
autoWatch: true,
browsers: ['ChromeHeadless']
})
}
- 修改package.json 中scripts
"scripts": {
...
"test": "karma start --single-run",
"test:unit": "karma start",
"test:unit:old": "vue-cli-service test:unit",//vue原有提供的代码
...
},
2、创建单元测试覆盖率
- 安装依赖
vue-test-utils:vue-test-utils官网配置覆盖率
npm install --save-dev karma-coverage cross-env
npm install --save-dev babel-plugin-istanbul
- 更新.babelrc 文件
{
……
env: {
test: {
"plugins": ["istanbul"]
}
}
……
}
- 更新 karma.conf.js文件
module.exports = function (config) {
config.set({
// ...
reporters: ['spec', 'coverage'],
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
}
})
}
- 更新test脚本
// 加上cross-env BABEL_ENV=test
{
"scripts": {
"test": "cross-env BABEL_ENV=test karma start --single-run"
}
}
六、如何写单元测试
-
在vue脚手架中,不同的单元测试写在tests/unit/**.spec.js
-
vue-test-utils提供的API:官网教你怎么写代码
-
举例button组件
vue/test-utils
//引入chai,所以有dscribe it expect 函数
import chai, {expect} from 'chai'
//sinon(西农)是一个 spy / stub / mock 库,用以辅助测试
import sinon from 'sinon'
import sinonChai from 'sinon-chai'
//vue-test-utils 提供的工具
import {shallowMount, mount} from '@vue/test-utils'
//引入要测试的组件
import Button from '../../src/button/button'
chai.use(sinonChai)
describe('Button.vue', () => {
it('存在.', () => {
expect(Button).to.exist
})
it('可以设置icon.', () => {
const wrapper = mount(Button, {
propsData: {
icon: 'settings'
}
})
const useElement = wrapper.find('use')
expect(useElement.attributes()['href']).to.equal('#i-settings')
})
it('可以设置loading.', () => {
const wrapper = mount(Button, {
propsData: {
icon: 'settings',
loading: true
}
})
const vm = wrapper.vm
const useElements = vm.$el.querySelectorAll('use')
expect(useElements.length).to.equal(1)
expect(useElements[0].getAttribute('xlink:href')).to.equal('#i-loading')
})
it('icon 默认的 order 是 1', () => {
const wrapper = mount(Button, {
attachToDocument: true,
propsData: {
icon: 'settings',
}
})
const vm = wrapper.vm
const icon = vm.$el.querySelector('svg')
expect(getComputedStyle(icon).order).to.eq('1')
})
it('设置 iconPosition 可以改变 order', () => {
const wrapper = mount(Button, {
attachToDocument: true,
propsData: {
icon: 'settings',
iconPosition: 'right'
}
})
const vm = wrapper.vm
const icon = vm.$el.querySelector('svg')
expect(getComputedStyle(icon).order).to.eq('2')
})
it('点击 button 触发 click 事件', () => {
const wrapper = mount(Button, {
propsData: {
icon: 'settings',
}
})
const vm = wrapper.vm
const callback = sinon.fake();
vm.$on('click', callback)
vm.$el.click()
expect(callback).to.have.been.called
})
})
- 运行
npm run test:unit
运行成功:单元测试及测试覆盖率
七、TravisCI 持续集成
- 每次都需要输入npm run test:unit来测试,如果用TravisCI写好测试用例文件配置相关配置就会自动化测试。
- 阮一峰文章:http://www.ruanyifeng.com/blog/2017/12/travis_ci_tutorial.html
- 在根目录下配置.travis.yml文件
//nodejs环境,版本为8,选用稳定版本的chrome测试
language: node_js
node_js:
- "8"
addons:
chrome: stable
sudo: required
before_script:
- "sudo chown root /opt/google/chrome/chrome-sandbox"
- "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"
- 使用github登录官网:https://travis-ci.org/
- 选中测试项目,且测试项目需要有测试脚本
- 每次github提交代码都会进行测试