引子
在之前分享的編輯器相關(guān)文章里,講到了語(yǔ)雀是全棧js開發(fā)的,并且號(hào)稱團(tuán)隊(duì)沒有測(cè)試工程師,參考文章里面有放關(guān)于全棧 JavaScript 測(cè)試的相關(guān)總結(jié)分享,今天我們就聊一聊前端的測(cè)試。
單元測(cè)試
- 定義:
在計(jì)算機(jī)編程中,單元測(cè)試(Unit Testing)又稱為模塊測(cè)試,是針對(duì)程序模塊(軟件設(shè)計(jì)的最小單位)來(lái)進(jìn)行正確性檢驗(yàn)的測(cè)試工作。
程序單元是應(yīng)用的最小可測(cè)試部件。在過(guò)程化編程中,一個(gè)單元就是單個(gè)程序、函數(shù)、過(guò)程等;對(duì)于面向?qū)ο缶幊蹋钚卧褪欠椒?,包括基類(超類)、抽象類、或者派生類(子類)中的方法?/p>
- 意義
- 提升能力
- 提升效率:及早發(fā)現(xiàn)問(wèn)題
- 追求卓越:有助于開發(fā)人員去思考代碼結(jié)構(gòu)的設(shè)計(jì),讓代碼更加有利于測(cè)試
- 覆蓋全面:能夠覆蓋到QA測(cè)試覆蓋不到的情況
- 大型項(xiàng)目,協(xié)同開發(fā),公共抽離組件會(huì)出現(xiàn)一些問(wèn)題,有了單測(cè)后,更強(qiáng)壯,更易讀,升級(jí)時(shí),回歸測(cè)試任務(wù)少,提升公共組件的質(zhì)量。
- 測(cè)試方法論 TDD&BDD
- TDD:Test-driven development 測(cè)試驅(qū)動(dòng)開發(fā)
TDD 從測(cè)試的角度來(lái)檢驗(yàn)整個(gè)項(xiàng)目。大概的流程是先針對(duì)每個(gè)功能點(diǎn)抽象出接口代碼,然后編寫單元測(cè)試代碼,接下來(lái)實(shí)現(xiàn)接口,運(yùn)行單元測(cè)試代碼,循環(huán)此過(guò)程,直到整個(gè)單元測(cè)試都通過(guò)。 - BDD:Behavior Driven Development 行為驅(qū)動(dòng)開發(fā)
是通過(guò)編寫行為和規(guī)范來(lái)驅(qū)動(dòng)軟件開發(fā)。更注重功能本身。
- 原則:FIRST
- F fast 快速 過(guò)程快
- I Isolate 隔離 測(cè)試用例應(yīng)當(dāng)獨(dú)立執(zhí)行,避免一個(gè)測(cè)試結(jié)果依賴于另外一個(gè)。需要把測(cè)試分解成盡可能小的單元,這將幫我們確定在錯(cuò)誤發(fā)生時(shí)的確切代碼位置。
- R Repeatable 可重復(fù):多次運(yùn)行測(cè)試應(yīng)該產(chǎn)生相同的結(jié)果,如果不確定,就不知道哪些結(jié)果是有效的,哪些又是無(wú)效的。另外,反復(fù)性可以確保我們的測(cè)試不依賴于外部因素(諸如網(wǎng)絡(luò)或 CPU 負(fù)載)。
- S Self-validating 自我驗(yàn)證無(wú)需人工
- T Timely 及時(shí),上線前
測(cè)什么
結(jié)果正確
邊界條件檢查
反向關(guān)聯(lián)(加密解密 讀寫操作)
強(qiáng)制錯(cuò)誤條件測(cè)試的核心
斷言(assert)即表達(dá)程序設(shè)計(jì)人員對(duì)于系統(tǒng)應(yīng)達(dá)到狀態(tài)的一種預(yù)期。
前端測(cè)試框架:
幫助我們把測(cè)試代碼抽離出來(lái),作為一個(gè)整體結(jié)構(gòu)化地去設(shè)計(jì)測(cè)試用例,放置到專門測(cè)試文件,然后也可以實(shí)現(xiàn)自動(dòng)運(yùn)行以及顯示測(cè)試結(jié)果。
介紹:
Mocha,Jest,Jasmine 可以說(shuō)都是測(cè)試框架,可以達(dá)到之前說(shuō)的,抽離,結(jié)構(gòu)化,自動(dòng)運(yùn)行等等,其中 Jest 是一個(gè)相當(dāng)全面的框架,且零配置,同時(shí)需要注意的是 Jest 也是基于 Jasmine 的,所以 Jest 的一些語(yǔ)法和 Jasmine 一模一樣,連報(bào)錯(cuò)有時(shí)都會(huì)相同。
Chai,Should 都屬于斷言庫(kù),它們的 API 相對(duì)測(cè)試框架自帶的斷言 API 更加語(yǔ)義化,更好用,可以和上面的測(cè)試框架結(jié)合著用。
Karma 是一個(gè) Test-Runner,可以說(shuō)是凌駕測(cè)試框架之上,可以讓給你的瀏覽器自動(dòng)跑所有的測(cè)試用例。
Enzyme是由airbnb開發(fā)的React單元測(cè)試工具。它擴(kuò)展了React的TestUtils并通過(guò)支持類似jQuery的find語(yǔ)法可以很方便的對(duì)render出來(lái)的結(jié)果做各種斷言。
Jest
https://github.com/facebook/jest star 36.2k
Jest是Facebook開發(fā)的一個(gè)測(cè)試框架,它集成了測(cè)試執(zhí)行器、斷言庫(kù)、spy、mock、snapshot和測(cè)試覆蓋率報(bào)告等功能。React項(xiàng)目本身也是使用Jest進(jìn)行單測(cè)的,因此契合度相當(dāng)高。
- 自帶斷言函數(shù)
exspect(運(yùn)行結(jié)果).toBe(期望的結(jié)果);
//常見斷言方法
expect({a:1}).toBe({a:1})//判斷兩個(gè)對(duì)象是否相等
expect(1).not.toBe(2)//判斷不等
expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 2 } })//判斷相等
expect(n).toBeNull(); //判斷是否為null
expect(n).toBeUndefined(); //判斷是否為undefined
expect(n).toBeDefined(); //判斷結(jié)果與toBeUndefined相反
expect(n).toBeTruthy(); //判斷結(jié)果為true
expect(n).toBeFalsy(); //判斷結(jié)果為false
expect(value).toBeGreaterThan(3); //大于3
expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5
expect(value).toBeLessThan(5); //小于5
expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5
expect(value).toBeCloseTo(0.3); // 浮點(diǎn)數(shù)判斷相等
expect('Christoph').toMatch(/stop/); //正則表達(dá)式判斷
expect(['one','two']).toContain('one'); //包含
- 支持異步測(cè)試
- 支持Dom測(cè)試
- Mock Functions
一個(gè)簡(jiǎn)單的示例:
- 安裝
npm install --save-dev jest - 新建測(cè)試文件
unit.test.js
import {dealData} from "./src/util/Util";
describe("dealData測(cè)試",()=>{
test('dealData 1 GB to equal 1 GB', () => {
expect(dealData(1, 'GB')).toEqual({
value:1,
unit:'GB'
});
});
//輸入數(shù)據(jù)大于1024GB則轉(zhuǎn)換為TB
test('dealData 2048 GB to equal 2 TB', () => {
expect(dealData(2048, 'GB')).toEqual({
value:2,
unit:'TB'
});
});
//輸入數(shù)據(jù)大于1024*1024*10GB則轉(zhuǎn)換為PB
test('dealData 20971520 GB to equal 20 PB', () => {
expect(dealData(20971520, 'GB')).toEqual({
value:20,
unit:'PB'
});
});
//PB為最大單位,不進(jìn)行進(jìn)一步處理
test('dealData 419430400 GB to equal 20 PB', () => {
expect(dealData(41943040000, 'GB')).toEqual({
value:40000,
unit:'PB'
});
});
//其他單位不進(jìn)行轉(zhuǎn)換
test('dealData 1 KB to equal 1 KB', () => {
expect(dealData(1, 'KB')).toEqual({
value:1,
unit:'KB'
});
});
//接口異常時(shí)數(shù)據(jù)不進(jìn)行轉(zhuǎn)換
test('dealData -- to equal --', () => {
expect(dealData('--', '')).toEqual({
value:'--',
unit:''
});
});
})
注:dealData 是一個(gè)抽離出來(lái)的工具函數(shù),幫助動(dòng)態(tài)處理業(yè)務(wù)數(shù)據(jù)單位
- 在
package.json中增加代碼
{
"scripts": {
"test": "jest"
}
}
- 運(yùn)行
npm run test
image.png
Enzyme
https://github.com/enzymejs/enzyme star 19.7k
React測(cè)試必須使用官方的測(cè)試工具庫(kù),但是它用起來(lái)不夠方便,所以有人做了封裝,推出了一些第三方庫(kù),其中Airbnb公司的Enzyme最容易上手。
項(xiàng)目實(shí)戰(zhàn)時(shí),結(jié)合jest和enzyme。
Enzyme為我們提供來(lái)三種渲染組件的方法shallow、render、mount。
shallow 方法就是官方的shallow rendering的封裝。
render 方法將React組件渲染成靜態(tài)的HTML字符串,然后分析這段HTML代碼的結(jié)構(gòu),返回一個(gè)對(duì)象。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析庫(kù)Cheerio,它返回的是一個(gè)Cheerio實(shí)例對(duì)象。
mount方法用于將React組件加載為真實(shí)DOM節(jié)點(diǎn)。
測(cè)試登錄交互例子:
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 />);
describe('', () => {
it('標(biāo)題顯示', () => {
const title = wrapper.find('.title').text();
expect(title).toBe('登錄');
})
const accountInput = wrapper.find('.account').find('input');
const accountTitle = wrapper.find('.account .name').find('span');
it('輸入不合法賬號(hào)', () => {
const event = {
target: {
value: 'abc123'
}
}
accountInput.simulate('change', event);
expect(accountTitle.text()).toBe('賬戶輸入錯(cuò)誤,請(qǐng)重新輸入');
})
})
uirecorder
https://github.com/alibaba/uirecorder star 1.8k
UI Recorder 是一款面向多端的 UI 自動(dòng)化錄制工具,類似于Selenium IDE 但比Selenium IDE 更加強(qiáng)大!
UI Recorder 非常簡(jiǎn)單易用,零成本解決測(cè)試回歸問(wèn)題。
功能:
- 支持所有用戶行為: 鍵盤事件, 鼠標(biāo)事件, alert, 文件上傳, 拖放, svg, shadow dom
- 全平臺(tái)支持,移動(dòng)端 Android, iOS 錄制, 基于 Macaca 實(shí)現(xiàn)
- 無(wú)干擾錄制: 和正常測(cè)試無(wú)任何區(qū)別,無(wú)需任何交互
- 錄制用例存儲(chǔ)在本地
- 支持豐富的斷言類型: val,text,displayed,enabled,selected,attr,css,url,title,cookie,localStorage,sessionStorage
- 支持圖片對(duì)比
- 支持強(qiáng)大的變量字符串
- 支持公共測(cè)試用例: 允許用例中動(dòng)態(tài)調(diào)用另外一個(gè)
- 支持并發(fā)測(cè)試
- 支持多國(guó)語(yǔ)言: 英文, 簡(jiǎn)體中文, 繁體中文
- 支持單步截圖
- 支持HTML報(bào)告和JUnit報(bào)告
- 全系統(tǒng)支持: Windows, Mac, Linux
- 基于Nodejs的測(cè)試用例: jWebDriver
官方教程:https://www.yuque.com/artist/uirecorder/yd7ztf
- 初始化工程
- 開始錄制,進(jìn)行界面操作,可以添加斷言,懸停等等
- 結(jié)束錄制,自動(dòng)生成腳本文件
- 利用已有腳本文件進(jìn)行回歸測(cè)試
