大前端測(cè)試

引子

在之前分享的編輯器相關(guān)文章里,講到了語(yǔ)雀是全棧js開發(fā)的,并且號(hào)稱團(tuán)隊(duì)沒有測(cè)試工程師,參考文章里面有放關(guān)于全棧 JavaScript 測(cè)試的相關(guān)總結(jié)分享,今天我們就聊一聊前端的測(cè)試。

單元測(cè)試

  1. 定義:

在計(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>

  1. 意義
  • 提升能力
  • 提升效率:及早發(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ì)量。
  1. 測(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ā)。更注重功能本身。
  1. 原則: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í),上線前
  1. 測(cè)什么
    結(jié)果正確
    邊界條件檢查
    反向關(guān)聯(lián)(加密解密 讀寫操作)
    強(qiáng)制錯(cuò)誤條件

  2. 測(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)單的示例:

  1. 安裝 npm install --save-dev jest
  2. 新建測(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ù)單位

  1. package.json中增加代碼
{
  "scripts": {
    "test": "jest"
  }
}
  1. 運(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)題。

功能:

  1. 支持所有用戶行為: 鍵盤事件, 鼠標(biāo)事件, alert, 文件上傳, 拖放, svg, shadow dom
  2. 全平臺(tái)支持,移動(dòng)端 Android, iOS 錄制, 基于 Macaca 實(shí)現(xiàn)
  3. 無(wú)干擾錄制: 和正常測(cè)試無(wú)任何區(qū)別,無(wú)需任何交互
  4. 錄制用例存儲(chǔ)在本地
  5. 支持豐富的斷言類型: val,text,displayed,enabled,selected,attr,css,url,title,cookie,localStorage,sessionStorage
  6. 支持圖片對(duì)比
  7. 支持強(qiáng)大的變量字符串
  8. 支持公共測(cè)試用例: 允許用例中動(dòng)態(tài)調(diào)用另外一個(gè)
  9. 支持并發(fā)測(cè)試
  10. 支持多國(guó)語(yǔ)言: 英文, 簡(jiǎn)體中文, 繁體中文
  11. 支持單步截圖
  12. 支持HTML報(bào)告和JUnit報(bào)告
  13. 全系統(tǒng)支持: Windows, Mac, Linux
  14. 基于Nodejs的測(cè)試用例: jWebDriver

官方教程:https://www.yuque.com/artist/uirecorder/yd7ztf

  • 初始化工程
  • 開始錄制,進(jìn)行界面操作,可以添加斷言,懸停等等
  • 結(jié)束錄制,自動(dòng)生成腳本文件
  • 利用已有腳本文件進(jìn)行回歸測(cè)試
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容