2017年8月8日 星期二

React.js (5) - 用 Mocha 做 React Unit Test

React 進行測試,通常會使用 Mocha (, Chai) ,另外還有 react-addons-test-utils, jsdom 這樣的工具來對 JSX 內容作測試。

React Unit Test 的 Package.json

Package.json 需要增加的套件有: (請自行手動加入在 React 專案的 package.json 欄位)


{
"scripts": {
    "test": "mocha --compilers js:babel-core/register ./test/* --require ./test/test_helper.js"
  },
"devDependencies": {
    "babel-core": "^6.4.5",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "chai": "^3.5.0",
    "jsdom": "^8.1.0",
    "mocha": "^2.4.5",
    "react-addons-test-utils": "^15.2.0"
  }
}

寫好之後,進行測試需要 babel 支持,還要增加一個 .babelrc 的檔案放在專案主目錄,並增加測試工具描述:
{
     "presets": ["es2015", "react"]
}

接著,測試檔案跑 `=>` arrow function 有可能還會出錯,必須安裝另外一個套件,另 ()=>{} 這樣的寫法不會出錯:

npm install babel-plugin-transform-class-properties  --save-dev
然後,要在 .babelrc 檔案加入 plugin 描述,令 .babelrc 檔案為:
{
    "presets": ["es2015", "react"],
    "plugins": ["transform-class-properties"]
}

完成後,就跑一次 npm install 或 yarn add ,令新增的套件被安裝。

建立測試必須要的 DOM 環境

測試 React 之前,可以看見上一個章節的 package.json 中的 scripts 欄位,整體而言是我指定要測試 ./test/* 的全部腳本,然後提供一個 ./test/test_helper.js 來當作我的 DOM 環境。

./test/test_helper.js 是這樣寫的:
import jsdom from 'jsdom';

if (typeof document === 'undefined') {
    global.document = jsdom.jsdom('');
    global.window = document.defaultView;
    global.navigator = global.window.navigator;
}

撰寫測試檔案

完成環境建置後,就可以在 ./test/ 目錄底下自行新增隨意腳本,進行測試,以下設寫隨意腳本進行解釋:

import React from 'react'
import ReactDOM from 'react-dom'
import TestUtils from 'react-addons-test-utils'; //導入測試工具
import {expect} from 'chai';

import jsdom from 'jsdom';

import TextInput from '../src/components/TextInput.js';
import TextShow from '../src/components/TextShow.js';

describe('TextInput', function(){

    global.document = jsdom.jsdom();
    global.window = document.defaultView;
        
    //自己定義一個處理 function
    this.content = 'cool';
    const handleChange = (nv)=>{
         console.log("you clicked!");
         this.content = nv;
    }

    this.ti = TestUtils.renderIntoDocument(<TextInput onItemAdd={handleChange} content={this.content} />);

    //檢查元素是否被渲染
    it('should appears in view', ()=>{
        const shallowRender = TestUtils.createRenderer();
        shallowRender.render(<TextInput />);
        const result = shallowRender.getRenderOutput();
        expect(result.type).to.be.equal('div');
    });
 
    //測試 change, TestUtils 會提供各種測試工具,請參考官網: https://facebook.github.io/react/docs/test-utils.html
    it('input text\'s', ()=>{
        const c = ReactDOM.findDOMNode(this.ti);
        TestUtils.Simulate.change(c, { target : {value: '12345'} });
    })
});

describe('TextShow', ()=>{
    it('should appears in view', ()=>{
        const shallowRender = TestUtils.createRenderer();
        shallowRender.render(<TextShow />);
        const result = shallowRender.getRenderOutput();
        expect(result.type).to.be.equal('h1')
    })
})

測試

完成腳本撰寫後,跑 npm test 就可以進行測試。


Reference:
https://facebook.github.io/react/docs/test-utils.html
http://jason-wang.logdown.com/posts/664579-react-unit-test-simple-tests-using-chai-and-mocha
https://github.com/jantimon/html-webpack-plugin/issues/596
https://stackoverflow.com/questions/35345000/equal-sign-in-bad-place-causes-unknown-token-exception
http://ithelp.ithome.com.tw/users/20078318/ironman/1106?page=1
https://github.com/Khan/react-components/blob/master/test/blur-input-test.jsx
https://stackoverflow.com/questions/37368013/testing-with-mocha-es6-unexpected-token-import
https://stackoverflow.com/questions/35517245/error-missing-class-properties-transform
https://github.com/airbnb/enzyme/issues/684
https://www.toptal.com/react/how-react-components-make-ui-testing-easy
http://mherman.org/blog/2015/09/10/testing-node-js-with-mocha-and-chai/#.WY0QXISGOUk

沒有留言:

張貼留言

© Mac Taylor, 歡迎自由轉貼。
Background Email Pattern by Toby Elliott
Since 2014