Jest + Enzyme 前端自动化测试

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

会看到用例测试经由过程的信息

《Jest + Enzyme 前端自动化测试》

由于我们的要领没有做入参范例检测,下面经由过程传入字符串,来测试异常情况。在sort.test.js中新增一个测试用例用例

    test('排序字符串“52431”', () => {
        expect(sort('52431')).toEqual(12345);
    })

运转,则会看到测试失利的信息

《Jest + Enzyme 前端自动化测试》

从测试效果中我们能够消灭的看到,运转来两个测试用例,第一个用例经由过程来,第二个用例运转是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.415.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文件,并誊写简朴的要领用例,实行测试敕令,是能够一般实行测试用例的。然则,我们的项目却并非简朴的单个要领但测试,现实项目中会存在这大批的组件依靠,另有cssimage等静态资本的处置惩罚。所以,还要举行以下设置处置惩罚。

起首,我们在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-loaderurl-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)$": "<rootDir>/__mocks__/fileMock.js",
    "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"

前面经由过程正则来适配我们须要婚配的静态文件,背面为我们经由过程mock返回的数据。这里我们还须要在根目录中建立__mock__的文件夹。在里面新建fileMock.jsstyleMock.js两个文件。

    <!--fileMock.js-->
    module.exports = 'test-file-stub';
    <!--styleMock.js-->
    module.exports = {};

如许就能够将测试集合在组件的构造和逻辑上。别的,可能在我们的项目中,会运用大批的别号来简化援用途径,及webpack中的alias设置。此处一样须要举行别号的设置,设置体式格局与静态资本设置相似。一下是完全设置

    "jest": {
        "moduleFileExtensions": [
            "js",
            "jsx"
        ],
        "moduleDirectories": [
            "src",
            "node_modules"
        ],
        "transform": {
            "^.+\\.js$": "babel-jest"
        },
        "moduleNameMapper": {
            "^components(.*)$": "<rootDir>/src/components$1",
            "^pages(.*)$": "<rootDir>/src/pages$1",
            "^utils(.*)$": "<rootDir>/src/utils$1",
            "^services(.*)$": "<rootDir>/src/services$1",
            "^static(.*)$": "<rootDir>/src/static$1",
            "^models(.*)$": "<rootDir>/src/models$1",
            "^variable(.*)$": "<rootDir>//src/static/less/variable.less",
            "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
            "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
        }
  }

接下来建立一个待测试的组件,在src > pages文件夹中建立login组件,并设置好路由。组件代码参考测试Demo项目
运转后页面以下

<img src=”https://github.com/ISummerRai…; width=”320″ />

接着,定义测试用例,此Demo定义来八个测试用例以下

  • 1、页面title显现“登录”(UI)
  • 2、登录账号输入手机号或邮箱时,账号上方显现登录账号
  • 3、登录账号输入不为手机号或邮箱,账号上方显现【账户输入毛病,请从新输入】
  • 4、账号输入一般,暗码小于6位,登录按钮置灰。
  • 5、账号输入异常,暗码不小于6位,登录按钮置灰。
  • 6、账号输入一般,暗码不小于6位,登录按钮可点。
  • 7、点击暗码后眼睛图标,显现暗码。
  • 8、显现暗码状况,再次点击,隐蔽暗码。

接下来,新建文件login.test.js来编写测试用例代码。
由于用例中设想多个交互,所以我们须要先衬着出组件。Enzyme为我们供应来三种衬着组件的要领shallowrendermount

  • 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(<Login />);

如今,我们就能够运用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://segmentfault.com/a/1190000017930406
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞