react 中的测试

    xiaoxiao2025-05-15  8

    得益于 React 的组件化开发,测试应用变得很简单。我们可以用许多工具编写 React 测试。 Jest 是一套完备的测试框架方案,由 Facebook 的 Christopher Pojer 以及社区中的多名贡献者 所维护,它致力于提供最佳的开发体验;你也可以选择用 Mocha 自行搭建框架。本章将介绍构 建最佳测试环境的这两种方式。

    jest

    Jest是一个JavaScript测试框架 它适用于以下项目:Babel,TypeScript,Node,React,Angular,Vue等等 它可以接受配置文件或者命令行参数进行配置 Jest 会在源代码文件夹中寻找以.spec、.test 结尾的文件,或者位于__tests__目 录下的文件执行

    首先在你的package.json 的scripts 中配置如下

    "scripts": { "test": "jest --coverage" },

    --coverage参数是用来查看测试覆盖率的 他是集成了 Istanbul 这个库来实现的 --runInBand在当前进程运行所有测试 --verbose层次显示测试套件中每个测试的结果

    接下来写几个简单的js 测试

    编写sum.js

    function sum(a, b) { return a + b; } module.exports = sum;

    创建__test__目录 编写sum.test.js

    const sum = require('../sum'); //简单测试函数结果 it('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });

    然后执行npm test 运行测试 并可以看到代码的测试覆盖率 点此查看更多用例

    用jest 测试react 组件

    首先我们新建一个目录

    安装如下依赖

    "devDependencies": { "@babel/preset-env": "^7.4.5", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.4.4", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-register": "^6.26.0", "chai": "^4.2.0", "chai-spies": "^1.0.0", "install": "^0.12.2", "jsdom": "^15.1.0", "mocha": "^6.1.4", "npm": "^6.9.0", "react-test-renderer": "^16.8.6", "sinon": "^7.3.2", "sinon-chai": "^3.3.0" }, "dependencies": { "react": "^16.8.6", "react-dom": "^16.8.6" }

    编写.babelrc 文件

    { "presets": [ [ "@babel/preset-env" ], "@babel/preset-react" ] }

    编写一个最简单的react组件

    import React from 'react'; class Button extends React.Component{ render(){ return( <button onClick={this.props.onClick}>{this.props.text}</button> ) } } export default Button;

    接下来我们就为这个button 组件编写测试 ,其实在TDD的模式下 是先编写测试,然后再来实现组件的。完整的测试有利于业务逻辑的梳理和后期重构 我们来编写button.spec.js

    import React from 'react' import ShallowRenderer from 'react-test-renderer/shallow'; import { renderIntoDocument , findRenderedDOMComponentWithTag , Simulate, } from 'react-dom/test-utils'; import Button from './button'; test('works', () => { expect(true).toBe(true) }) // 浅渲染测试 在测试环境中渲染组件 // 浅渲染允许你按一级深度渲染组件,然后根据它返回的渲染结果进行一些预测 test('renders with text', () => { const text = 'text'; const renderer = new ShallowRenderer(); renderer.render(<Button text={text} />); const result = renderer.getRenderOutput(); expect(result.props.children).toBe(text) }) test("fires the onClick callBack",()=>{ const onClick = jest.fn() // 将React元素渲染到文档中的分离DOM节点中 Button const tree = renderIntoDocument( <Button onClick={ onClick } /> ) // 这个函数会根据传入的标签名在渲染树中查找组件 HTMLButtonElement const button = findRenderedDOMComponentWithTag( tree, 'button' ); // 使用可选eventData事件数据模拟DOM节点上的事件调度 Simulate.click(button); // 这里简单地表明我们希望 mock 函数被调用 expect(onClick).toBeCalled() })

    这里要提下浅渲染与完整 DOM 渲染的区别

    浅渲染只渲染一级组件对子组件不作处理

    然后运行npm test 来执行测试 github demo

    mocha

    Mocha(发音"摩卡")诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用

    新建目录 package.json 中添加

    "scripts": { "test": "mocha -r @babel/register" }

    依赖如下

    "devDependencies": { "@babel/preset-env": "^7.4.5", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.4.4", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-register": "^6.26.0", "chai": "^4.2.0", "chai-spies": "^1.0.0", "install": "^0.12.2", "jsdom": "^15.1.0", "mocha": "^6.1.4", "npm": "^6.9.0", "react-test-renderer": "^16.8.6", "sinon": "^7.3.2", "sinon-chai": "^3.3.0" }, "dependencies": { "react": "^16.8.6", "react-dom": "^16.8.6" }

    .babelrc

    { "presets": [ [ "@babel/preset-env" ], "@babel/preset-react" ] }

    编写button.js

    import React from 'react'; class Button extends React.Component{ render(){ return( <button onClick={this.props.onClick}>{this.props.text}</button> ) } } export default Button;

    mocha 默认解析的是test目录下的文件所以新建test/button.spec.js

    // Chai是 node 和浏览器的BDD /TDD断言库,可以与任何javascript测试框架愉快地配对 import chai from 'chai'; import sinon from "sinon"; // 使用Sinon.JS模拟框架的断言扩展Chai import sinonChai from "sinon-chai"; import { JSDOM } from 'jsdom'; import ShallowRenderer from 'react-test-renderer/shallow'; import React from 'react'; import Button from '../button'; import { renderIntoDocument , findRenderedDOMComponentWithTag , Simulate, } from 'react-dom/test-utils'; chai.should(); chai.use(sinonChai); const expect = chai.expect; const { window } = new JSDOM(`...`); // or even const { document } = (new JSDOM(`...`)).window; global.document = document; global.window = window; function hello(name, cb) { cb("hello " + name); } //描述按钮的行为 describe('Test for Button', () => { // 这里我们希望元素类型和文本是正确的 it('renders with text', () => { //定义文本变量,以判断预测代码是否有效: const text = 'text'; // 浅渲染 const renderer = new ShallowRenderer(); renderer.render(<Button text={text} />); const button = renderer.getRenderOutput(); expect(button.type).to.equal('button') expect(button.props.children).to.equal(text) }) it('fires the onClick callback', () => { const onClick = sinon.spy(); hello("foo", onClick); // 将React元素渲染到文档中的分离DOM节点中 Button const tree = renderIntoDocument( <Button onClick={ onClick } /> ) // 这个函数会根据传入的标签名在渲染树中查找组件 HTMLButtonElement const button = findRenderedDOMComponentWithTag( tree, 'button' ); // 使用可选eventData事件数据模拟DOM节点上的事件调度 Simulate.click(button); // expect(onClick).to.have.been.calledWith("hello foo"); }) })

    github demo

    enzyme

    Enzyme是React的JavaScript测试实用程序,可以更轻松地测试React Components的输出 ,他配合react使用起来更加方便

    具体代码

    最新回复(0)