寫在開頭: html
單元測試對於不少人比較模式,它是一種推進開發,或者提升產品質量的手段, 前端
我畫一張圖,你們就能理解react
其實單元測試,就是先編寫單元測試代碼,而後使用單元測試框架,去模擬環境(例如瀏覽器),而後運行你的代碼,看代碼是否按預期運行web
這裏爲了下降文章篇幅,對於初學者更友好,因而這裏使用我開源的通用腳手架,集成TypeScript+JavaScript混合開發,Jest框架,測試React組件、Enzyme、dva、Antd按需加載等主流技術~ 推薦你們使用npm
我開源的腳手架在npm上叫:ykj-cli json
使用步驟:後端
npm i ykj-cli -g 或 yarn add global ykj-cli ykj init project_name cd project_name yarn && yarn dev 便可打開看到頁面~
有什麼問題或者建議能夠提給我,我會即時改進,歡迎大家在項目中使用。我已經集成了PWA等功能,後期會按需加入更多可選功能瀏覽器
開始編寫第一個單元測試代碼antd
全部的測試代碼必須在test文件夾下,咱們的腳手架已經幫咱們作好了 app
新建一個app.test.tsx文件(必須是tsx結尾,由於要測試React組件)
一個合格的React項目,組件必須是tsx結尾,工具文件以ts結尾,聲明文件以.d.ts結尾
首先引入enzyme和React以及對應的組件
import App from '../src/app'; import { mount } from 'enzyme'; import React from 'react';
編寫單元測試代碼:
test('login test', async () => { console.log('App-mountComponent test function begin '); });
每一個test是一個單獨的測試函數,咱們使用封裝好腳手架封裝好的命令,測試一把看看
yarn test
發現沒有反應,這是爲何?由於裏面沒有寫任何單元測試代碼,此時咱們根據腳手架的實際文件來編寫單元測試代碼
import App from '../src/routers/home'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App />); expect(wrapper.find('.login_fade_in').children().length).toBe(8); console.log('App-mountComponent test function stop --success '); });
此時 yarn test 啓動測試
發現報錯,由於App組件是鏈接了dva的store數據中心,這裏沒有傳入props
那麼咱們能夠模擬傳入store嗎? 最簡單的方法,試試傳入一個空對象
import App from '../src/routers/home'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App store={{}}/>); expect(wrapper.find('.login_fade_in').children().length).toBe(8); console.log('App-mountComponent test function stop --success '); });
yarn test
啓動結果
發現報錯,測試沒有經過,那麼咱們要想辦法讓它測試經過,因而就要看看App.tsx組件須要什麼props~
import React, { Fragment } from 'react'; import { Button } from 'antd'; import { connect } from 'dva'; import './index.less'; interface Props { history: any; readonly count: number; dispatch: Function; list: Array<string>; }
這裏又要提到TypeScript是真香,個人腳手架支持TS和JS混合開發,趕忙來把~
一看原來須要傳入四個必須的參數,那麼咱們模擬一份吧,此次是認真的測試哦~
import App from '../src/routers/login'; import { mount } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = mount(<App Name="Peter Hello" changeShowContent={() => {}} />); expect(wrapper.find('.container').length).toBe(1); console.log('App-mountComponent test function stop --success '); });
上面單元測試代碼意思是:
這裏⚠️:若是是斷言,須要判斷值的,使用toBe,若是是
對象要進行比較的,使用toEqual
yarn test
測試結果經過,這就是一個最簡單的單元測試編寫,一般推薦根據需求先編寫單元測試代碼,再進行業務代碼編寫
而後生成單元測試報告
yarn test-c
此時能夠看到根目錄的coverage文件夾下有了lcov-report文件夾,進入後咱們直接打開裏面的index.html文件,能夠看到單元測試報告
這樣裏面有一些像分支覆蓋率、函數、代碼函數覆蓋等
其實像Jest用起來仍是比較方便的,核心理念就是使用測試框架運行業務代碼,再用單元測試代碼去檢測你的業務代碼,先後端單元測試理念其實都是同樣的思想,檢測代碼運行結果嘛。其餘的API這裏就不作解釋了,有興趣的能夠用ykj-cli這個腳手架試驗一把,上面的例子都在裏面,很是方便
前端單元測試還有一個很重要的一點,就是生成頁面快照
爲何要生成頁面快照?
你能夠先在某個時間端生成頁面快照,保存。
而後等部分代碼跑完後,再生成一次快照,跟以前的快照進行對比,這樣就能判斷你中間的這部分代碼有沒有影響UI,這樣能肯定有沒有BUG的出現
頁面快照:
import App from '../src/routers/login'; import { mount, shallow } from 'enzyme'; import React from 'react'; import toJson from 'enzyme-to-json'; //作快照 test('login test', async () => { console.log('App-mountComponent test function begin '); const wrapper = shallow(<App Name="Peter Hello" changeShowContent={() => {}} />); // toJson(wrapper, { // noKey: false, // mode: 'deep', // }); expect(wrapper).toMatchSnapshot() console.log('App-mountComponent test function stop --success '); });
這裏 expect(wrapper).toMatchSnapshot() 這行代碼,幫咱們在test文件夾下生成了__snapshots__文件夾
後面測試代碼中若是有操做改變了這個頁面,那麼就會報錯,單元測試不經過
下面的內容但願你也能認真看完
常見的單元測試代碼例子
單元測試的編寫難度可能比業務代碼難度更高,本文帶你入門,沒有問題,其餘的API須要你去多看文檔,學習,多寫。
推薦一些資料:
http://caibaojian.com/scb/enzyme.html
原創很累,感受有幫助,點個贊,關注下 前端巔峯
公衆號。推薦一下文章給須要的人吧