1. 测试类型

  • 单元测试:指的是以原件的单元为单位,对软件进行测试。单元可以是一个函数,也可以是一个模块或一个组件,基本特征就是只要输入不变,必定返回同样的输出。一个软件越容易些单元测试,就表明它的模块化结构越好,给模块之间的耦合越弱。React的组件化和函数式编程,天生适合进行单元测试
  • 功能测试:相当于是黑盒测试,测试者不了解程序的内部情况,不需要具备编程语言的专门知识,只知道程序的输入、输出和功能,从用户的角度针对软件界面、功能和外部结构进行测试,不考虑内部的逻辑
  • 集成测试:在单元测试的基础上,将所有模块按照设计要求组装成子系统或者系统,进行测试
  • 冒烟测试:在正式全面的测试之前,对主要功能进行的与测试,确认主要功能是否满足需要,软件是否能正常运行

2. 开发模式

  • TDD: 测试驱动开发,英文为Testing Driven Development,强调的是一种开发方式,以测试来驱动整个项目,即先根据接口完成测试编写,然后在完成功能是要不断通过测试,最终目的是通过所有测试
  • BDD: 行为驱动测试,英文为Behavior Driven Development,强调的是写测试的风格,即测试要写的像自然语言,让项目的各个成员甚至产品都能看懂测试,甚至编写测试

TDD和BDD有各自的使用场景,BDD一般偏向于系统功能和业务逻辑的自动化测试设计;而TDD在快速开发并测试功能模块的过程中则更加高效,以快速完成开发为目的。

3. Jest

Jest是Facebook开源的一个前端测试框架,主要用于React和React Native的单元测试,已被集成在create-react-app中。Jest特点:

  • 易用性:基于Jasmine,提供断言库,支持多种测试风格
  • 适应性:Jest是模块化、可扩展和可配置的
  • 沙箱和快照:Jest内置了JSDOM,能够模拟浏览器环境,并且并行执行
  • 快照测试:Jest能够对React组件树进行序列化,生成对应的字符串快照,通过比较字符串提供高性能的UI检测
  • Mock系统:Jest实现了一个强大的Mock系统,支持自动和手动mock
  • 支持异步代码测试:支持Promise和async/await
  • 自动生成静态分析结果:内置Istanbul,测试代码覆盖率,并生成对应的报告

4. Enzyme

Enzyme是Airbnb开源的React测试工具库库,它功能过对官方的测试工具库ReactTestUtils的二次封装,提供了一套简洁强大的 API,并内置Cheerio,

实现了jQuery风格的方式进行DOM 处理,开发体验十分友好。在开源社区有超高人气,同时也获得了React 官方的推荐。

三种渲染方法

  • shallow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,使得效率非常高。不需要DOM环境, 并可以使用jQuery的方式访问组件的信息
  • render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构
  • mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期。用到了jsdom来模拟浏览器环境

三种方法中,shallow和mount因为返回的是DOM对象,可以用simulate进行交互模拟,而render方法不可以。一般shallow方法就可以满足需求,如果需要对子组件进行判断,需要使用render,如果需要测试组件的生命周期,需要使用mount方法。

常用方法

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):设置根组件的属性

5. config explain

  • setupFilesAfterEnv:配置文件,在运行测试案例代码之前,Jest会先运行这里的配置文件来初始化指定的测试环境
  • moduleFileExtensions:代表支持加载的文件名
  • testPathIgnorePatterns:用正则来匹配不用测试的文件
  • testRegex:正则表示的测试文件,测试文件的格式为xxx.test.js等
  • collectCoverage:是否生成测试覆盖报告,如果开启,会增加测试的时间
  • collectCoverageFrom:生成测试覆盖报告是检测的覆盖文件
  • moduleNameMapper:代表需要被Mock的资源名称
  • transform:用babel-jest来编译文件,生成ES6/7的语法, ts-jest编译typescript文件

6. jest对象

  • jest.fn(implementation):返回一个全新没有使用过的mock function,这个function在被调用的时候会记录很多和函数调用有关的信息
  • jest.mock(moduleName, factory, options):用来mock一些模块或者文件
  • jest.spyOn(object, methodName):返回一个mock function,和jest.fn相似,但是能够追踪object[methodName]的调用信息,类似Sinon

7. 常见断言

expect(value):要测试一个值进行断言的时候,要使用expect对值进行包裹

toBe(value):使用Object.is来进行比较,如果进行浮点数的比较,要使用toBeCloseTo

not:用来取反

toEqual(value):用于对象的深比较

toMatch(regexpOrString):用来检查字符串是否匹配,可以是正则表达式或者字符串

toContain(item):用来判断item是否在一个数组中,也可以用于字符串的判断

toBeNull(value):只匹配null

toBeUndefined(value):只匹配undefined

toBeDefined(value):与toBeUndefined相反

toBeTruthy(value):匹配任何使if语句为真的值

toBeFalsy(value):匹配任何使if语句为假的值

toBeGreaterThan(number): 大于

toBeGreaterThanOrEqual(number):大于等于

toBeLessThan(number):小于

toBeLessThanOrEqual(number):小于等于

toBeInstanceOf(class):判断是不是class的实例

anything(value):匹配除了null和undefined以外的所有值

resolves:用来取出promise为fulfilled时包裹的值,支持链式调用

rejects:用来取出promise为rejected时包裹的值,支持链式调用

toHaveBeenCalled():用来判断mock function是否被调用过

toHaveBeenCalledTimes(number):用来判断mock function被调用的次数

assertions(number):验证在一个测试用例中有number个断言被调用

extend(matchers):自定义一些断言

8. 测试场景

对组件节点进行测试

it('should has Button', () => {
const { wrapper } = setup();
expect(wrapper.find('Button').length).toBe(2);
}); it('should render 2 item', () => {
const { wrapper } = setupByRender();
expect(wrapper.find('button').length).toBe(2);
}); it('should render item equal', () => {
const { wrapper } = setupByMount();
wrapper.find('.item-text').forEach((node, index) => {
expect(node.text()).toBe(wrapper.props().list[index])
});
}); it('click item to be done', () => {
const { wrapper } = setupByMount();
wrapper.find('Button').at(0).simulate('click');
expect(props.deleteTodo).toBeCalled();
});

使用 snapshot 进行 UI 测试

it('renders correctly', () => {
const tree = renderer
.create(<TodoList {...props} />)
.toJSON(); expect(tree).toMatchSnapshot();
});

测试组件的内部函数

it('calls component handleTest', () => { // class中使用箭头函数来定义方法
const { wrapper } = setup();
const spyFunction = jest.spyOn(wrapper.instance(), 'handleTest');
wrapper.instance().handleTest();
expect(spyFunction).toHaveBeenCalled();
spyFunction.mockRestore();
}); it('calls component handleTest2', () => { //在constructor使用bind来定义方法
const spyFunction = jest.spyOn(TodoList.prototype, 'handleTest2');
const { wrapper } = setup();
wrapper.instance().handleTest2();
expect(spyFunction).toHaveBeenCalled();
spyFunction.mockRestore();
});

jest enzyme unit test react的更多相关文章

  1. react 单元测试 (jest+enzyme)

    为什么要做单元测试 作为一个前端工程师,我是很想去谢单元测试的,因为每天的需求很多,还要去编写测试代码,感觉时间都不够用了. 不过最近开发了一个比较复杂的项目,让我感觉一旦项目大了.复杂了,而且还是多 ...

  2. 搭建 Jest+ Enzyme 测试环境

    1.为什么要使用单元测试工具? 因为代码之间的相互调用关系,又希望测试过程单元相互独立,又能正常运行,这就需要我们对被测函数的依赖函数和环境进行mock,在测试数据输入.测试执行和测试结果检查方面存在 ...

  3. Jest+Enzyme React js/typescript测试环境配置案例

    本文案例github:https://github.com/axel10/react-jest-typescript-demo 配置jest的react测试环境时我们可以参考官方的配置教程: http ...

  4. react: typescript jest && enzyme

    Install Jest 1.install jest dependencies jest @types/jest ts-jest -D 2.jest.config.js module.exports ...

  5. [React Unit Testing] React unit testing demo

    import React from 'react' const Release = React.createClass({ render() { const { title, artist, outO ...

  6. [React] Unit test a React Render Prop component

    In this lesson, I use Enzyme and Jest to unit test a Counter Render Prop component. Writing integrat ...

  7. react typescript jest config (一)

    1. initialize project create a folder project Now we'll turn this folder into an npm package. npm in ...

  8. 【前端单元测试入门02】react的单元测试之Enzyme

    React项目的单元测试 React的组件结构和JSX语法,对上一章的内容来讲进行测试显得很勉强. React官方已经提供了一个测试工具库:react-dom/test-utils 只是用起来不够方便 ...

  9. react第三方库

    作者:慕课网链接:https://www.zhihu.com/question/59073695/answer/1071631250来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

随机推荐

  1. HDU - 3068 最长回文manacher马拉车算法

    # a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...

  2. [React]Hook初探

    Hook是什么 Hook是React从16.8开始支持的特性,使用Hook可以在不使用class时使用state Hook支持在不需要修改组件状态的情况下复用逻辑状态,从而解决使用render pro ...

  3. Java系列之内部类

    今天温习一下 Java 中的内部类,内部类一般有如下几种:静态内部类.成员内部类.匿名内部类和方法内部类,下文中将主要介绍静态内部类和成员内部类,主要内容如下: 概述 静态内部类 成员内部类 匿名内部 ...

  4. Java实现3次找到假球

    前言 之前老师让写一个程序,就写了写. 正文 题目要求 程序要求 10个铅球中有一个假球(比其他铅球的重量要轻),用天平三次称出假球. 程序设计思路 第一次使用天平分别称5个球,判断轻的一边有假球:拿 ...

  5. captcha-killer burp验证码识别插件体验

    0x01 使用背景 在渗透测试和src挖洞碰到验证码不可绕过时,就会需要对存在验证码的登录表单进行爆破,以前一直使用PKav HTTP Fuzzer和伏羲验证码识别来爆破,但是两者都有缺点PKav H ...

  6. memcached-tool 工具

    perl memcached-tool server_ip:port stats 输出说明: pid memcache服务器的进程ID uptime 服务器已经运行的秒数 time 服务器当前的uni ...

  7. SWUST OJ 1012哈希表(链地址法处理冲突)

    哈希表(链地址法处理冲突) 1000(ms) 10000(kb) 2676 / 6911 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法 ...

  8. 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统··········

    网上百度了下,解决方案是: 1. 以管理员身份运行PowerShell2. 执行:get-ExecutionPolicy,回复Restricted,表示状态是禁止的3.执行:set-Execution ...

  9. 使用 Spring data redis 结合 Spring cache 缓存数据配置

    使用 JavaConfig 方式配置 依赖 jar 包: jedis.spring-data-redis 首先需要进行 Redis 相关配置 @Configuration public class R ...

  10. CF633(div.2)A. Filling Diamonds

    题目描述 http://codeforces.com/contest/1339/problem/A 给定一个 \(n(1\le n \le 10^9)\) ,问用一个由两个三角形组成的菱形,填充下面这 ...