摘要:简介是发布的一个开源的基于框架的单元测试工具。具体版本对照如下版本版本此处使用的版本为,所以我们需要安装依赖安装完成,接下来需要进行相关的配置。这样就可以将测试集中在组件的结构和逻辑上。
Jest、Enzyme 简介
Jest 是 Facebook 发布的一个开源的、基于 Jasmine 框架的 JavaScript 单元测试工具。
Enzyme 是 React 的测试类库。 Enzyme 提供了一套简洁强大的 API,并通过 jQuery 风格的方式进行DOM 处理,开发体验十分友好。
普通方法测试首先,使用npm安装Jest
npm install --save-dev jest
在目录下新建一个待测试文件 sort.js。
function sort(sortArr) { return sortArr.sort((a, b) => a - b); } module.exports = sort;
此处sort方法未对入参做类型检测
在这里定义了一个数组排序方法,下面来书写其测试用例,在目录下新建一个sort.test.js文件。
const sort = require("./sort"); const arr = [5,2,4,3,1]; test("排序数组[5,2,4,3,1]", () => { expect(sort(arr)).toEqual([1,2,3,4,5]); })
在用例中,我们先引入了待测试的方法,接下来定义了一个排序数组[5,2,4,3,1]的测试用例.test()用来定义一个测试用例,expect()会执行内部的方法,返回一个待测试的结果。toEqual()用来判断返回的结果于期望的结果是否相等。这里由于期望返回结果为数组,所以使用toEqual进行判断,除此之外,还有toBe(),toBeNull()等方法来比较不同的类型。更多内容...
打开package.json,在scripts中新增
test: "jest"
然后运行命令
npm run test
会看到用例测试通过的信息
由于我们的方法没有做入参类型检测,下面通过传入字符串,来测试异常情况。在sort.test.js中新增一个测试用例用例
test("排序字符串“52431”", () => { expect(sort("52431")).toEqual(12345); })
运行,则会看到测试失败的信息
从测试结果中我们可以清除的看到,运行来两个测试用例,第一个用例通过来,第二个用例运行是js出现了报错。此时便能根据测试结果,调整代码
更多测试方法此处不做讨论,具体可以参考Jest文档
在具体项目中的使用下面来在实际的项目中使用Jest + Enzyme来进行测试。测试Demo项目
首先,使用Create-React-App来创建一个应用。
接着,安装jest
npm install --save-dev jest
由于在书写用例时,会用到es6语法,所以还要安装babel-jest来进行转码
npm install --save-dev babel-jest
安装enzyme
npm install --save-dev enzyme
也可以使用react官方测试插件react-addons-test-utils,此处我们使用enzyme,故不需要安装。
此外,还需要根据使用的react版本来安装enzyme-adapter-react。具体版本对照如下
enzyme-adapter-react版本 | react版本 | ||
---|---|---|---|
enzyme-adapter-react-16 | ^16.4.0-0 | ||
enzyme-adapter-react-16.3 | ~16.3.0-0 | ||
enzyme-adapter-react-16.2 | ~16.2 | ||
enzyme-adapter-react-16.1 | `~16.0.0-0 | ~16.1` | |
enzyme-adapter-react-15 | ^15.5.0 | ||
enzyme-adapter-react-15.4 | 15.0.0-0 - 15.4.x | ||
enzyme-adapter-react-14 | ^0.14.0 | ||
enzyme-adapter-react-13 | ^0.13.0 |
此处demo使用的react版本为^16.4.1,所以我们需要安装enzyme-adapter-react-16
npm install --save-dev enzyme-adapter-react-16
依赖安装完成,接下来需要进行相关的配置。
首先配置package.json的测试命令test: "jest"。
此时如果我们在根目录下创建一个.test.js文件,并书写简单的方法用例,执行测试命令,是可以正常执行测试用例的。但是,我们的项目却并不是简单的单个方法但测试,实际项目中会存在这大量的组件依赖,还有css,image等静态资源的处理。所以,还要进行如下配置处理。
首先,我们在package.json文件中新增一个jest的配置项
jest: {}
这里我们主要进行三个配置。
moduleFileExtensions代表支持加载的文件名。此处我们的测试文件均以.js结尾,所以只配置成["js"]即可
transform用于编译 ES6/ES7 语法,需配合 babel-jest 使用
moduleNameMapper代表需要被 Mock 的资源名称。如果需要 Mock 静态资源(如less、scss等),则需要配置 Mock 的路径
jest默认会检索项目内的*.test.js,*.test.jsx形式的文件并执行。当编写当用例没被jest检索到时,可通过moduleDirectories来配置路径。
在具体到组件测试时,为了测试组件到交互性,我们需要jest渲染出组件进行操作,此时,由于我们到项目中大量使用来webpack到依赖管理,以及less-loader、url-loader等预编译。在jest渲染组件是,无法识别这些.less等文件。所以我们需要通过mock来处理这些静态文件。因为jest在渲染组件时,是不需要依赖css,image等静态资源的。所以我们可以这样配置:
".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/fileMock.js", ".(css|less)$": " /__mocks__/styleMock.js"
前面通过正则来适配我们需要匹配的静态文件,后面为我们通过mock返回的数据。这里我们还需要在根目录中创建__mock__的文件夹。在里面新建fileMock.js和styleMock.js两个文件。
module.exports = "test-file-stub";
module.exports = {};
这样就可以将测试集中在组件的结构和逻辑上。另外,可能在我们的项目中,会使用大量的别名来简化引用路径,及webpack中的alias配置。此处同样需要进行别名的配置,配置方式与静态资源配置类似。一下是完整配置
"jest": { "moduleFileExtensions": [ "js", "jsx" ], "moduleDirectories": [ "src", "node_modules" ], "transform": { "^.+.js$": "babel-jest" }, "moduleNameMapper": { "^components(.*)$": "/src/components$1", "^pages(.*)$": " /src/pages$1", "^utils(.*)$": " /src/utils$1", "^services(.*)$": " /src/services$1", "^static(.*)$": " /src/static$1", "^models(.*)$": " /src/models$1", "^variable(.*)$": " //src/static/less/variable.less", ".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": " /__mocks__/fileMock.js", ".(css|less)$": " /__mocks__/styleMock.js" } }
接下来创建一个待测试的组件,在src > pages文件夹中创建login组件,并配置好路由。组件代码参考测试Demo项目
运行后页面如下
接着,定义测试用例,此Demo定义来八个测试用例如下
1、页面title显示“登录”(UI)
2、登录账号输入手机号或邮箱时,账号上方显示登录账号
3、登录账号输入不为手机号或邮箱,账号上方显示【账户输入错误,请重新输入】
4、账号输入正常,密码小于6位,登录按钮置灰。
5、账号输入异常,密码不小于6位,登录按钮置灰。
6、账号输入正常,密码不小于6位,登录按钮可点。
7、点击密码后眼睛图标,显示密码。
8、显示密码状态,再次点击,隐藏密码。
接下来,新建文件login.test.js来编写测试用例代码。
由于用例中设计多个交互,所以我们需要先渲染出组件。Enzyme为我们提供来三种渲染组件的方法shallow、render、mount。
shallow 方法就是官方的shallow rendering的封装。
render 方法将React组件渲染成静态的HTML字符串,然后分析这段HTML代码的结构,返回一个对象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析库Cheerio,它返回的是一个Cheerio实例对象。
mount方法用于将React组件加载为真实DOM节点。
三种方法中,shallow render 返回的为对象,用于分析HTML结构,所以无法用于交互测试。mount方法加载的为真实的DOM节点,所以可用于交互测试。本Login组件存在大量交互测试,所以使用mount创建组件,使用mount需要先使用Adapter配置如下
import Login from "pages/Login"; import React from "react"; import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; import { mount } from "enzyme"; configure({ adapter: new Adapter() }); const wrapper = mount();
现在,我们就可以使用Enzyme的API来编写测试用例了,Enzyme提供了丰富的类jquery风格的API,下面是部分API
.get(index):返回指定位置的子组件的DOM节点 .at(index):返回指定位置的子组件 .first():返回第一个子组件 .last():返回最后一个子组件 .type():返回当前组件的类型 .text():返回当前组件的文本内容 .html():返回当前组件的HTML代码形式 .props():返回根组件的所有属性 .prop(key):返回根组件的指定属性 .state([key]):返回根组件的状态 .setState(nextState):设置根组件的状态 .setProps(nextProps):设置根组件的属性
完整API参见 Enzyme API
在前半部分的demo中,我们使用来 test() 方法来编写用例,此处,我们使用
describe("", () => { it("", () => {}) })
来编写测试用例,这样我们可以对测试用例进行分组
让我们来开始第一个用例“页面title显示「登录」”的编写
it("标题显示", () => { const title = wrapper.find(".title").text(); expect(title).toBe("登录"); })
这个用例十分简单,仅仅在第一步获取到了title中的文本,并对文本进行校验。
第二个和第三个用例为对输入框输入文本对校验,此处,我们可以多带带对校验方法进行测试,也可以页面对交互来完成测试。这里用例通过交互来进行测试用例对编写。由于在输入信息过程中,校验通过input框的onChange事件触发,所以我们需要用到 simulate 来触发事件。其中一个用例如下
const accountInput = wrapper.find(".account").find("input"); const accountTitle = wrapper.find(".account .name").find("span"); it("输入不合法账号", () => { const event = { target: { value: "abc123" } } accountInput.simulate("change", event); expect(accountTitle.text()).toBe("账户输入错误,请重新输入"); })
模拟输入来一个不合法的账号‘abc123’,验证失败,显示失败信息。
在4,5,6三个用例中,需要获取登录按钮Button组件的可点击状态,由于enzyme无法获取 css 状态,此时可以使用API中的prop(key)来获取组件的props状态,从而判断组件的可点击状态。其中一个用例如下
it("输入正确账号,密码小于6位,指定状态", () => { wrapper.setState({ account: "18888888888", password: "12345", errorAccount: false }); // 此处需重新获取btn对象,否则会导致用例失败 const submitBtn = wrapper.find(".btn-box").find("Button"); expect(submitBtn.props().disabled).toBe(true); })
此处通过直接设置state的值来更改Button的状态。需要注意的是,为来减少重复定义,许多Dom对象的获取都在describe组下做了统一的定义,但在执行expect获取按钮状态是,需要重新查找,来获取最新但状态。除了直接指定state状态之外,还可以通过输入框输入,change事件触发但方式来完成用例,如下
it("输入正确账号,密码小于6位,通过change触发", () => { const accountEvent = { target: { value: "18888888888" } }; const pwdEvent = { target: { value: "12345" } } accountInput.simulate("change", accountEvent); passwordInput.simulate("change", pwdEvent); const submitBtn = wrapper.find(".btn-box").find("Button"); expect(submitBtn.prop("disabled")).toBe(true);
7、8两个用例使用但方法与上面相同,不再赘述。
所有用例编写完成之后,执行npm run test可以看到所有用例都通过测试。
测试覆盖率在 package.json 文件的 test 命令修改为
test: "jest --coverage"
执行 npm run test即可在用例执行信息后显示用例的覆盖率报告。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101149.html
摘要:前端开发需要了解的工具集合前端开发需要了解的一些工具,这些工具能够帮助你在项目开发中事半功倍。总之,是前端打包的不二选择。所以,很多情况下都是与配合使用。它的一个理念就是提供一套完整集成的零配置测试体验。 前端开发需要了解的工具集合:webpack, eslint, prettier, ... 前端开发需要了解的一些工具,这些工具能够帮助你在项目开发中事半功倍。 1. nrm: npm...
摘要:前端开发需要了解的工具集合前端开发需要了解的一些工具,这些工具能够帮助你在项目开发中事半功倍。总之,是前端打包的不二选择。所以,很多情况下都是与配合使用。它的一个理念就是提供一套完整集成的零配置测试体验。 前端开发需要了解的工具集合:webpack, eslint, prettier, ... 前端开发需要了解的一些工具,这些工具能够帮助你在项目开发中事半功倍。 1. nrm: npm...
摘要:单元测试相关词条白盒测试,抛开,将项目分割成若干的单元,进行业务逻辑的测试。下面主要说一下组件和单元测试由于是基于的单页应用,每个页面,或者说组件的基本结构分为四部分储存业务逻辑,囊括了相关的和,只进行渲染,负责链接和。 原文链接:Redux Testing Step by Step: A Simple Methodology for Testing Business Logic 测试...
摘要:单元测试相关词条白盒测试,抛开,将项目分割成若干的单元,进行业务逻辑的测试。下面主要说一下组件和单元测试由于是基于的单页应用,每个页面,或者说组件的基本结构分为四部分储存业务逻辑,囊括了相关的和,只进行渲染,负责链接和。 原文链接:Redux Testing Step by Step: A Simple Methodology for Testing Business Logic 测试...
阅读 1068·2021-11-24 10:24
阅读 2560·2021-11-22 13:54
阅读 947·2021-09-24 09:55
阅读 3571·2019-08-30 15:54
阅读 1288·2019-08-30 15:44
阅读 1067·2019-08-30 14:23
阅读 3179·2019-08-29 13:45
阅读 1202·2019-08-29 11:19