前端单元测试入门3-react测试
1.react测试体验
1.1安装
create-react-app react-test cd react-test
1.2 创建sum.js
module.exports = function(a,b){ return a+b; }
1.3 创建sum.spec.js
let sum = require('./sum'); it('a+b',function(){ expect(sum(1,2)).toBe(3); });
1.4 运行测试
npm test
2.enzyme测试
- Shallow Rendering(浅渲染)指的是,将一个组件渲染成虚拟DOM对象,但是只渲染第一层,不渲染所有子组件,所以处理速度非常快。它不需要DOM环境,因为根本没有加载进DOM
- find()方法:只支持简单选择器 类选择器、id选择器、标签选择器、复合选择器
2.1 安装enzyme
npm i enzyme enzyme-adapter-react-16 -D
2.2 创建 TodoInput.js
import React, { Component } from 'react'; export default class TodoInput extends Component { handleKeyDown = (event) => { let code = event.keyCode; if (code == 13) { let text = event.target.value; this.props.addTodo(text); event.target.value = ''; } } addTodo = () => { let text = this.todo.value; this.props.addTodo(text); this.todo.value = ''; } render() { return ( <div> <input ref={input => this.todo = input} onKeyDown={this.handleKeyDown} /> <input id="addBtn" onClick={this.addTodo} defaultValue="增加" /> </div> ) } }
2.3 创建 TodoInput.spec.js
import React from 'react'; import Enzyme,{shallow} from 'enzyme'; import TodoInput from './TodoInput'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({adapter:new Adapter()}); //http://airbnb.io/enzyme/docs/api/ShallowWrapper/find.html //http://airbnb.io/enzyme/docs/api/selector.html it('shoud render 请输入',function(){ const wrapper = shallow(<TodoInput/>); const h3 = wrapper.find('h3'); const input = wrapper.find('input'); expect(h3.text()).toBe('待办事项'); expect(input.props().defaultValue).toBe('请输入'); });
2.3 创建 TodoList.js
import React, { Component } from 'react'; import TodoItem from './TodoItem'; export default class TodoList extends Component { render() { return ( <ul> { this.props.todos.map(todo => <TodoItem key={todo.id} todo={todo} delTodo={this.props.delTodo} toggleTodo={this.props.toggleTodo} />) } </ul> ) } }
2.4 点击事件
import React from 'react'; import Enzyme,{shallow} from 'enzyme'; import TodoInput from './TodoInput'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({adapter:new Adapter()}); //http://airbnb.io/enzyme/docs/api/ShallowWrapper/find.html //http://airbnb.io/enzyme/docs/api/selector.html describe('测试TodoInput',function(){ let todos; beforeEach(()=>{ todos =[{text:'1'},{text:'2'}]; }); it('shoud render 请输入',function(){ let wrapper = shallow(<TodoInput/>); const h3 = wrapper.find('h3'); const input = wrapper.find('input'); expect(h3.text()).toBe('待办事项'); expect(input.props().defaultValue).toBe('请输入'); }); it('点击按钮的时候调用addTodo方法',function(){ let addTodo = jest.fn(); let wrapper = shallow(<TodoInput addTodo = {addTodo}/>); let button = wrapper.find('button'); button.simulate('click'); expect(addTodo).toBeCalled(); }); });
2.5 TDD
- TDD是测试驱动开发(Test-Driven Development)是敏捷开发中的一项核心实践和技术,也是一种设计方法论
- TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码
创建reducer.js
const ADD_TODO = 'ADD_TODO'; const DEL_TODO = 'DEL_TODO'; let INIT_STATE = [{id:1,text:'1'},{id:2,text:'2'}]; function reducer(state=INIT_STATE,action={}){ switch(action.type){ case ADD_TODO: return [...state,action.todo]; case DEL_TODO: return state.filter(item=>item.id != action.id); default: return state; } } module.exports = reducer;
创建reducer.spec.js
let reducer = require('./reducer'); const ADD_TODO = 'ADD_TODO'; const DEL_TODO = 'DEL_TODO'; describe('reducer',()=>{ let INIT_STATE = [{id:1,text:'1'},{id:2,text:'2'}]; it('初始状态',()=>{ expect(reducer(undefined,{})).toEqual(INIT_STATE); }); it('增加todo',()=>{ let todos = reducer(INIT_STATE,{type:ADD_TODO,todo:{id:3,text:'3'}}); expect(todos).toEqual([...INIT_STATE,{id:3,text:'3'}]); }); it('删除todo',()=>{ let todos = reducer(INIT_STATE,{type:DEL_TODO,id:2}); expect(todos).toEqual([{id:1,text:'1'}]); }); });
2.6 测试点击事件
import React from 'react'; import Enzyme,{shallow} from 'enzyme'; import TodoItem from './TodoItem'; import Adapter from 'enzyme-adapter-react-16'; import { wrap } from 'module'; Enzyme.configure({adapter:new Adapter()}); //http://airbnb.io/enzyme/docs/api/ShallowWrapper/find.html //http://airbnb.io/enzyme/docs/api/selector.html describe('TodoItem',function(){ it('todo',()=>{ const wrapper = shallow(<TodoItem todo={{id:1,text:'1'}}/>); expect(wrapper.text()).toMatch(/1/); expect(wrapper.hasClass('todo')).toBe(true); expect(wrapper.hasClass('todo-selected')).toBe(false); }); it('todo-selected',()=>{ const wrapper = shallow(<TodoItem todo={{id:1,text:'1'}}/>); expect(wrapper.text()).toMatch(/1/); wrapper.simulate('click'); expect(wrapper.hasClass('todo')).toBe(false); expect(wrapper.hasClass('todo-selected')).toBe(true); }); });
2.7 mount
mount将React组件加载为真实的DOM
- .get(index):返回指定位置的子组件的DOM节点
- .at(index):返回指定位置的子组件
- .text():返回当前组件的文本内容
- .html():返回当前组件的HTML代码形式
- .props():返回根组件的所有属性
- .prop(key):返回根组件的指定属性
- .state([key]):返回根组件的状态
import React from 'react'; import Enzyme,{mount} from 'enzyme'; import TodoApp from './TodoApp'; import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({adapter:new Adapter()}); describe('TodoApp',function(){ it('addTodo',()=>{ let wrapper = mount(<TodoApp/>); let len = wrapper.find('li').length; wrapper.find('button').at(0).simulate('click'); expect(wrapper.find('li').length).toBe(len + 1); }); it('delTodo',()=>{ let wrapper = mount(<TodoApp/>); let len = wrapper.find('li').length; wrapper.find('button').at(1).simulate('click'); expect(wrapper.find('li').length).toBe(len - 1); }); });
3. 参考
- create-react-app
- jest
- expect
- jest中文网
- enzyme
- Jasmine
- istanbul
- prop-types
相关推荐
AnndyR 2020-06-09
颤抖吧腿子 2020-09-04
游走的豚鼠君 2020-11-10
81417707 2020-10-30
ctg 2020-10-14
小飞侠V 2020-09-25
PncLogon 2020-09-24
jipengx 2020-09-10
wwzaqw 2020-09-04
maple00 2020-09-02
青蓝 2020-08-26
罗忠浩 2020-08-16
liduote 2020-08-13
不知道该写啥QAQ 2020-08-02
pengruiyu 2020-08-01
wmd看海 2020-07-27
孝平 2020-07-18
Eduenth 2020-07-05