单元测试原则
AIR原则
- A: Automatic(自动化),不能有对人工操作的依赖
- I : Independent (独立性),用例直接不能有逻辑、顺序上的依赖关系
- R: Repeatable (可重复),尽可能不依赖外部环境
BCDE原则
- B: Border ,边界值测试:循环边界、特殊取值、特殊长度、数据顺序等
- C: Correct,正确的输入,并得到预期的结果
- D: Design,与设计文档相结合,来编写单元测试
- E: Error,强制错误信息输入 (如:非法数据),并得到预期的结果
单元测试工具
Node后端单元测试
一般由框架本身提供,如egg-mock、@nestjs/testing
//egg-mock
const { app, mock, assert } = require('egg-mock/bootstrap');
describe('get()', () => {
it('should get exists user', async () => {
// 创建 ctx
const ctx = app.mockContext();
//通过 ctx 访问到 service.user
const user = await ctx.service.user.get('xiaoming');
assert(user);
assert(user.name === 'xiaoming');
)}
})
前端单元测试工具
Enzyme(react)
Airbnb出品,是对 React 官方测试工具库的封装,完整文档:官方文档
enzyme支持三种方式的渲染:
- shallow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,因而效率非常高。不需要DOM环境, 并可以使用jQuery的方式访问组件的信息;
import { shallow ] from 'enzyme'; import Foo from './Foo'; describe('<MyComponent />',() => { it('renders three <Foo /> components', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find(Foo)).to.have.lengthof(3); }) });
- render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构。
import React from 'react'; import { render ] from 'enzyme'; describe('<Foo />', () => { it('renders a div', () => { const wrapper = render(<div className="myClass" />) expect(wrapper.html()).to.contain('div'); }) })
- mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期,用到了jsdom来模拟浏览器环境。
import { mount ) from 'enzyme'; import Foo from './Foo'; describe('<Foo />', () => { it('allows us to set props', () => { const wrapper = mount(<Foo bar="baz" />); expect(wrapper.props().bar).to.equal('baz'); wrapper.setProps([ bar: 'foo'); expect(wrapper.props().bar).to.equal('foo' ); }) })
enzyme中有几个比较核心的函数需要注意,如下:
- simulate(event, mock):用来模拟事件触发,event为事件名称,mock为一个event object;
- instance():返回测试组件的实例;
- find(selector):根据选择器查找节点,selector可以是CSS中的选择器,也可以是组件的构造函数,以及组件的display name等;
- at(index):返回一个渲染过的对象;
- get(index):返回一个react node,要测试它,需要重新渲染;
- contains(nodeOrNodes):当前对象是否包含参数重点 node,参数类型为react对象或对象数组;
- text():返回当前组件的文本内容;
- html(): 返回当前组件的HTML代码形式;
- props():返回根组件的所有属性;
- prop(key):返回根组件的指定属性;
- state():返回根组件的状态;
- setState(nextState):设置根组件的状态;
- setProps(nextProps):设置根组件的属性;
@vue/test-utils(vue)
官方文档:vue/test-utils