0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

前端領(lǐng)域的自動(dòng)化測(cè)試

冬至子 ? 來(lái)源:林不渡也不是不能渡 ? 作者:林不渡 ? 2022-10-12 10:35 ? 次閱讀

前言:前端領(lǐng)域的自動(dòng)化測(cè)試

一直以來(lái)對(duì)于前端同學(xué)來(lái)說(shuō),自動(dòng)化測(cè)試都是一個(gè)比較特殊的命題。一方面,大家其實(shí)都知道自動(dòng)化測(cè)試的好處,做了什么改動(dòng)只要跑一遍測(cè)試用例就知道有沒(méi)有改掛了之前的邏輯,進(jìn)行修改時(shí)也更有底氣。而另一方面,前端本身就具有特殊性,活動(dòng)頁(yè)從需求評(píng)審到正式上線可能在一周內(nèi)就完成了,這種迭代速度還寫(xiě)測(cè)試用例就是折磨自己。

但實(shí)際上,自動(dòng)化測(cè)試在前端工程中也是相當(dāng)重要的一部分。即使是快速迭代的活動(dòng)頁(yè)面,也會(huì)有通用的工具函數(shù)與 SDK,對(duì)這一部分的代碼進(jìn)行測(cè)試用例的完善是有必要且意義重大的,而對(duì)于某些流量巨大且長(zhǎng)期存在的頁(yè)面,我們甚至需要進(jìn)行多種測(cè)試場(chǎng)景的保障。

然而由于這兩種情況的存在,很多前端同學(xué)其實(shí)都對(duì)自動(dòng)化測(cè)試的認(rèn)知相當(dāng)空白,它有哪些分類?有哪些推薦的實(shí)踐?有哪些框架與方案?而這篇文章的目的就是進(jìn)行一個(gè)基礎(chǔ)的掃盲,至少完成閱讀以后你會(huì)知道如何為項(xiàng)目編寫(xiě)測(cè)試用例,以及應(yīng)該編寫(xiě)哪些場(chǎng)景的測(cè)試用例。

單元測(cè)試與集成測(cè)試

單元測(cè)試(Unit Testing)正如其名,其中的測(cè)試用例應(yīng)當(dāng)是針對(duì)代碼中的各個(gè)單元的,如前端代碼中,每一個(gè)工具方法都可以被作為一個(gè)單元,對(duì)應(yīng)一個(gè)獨(dú)立的測(cè)試用例。但這么說(shuō)并不意味著你要寫(xiě)出非常細(xì)粒度的代碼——這不是沒(méi)事折磨自己?jiǎn)幔课彝ǔJ褂谩肮δ軉卧钡姆绞絹?lái)確定粒度,比如生產(chǎn)薯?xiàng)l的流水線上,清洗-削皮-切片-包裝就是四個(gè)完全獨(dú)立的功能單元。

你可能會(huì)感到疑惑,這四個(gè)功能單元明明存在依賴關(guān)系,為何說(shuō)是完全獨(dú)立的?這是因?yàn)樵趩卧獪y(cè)試時(shí),非常重要的一個(gè)步驟就是對(duì)當(dāng)前測(cè)試單元的外部依賴進(jìn)行模擬,比如我在測(cè)試削皮功能時(shí),會(huì)直接給到“已經(jīng)清洗完畢的土豆”,然后檢查“削皮后的土豆”,而不會(huì)真的去調(diào)用前后的功能單元。

常見(jiàn)的模擬操作可以分為 Fake、Stub、Mock、Spy 這么幾種,我們?cè)谙挛臅?huì)有更詳細(xì)的介紹。

一種常見(jiàn)的情況是工具方法中會(huì)基于外部依賴的表現(xiàn)執(zhí)行不同分支的代碼(if/else,try/catch,resolve/reject 等)。這種時(shí)候,我們需要做的就是通過(guò)修改外部依賴的表現(xiàn),來(lái)檢查工具方法內(nèi)部各個(gè)代碼分支的執(zhí)行情況。比如,在 fetch 成功返回時(shí)應(yīng)當(dāng)調(diào)用 processData 方法,在 fetch 失敗時(shí)應(yīng)當(dāng)調(diào)用 reportError 方法,此時(shí)你就可以篡改掉 fetch 的實(shí)現(xiàn),然后檢查 processData 、reportError 方法是否被調(diào)用(注意,這兩個(gè)方法也需要被模擬(Stub / Spy) ,然后才能檢查它們的調(diào)用情況)。

當(dāng)然,完全模擬所有外部依賴是最理想的情況,在很多時(shí)候一個(gè)工具方法可能具有許多外部依賴,此時(shí)你可以省略掉其中能確定無(wú)副作用(如 logger 這樣的純函數(shù)),或者是與核心邏輯無(wú)關(guān)的部分。

我們知道,測(cè)試用例也可以反過(guò)來(lái)對(duì)代碼產(chǎn)生檢查作用,而在單元測(cè)試階段這種作用基本是最明顯的,比如你可以很容易發(fā)現(xiàn)某一處功能單元設(shè)計(jì)得過(guò)于耦合,或是某一外部依賴將導(dǎo)致代碼進(jìn)入錯(cuò)誤分支等情況。

目前推薦的單元測(cè)試方案主要有這么幾種,Jest、Mocha、Sinon、Jasime 以及 AVA,它們之間各有優(yōu)劣,這里不做比較。但需要注意的是,一套完整的,能夠滿足實(shí)際需求的單元測(cè)試方案,通常意味著需要包括這么幾個(gè)功能:

如果你此前并沒(méi)有對(duì)這些單元測(cè)試方案非常熟悉,那我推薦你了解一下 Vitest ,來(lái)自 antfu 的作品,特色是快(畢竟基于 Vite)以及對(duì) TypeScript、ES Module 的良好支持,我目前在工作中的單元測(cè)試也已經(jīng)全部遷移到 Vitest,同時(shí) Vitest 還自帶了 UI 界面,讓你可以更享受編寫(xiě)測(cè)試并看著它們一個(gè)個(gè)通過(guò)的過(guò)程。

測(cè)試覆蓋率報(bào)告,這一功能常見(jiàn)的方式是通過(guò) istanbul (1.0版本,2.0 更名為 nyc)或 c8 來(lái)進(jìn)行實(shí)現(xiàn),其原理包括代碼插樁與使用 V8 引擎內(nèi)置功能兩種,這里不再贅述。另外一個(gè)常見(jiàn)的場(chǎng)景是輸出其他語(yǔ)言格式的覆蓋率報(bào)告(如 JUnit),社區(qū)也通過(guò) Reporters 的機(jī)制為這些測(cè)試框架做了支持。

模擬功能(Stub 、Fake Timers 等),包括對(duì)一個(gè)對(duì)象的 Spy,一個(gè)函數(shù)的 Stub,對(duì)一個(gè)模塊的 Mock,都屬于模擬的范疇。

用例收集,編寫(xiě)測(cè)試用例時(shí)我們同樣需要基于功能單元區(qū)分,常見(jiàn)的方式就是 describe 收集一個(gè)功能單元,內(nèi)部又使用 it / test 來(lái)進(jìn)行功能單元各個(gè)邏輯分支的驗(yàn)證。如:

describe('Utils.Reporter',()=>{
it('shouldreporterrorwhenxxx',()=>{})
it('shouldshowwarningswhenxxx',()=>{})
})

斷言,Jest 提供了注入到全局的 expect 風(fēng)格斷言(expect(1+1).toBe(2)),而 Sinon 提供的則是類似 NodeJs asserts 模塊風(fēng)格的斷言(``sinon.assert.pass(1 + 1 === 2)`),而 Mocha 則不綁定斷言庫(kù),你可以使用 asserts 模塊或者 Chai 來(lái)進(jìn)行斷言。另外,斷言又包括了幾種不同的風(fēng)格,我們同樣在下文講解。

poYBAGNGJ5yAD5FgAAEP3CnJME8895.png

如果說(shuō)單元測(cè)試是為了測(cè)試單個(gè)功能單元,那么集成測(cè)試(Integration Testing)很明顯就是為了測(cè)試多個(gè)功能單元的協(xié)作。但需要注意的是,多個(gè)功能單元協(xié)作并不意味著對(duì)整個(gè)系統(tǒng)(流水線)進(jìn)行完整的功能測(cè)試,通常我們還會(huì)將幾個(gè)功能單元分散開(kāi)進(jìn)行組合,成為系統(tǒng)的某一部分,比如清洗-削皮作為預(yù)處理功能,需要確定一籮筐土豆能否正確地變成干凈的去皮土豆,切片-包裝作為核心功能,需要確定去皮土豆能變成冷凍薯?xiàng)l。

而要進(jìn)行集成測(cè)試的編寫(xiě),其實(shí)我們?nèi)匀恢恍枰褂脝卧獪y(cè)試方案即可,因?yàn)楸举|(zhì)上集成測(cè)試就是同時(shí)對(duì)多個(gè)功能單元進(jìn)行測(cè)試,我們驗(yàn)證的范疇也隨之?dāng)U大了而已。

而關(guān)于集成測(cè)試的維度拆分則并沒(méi)有準(zhǔn)確的界限,你可以像上面那樣將預(yù)處理功能作為一個(gè)系統(tǒng)部分,也可以將整個(gè)流水線作為一個(gè)系統(tǒng)部分(還有供應(yīng)鏈部分、烹飪部分與服務(wù)部分),按照你的實(shí)際業(yè)務(wù)場(chǎng)景就行。

Mock、Fake、Stub

很多時(shí)候測(cè)試用例的運(yùn)行時(shí)是受限的,比如我們并不希望真的發(fā)起網(wǎng)絡(luò)請(qǐng)求,或者是和數(shù)據(jù)庫(kù)交互,以及 DOM API 的操作等。這個(gè)時(shí)候我們會(huì)使用一系列模擬手段,來(lái)特定地模擬一個(gè)可交互的對(duì)象,并通過(guò)修改它的行為來(lái)檢查預(yù)期的處理邏輯是否執(zhí)行。

這個(gè)模擬行為通常被直接稱為 Mock,但實(shí)際上,由于模擬的對(duì)象類型以及注入的模擬邏輯,更準(zhǔn)確的描述是將這些行為劃分為三大類。首先是最常用的 Stub ,假設(shè)我們?cè)跒?UserService 編寫(xiě)單元測(cè)試,其內(nèi)部注入的 PrismaService 負(fù)責(zé)數(shù)據(jù)庫(kù)的讀寫(xiě),我們可以使用一個(gè) PrismaServiceStub 替換掉實(shí)際的服務(wù),并且在其內(nèi)部提供對(duì)應(yīng) PrismaService.user.findUnique 這樣的方法,然后在我們調(diào)用 UserService.queryUser 時(shí),就可以檢查 PrismaServiceStub 上對(duì)應(yīng)的方法是否被預(yù)期的入?yún)⒄{(diào)用,而其出參是否被預(yù)期地處理后返回。Spy 也可以認(rèn)為是 Stub 的一種,但它更強(qiáng)調(diào)“是否按照預(yù)期調(diào)用”這個(gè)過(guò)程,我們甚至可以僅僅監(jiān)聽(tīng)一個(gè)對(duì)象而無(wú)需提供模擬實(shí)現(xiàn)(如 console 這樣的 API)。

而如果我們不希望替換掉 PrismaService,而是希望它真的去進(jìn)行數(shù)據(jù)讀寫(xiě),但不是對(duì)真實(shí)的數(shù)據(jù)庫(kù),就可以提供一個(gè) Fake 的數(shù)據(jù)庫(kù)——比如一個(gè)對(duì)象,這樣對(duì)數(shù)據(jù)庫(kù)的讀寫(xiě)就變成了對(duì)內(nèi)存對(duì)象的讀寫(xiě),變得更加快捷和穩(wěn)定,這就是 Fake。另外一個(gè)常見(jiàn)的 Fake 場(chǎng)景就是定時(shí)器,常見(jiàn)的單元測(cè)試框架都提供了 Fake Timers 的功能支持。

而 Mock 其實(shí)和 Stub 也非常類似,但 Mock 更像是其中“預(yù)期的入?yún)ⅰ保⒉魂P(guān)注返回值,我個(gè)人理解通常項(xiàng)目中 fixtures 文件夾下的各種對(duì)象和 JSON 就是典型的 Mock 。

當(dāng)然,Mock、Stub、Spy 三者還是非常相似的,我們也并不是必須搞清楚其中的差異,因?yàn)樗鼈兊谋举|(zhì)都是模擬罷了。

斷言:expect、assert、should

我們常見(jiàn)的斷言包括 expect 與 assert 形式,NodeJs 提供了原生的 asserts 模塊讓你來(lái)編寫(xiě)一些簡(jiǎn)單的斷言,你可以在實(shí)際代碼中也使用斷言來(lái)確保邏輯正確運(yùn)行,而 expect 形式則通常只見(jiàn)于測(cè)試用例中。如檢查一個(gè)函數(shù)的調(diào)用和比較兩個(gè)對(duì)象,兩種風(fēng)格分別是這樣的:

expect(mockFn).toBeCalledWith(

"linbudu"

);

assert.pass(mockFn.calls[

0

].arg===

"linbudu"

);

expect(obj1).toEqual(obj2);

assert.equal(obj1,obj2);

通常我個(gè)人更喜歡命令式風(fēng)格明顯的 expect 斷言,而除了這兩種風(fēng)格以外,其實(shí)還有一種 should 形式的鏈?zhǔn)斤L(fēng)格斷言,它寫(xiě)起來(lái)是這樣的:

mockFn.should.be.called();

obj1.should.equal(obj2);

值得一提的是在 Chai 這個(gè)斷言庫(kù)中對(duì)以上三種斷言風(fēng)格都進(jìn)行了支持,如果你有興趣,不妨都試一試。

前端頁(yè)面中的組件測(cè)試與 E2E 測(cè)試

單元測(cè)試和集成測(cè)試是前后端應(yīng)用中通用的概念,而完成了對(duì)基礎(chǔ)功能單元的測(cè)試以后,我們需要更進(jìn)一步,關(guān)注領(lǐng)域中特定的功能,比如從前端視角來(lái)看一個(gè)組件的 UI 與功能,從后端視角來(lái)看一個(gè)接口面對(duì)千奇百怪入?yún)⒌捻憫?yīng)。

在當(dāng)今的前端項(xiàng)目中,組件化應(yīng)該是最明顯的一個(gè)趨勢(shì),那么進(jìn)行組件維度的測(cè)試也自然是相當(dāng)有必要的。以 React 組件為例,我們可以模擬這個(gè)組件的入?yún)?,并觀察其實(shí)際渲染的 UI 組件是否正確,以及使用快照的方式,來(lái)檢查組件的實(shí)際渲染是否一致。

目前使用的組件測(cè)試方案通常是和框架綁定的,如 React 下的 @testing-library/react 和 Enzyme,Vue 下的 @vue/test-utils,Svelte 下的 @testing-library/svelte,這是因?yàn)楸举|(zhì)上我們是在孤立地渲染這個(gè)組件,并模擬框架行為來(lái)驗(yàn)證其表現(xiàn)。

在組件測(cè)試方案中,我更推薦 @testing-library/react (還包括 @testing-library/react-hooks),Enzyme 的 API 要更加復(fù)雜,同時(shí)其目前應(yīng)該已經(jīng)不再維護(hù)(或是維護(hù)力度堪憂)。使用其編寫(xiě)的測(cè)試用例是這樣的:

import

*

as

React

from

'react'

function

HiddenMessage

({children}){

const

[showMessage,setShowMessage]=React.useState(

false

)

return

(

<

div

>

<

label

htmlFor

=

"toggle"

>ShowMessage

label

>

<

input

id

=

"toggle"

type

=

"checkbox"

onChange

=

{e

=>setShowMessage(e.target.checked)}

checked={showMessage}

/>

{showMessage?children:null}

div

>

)

}

export

default

HiddenMessage

import

*

as

React

from

'react'

import

{render,fireEvent,screen}

from

'@testing-library/react'

import

HiddenMessage

from

'../hidden-message'

test(

'showsthechildrenwhenthecheckboxischecked'

,()=>{

const

testMessage=

'TestMessage'

//將組件模擬渲染出來(lái)

render(<

HiddenMessage

>{testMessage}

HiddenMessage

>)

//基于模糊查詢來(lái)驗(yàn)證DOM元素的存在

expect(screen.queryByText(testMessage)).toBeNull()

//同樣基于模糊查詢來(lái)觸發(fā)事件

fireEvent.click(screen.getByLabelText(

/show/i

))

//驗(yàn)證結(jié)果是否符合預(yù)期

expect(screen.getByText(testMessage)).toBeInTheDocument()

})

單元測(cè)試、集成測(cè)試、組件測(cè)試,看起來(lái)我們已經(jīng)非常完美地使用自動(dòng)化測(cè)試從不同場(chǎng)景與不同維度進(jìn)行了功能的驗(yàn)證,但實(shí)際上,我們還少了一個(gè)非常重要的維度——用戶視角。在程序最終交付驗(yàn)收時(shí),我們可愛(ài)的測(cè)試同學(xué)會(huì)來(lái)把各個(gè)功能和鏈路都檢查一遍,而即使你已經(jīng)寫(xiě)了巨量的測(cè)試用例,還是有可能會(huì)被發(fā)現(xiàn)大量的問(wèn)題,這就是因?yàn)橐暯遣煌?。作為程序?a target="_blank">開(kāi)發(fā)者,你清楚地了解程序的控制流走向,也對(duì)每一個(gè)分支了然于胸,所以在編寫(xiě)測(cè)試用例時(shí)你其實(shí)更像是上帝視角。

要從用戶的視角出發(fā),實(shí)際上我們只需要屏蔽對(duì)程序內(nèi)部的所有感知,而只是去使用這個(gè)程序即可。這樣的測(cè)試被稱為端到端測(cè)試(End-to-End Testing,E2E),它不再關(guān)注內(nèi)部功能單元的細(xì)節(jié),而是完全從外部還原一個(gè)真實(shí)的用戶視角,如前端應(yīng)用中,用戶登錄-搜索商品-加入購(gòu)物車-編輯商品-結(jié)算商品的一系列交互,誰(shuí)管你的登錄背后隱藏了多少權(quán)限分級(jí),商品貨架分級(jí)設(shè)計(jì)得多么精細(xì),只要這個(gè)流程無(wú)法順利走通,那你的系統(tǒng)就是有問(wèn)題的。

而既然 E2E 測(cè)試是在模擬用戶行為,那么其實(shí)我們所需要做的就是使用用戶的環(huán)境來(lái)運(yùn)行系統(tǒng)罷了。如對(duì)于前端頁(yè)面,其實(shí)就是瀏覽器(更準(zhǔn)確地說(shuō)是瀏覽器內(nèi)核),而對(duì)于后端服務(wù)則是客戶端。

Cypress 的功能為例,來(lái)看看我們是如何模擬用戶行為的:

poYBAGNGJ7mACSr6AACIqDFNSjw017.png

在前端領(lǐng)域中編寫(xiě) E2E 測(cè)試,常見(jiàn)的 E2E 測(cè)試框架主要包括 Puppeteer、Cypress、Playwright、Selenium 這么幾種。它們之間各有優(yōu)劣,適用場(chǎng)景也有所不同,我們會(huì)在下面進(jìn)行比較。

與其他測(cè)試場(chǎng)景的重要不同之一,就是 E2E 測(cè)試是可以由測(cè)試同學(xué)來(lái)編寫(xiě)的(如支持 PythonJava 的 Selenium),在產(chǎn)品進(jìn)行迭代的同時(shí),測(cè)試同學(xué)會(huì)按照功能點(diǎn)變化對(duì)應(yīng)地完善測(cè)試用例,同時(shí)確保以往所有功能的測(cè)試用例不受影響。

Puppeteer、Cypress、Playwright 的取舍

前端 E2E 測(cè)試目前常用的包括 Puppeteer、Cypress、Playwright 這么幾款,這就可能讓你感到選擇困難,到底應(yīng)該選哪個(gè)?萬(wàn)一選了一個(gè),寫(xiě)著寫(xiě)著發(fā)現(xiàn)不符合需求了,咋辦?這一部分我們就來(lái)簡(jiǎn)單介紹一下它們。

先上結(jié)論:非常簡(jiǎn)單的場(chǎng)景使用 Puppeteer(需要搭配 Jest-Puppeteer),PC 應(yīng)用使用 Cypress,移動(dòng)端應(yīng)用使用 Playwright。

接著我們?cè)賮?lái)一個(gè)個(gè)解釋。首先是 Puppeteer,認(rèn)真地說(shuō),它就不應(yīng)該用來(lái)做 E2E 測(cè)試,因?yàn)槿思艺娴木椭皇且粋€(gè)無(wú)頭瀏覽器,你要用它來(lái)寫(xiě)寫(xiě)爬蟲(chóng)之類的倒還好,強(qiáng)行霸王硬上弓要人家給你干 E2E,一方面是只支持 Chrome + Chromium 內(nèi)核,另一方面人家不帶斷言庫(kù),你還得帶一個(gè) Jest-Puppeteer 一起。但如果是真的非常非常簡(jiǎn)單的場(chǎng)景,你還是可以用 Puppeteer ,加上 NodeJs 的基礎(chǔ)斷言庫(kù),通過(guò)自動(dòng)化方式確定一些頁(yè)面功能還是沒(méi)問(wèn)題的。

然后是 Cypress ,其場(chǎng)景從人家的 Slogan 其實(shí)也能感覺(jué)出來(lái):Fast, easy and reliable testing for anything that runs in a browser,注意 in a browser,其實(shí)人家就是提供了無(wú)頭瀏覽器,斷言,GUI,以及 Web 下的各種 API ,然后你就可以完全模擬使用瀏覽器進(jìn)行的一切行為了。同時(shí) Cypress 也通過(guò)代碼插樁的方式支持了覆蓋率報(bào)告相關(guān)的能力。需要注意的是,Cypress 只支持瀏覽器維度的配置,如 chrome(也支持chromium)、edge、firefox。

因此,如果你更側(cè)重于檢查應(yīng)用在移動(dòng)端的表現(xiàn),那其實(shí)應(yīng)該使用 Playwright 。為什么?Playwright 支持同時(shí)運(yùn)行多個(gè) project,這些 project 可以被配置為使用瀏覽器內(nèi)核(檢驗(yàn) PC、桌面端場(chǎng)景),也可以被配置為使用內(nèi)置的 devices 預(yù)設(shè),來(lái)檢驗(yàn)其在移動(dòng)端的表現(xiàn),這些預(yù)設(shè)包括了視口大小、默認(rèn)瀏覽器內(nèi)核(chromium,webkit,safari 等)等等,參考官網(wǎng)的示例配置:

//playwright.config.ts

import

{

type

PlaywrightTestConfig,devices}

from

'@playwright/test'

;

const

config:PlaywrightTestConfig={

projects:[

{

name:

'DesktopChromium'

,

use:{

browserName:

'chromium'

,

viewport:{width:

1280

,height:

720

},

},

},

{

name:

'DesktopSafari'

,

use:{

browserName:

'webkit'

,

viewport:{width:

1280

,height:

720

},

}

},

{

name:

'DesktopFirefox'

,

use:{

browserName:

'firefox'

,

viewport:{width:

1280

,height:

720

},

}

},

{

name:

'MobileChrome'

,

use:devices[

'Pixel5'

],

},

{

name:

'MobileSafari'

,

use:devices[

'iPhone12'

],

},

],

};

export

default

config;

在我所在的團(tuán)隊(duì),目前也正在基于 Playwright 建立 E2E 測(cè)試用例,來(lái)更方便快捷地保障核心應(yīng)用的頁(yè)面功能。

最后,如果你并不是在開(kāi)發(fā)一個(gè)前端應(yīng)用,而是在開(kāi)發(fā)一個(gè) UI 組件庫(kù),那你可以使用 StoryBook 提供的測(cè)試能力(基于 Jest 與 Playwright),這樣一來(lái)你既能夠基于 StoryBook 獲得組件的可視化文檔說(shuō)明,也可以獲得自動(dòng)生成的 E2E 測(cè)試用例:

poYBAGNGJ86AWKinAADFZJ09x0E682.png

后端服務(wù)中的 E2E 測(cè)試與壓力測(cè)試

而對(duì)于后端服務(wù)中的測(cè)試,由于我暫時(shí)還沒(méi)有比較深入地實(shí)踐,這里就只簡(jiǎn)單介紹下 Node API 中的 E2E 測(cè)試、壓力測(cè)試。

上面我們已經(jīng)提到,對(duì)于后端服務(wù)來(lái)說(shuō)其實(shí)用戶就是各個(gè)客戶端,而我們也只需要模擬客戶端,向 API 發(fā)起請(qǐng)求,模擬登錄態(tài)信息和各種參數(shù),然后查看最終返回的結(jié)果是否符合預(yù)期即可。在這個(gè)過(guò)程中,API 由哪個(gè) Controller 承接,調(diào)用了哪些 Service,走過(guò)了哪些 Middleware ,我們都不應(yīng)該也無(wú)需關(guān)心。而假裝自己是客戶端的方式就簡(jiǎn)單多了,常見(jiàn)的方式是使用 supertest 。另外,通常后端服務(wù)的 E2E 測(cè)試也應(yīng)該是盡量模擬完整的交互過(guò)程:上傳商品-編輯商品-上架商品-下架商品-...,只不過(guò)這個(gè)過(guò)程并不像在前端那樣直觀。

另外后端服務(wù)中的 E2E 測(cè)試如何 Mock 也有不同的情況,如果希望盡可能模擬用戶,可以使用專用的測(cè)試環(huán)境數(shù)據(jù)庫(kù),但這樣測(cè)試的執(zhí)行就不完全穩(wěn)定。如果希望從簡(jiǎn),那么可以像單元測(cè)試與集成測(cè)試中那樣模擬掉外部依賴。另外,部分 NodeJs 框架也直接提供了原生的測(cè)試支持,如 @nestjs/testing,@midwayjs/mock 等等。

另外一個(gè)后端服務(wù)特殊的測(cè)試場(chǎng)景則是壓力測(cè)試,在某些時(shí)候也可以被等價(jià)于性能測(cè)試,從某些方面它其實(shí)也是在模擬用戶,只不過(guò)不是模擬一個(gè)用戶的交互行為,而是模擬較大量級(jí)的用戶訪問(wèn),以此來(lái)測(cè)試服務(wù)的性能。本質(zhì)上壓力測(cè)試并不是在測(cè)試 API 的邏輯,而是承載 API 的服務(wù)器性能與負(fù)載均衡相關(guān)邏輯。進(jìn)行壓力測(cè)試可以很簡(jiǎn)單地使用腳本開(kāi)多線程并發(fā)請(qǐng)求,也可以使用 Apache Bench、Webbench、wrk(wrk2)測(cè)試工具,或者 npm 社區(qū)也有 autocannon 這樣的實(shí)現(xiàn)。

在壓力測(cè)試下,我們主要關(guān)注這么幾個(gè)指標(biāo):

每秒請(qǐng)求數(shù) RPS,Request Per Second,更常見(jiàn)的稱呼是每秒查詢數(shù) QPS,Query Per Second,它代表了到達(dá)服務(wù)器的請(qǐng)求數(shù)量。

并發(fā)用戶數(shù) CL,Concurrency Level,不同于 RPS,并發(fā)數(shù)代表了當(dāng)前仍未完結(jié)的等待處理的請(qǐng)求。舉例來(lái)說(shuō),假設(shè)某個(gè)神奇 API 的請(qǐng)求處理速度非常快,每個(gè)請(qǐng)求的處理時(shí)間無(wú)限趨近于 0 ,那么即使其 RPS 可能達(dá)到一百萬(wàn),并發(fā)數(shù)卻也非常低(趨近于0)——因?yàn)樗幚淼膶?shí)在是太快了,幾乎不需要同時(shí)處理兩個(gè)請(qǐng)求。

每秒事務(wù)數(shù) TPS,Transactions Per Second,TPS 有點(diǎn)類似于 QPS,但它所關(guān)注的事務(wù)其實(shí)是比請(qǐng)求-響應(yīng)過(guò)程更具象的過(guò)程,舉例來(lái)說(shuō),訪問(wèn) server/index.html ,實(shí)際上還訪問(wèn)了 server/index.css 與 server/index.js 文件,那么這個(gè)過(guò)程實(shí)際上只會(huì)記為一次事務(wù),但會(huì)記為三次查詢。

響應(yīng)時(shí)間 RT,Response Time,一個(gè)請(qǐng)求從進(jìn)入到帶走響應(yīng)的耗時(shí),這個(gè)耗時(shí)包括了等待時(shí)間-處理時(shí)間-IO讀寫(xiě)時(shí)間-響應(yīng)到達(dá)時(shí)間。

除了這些指標(biāo)以外,我們還會(huì)關(guān)注服務(wù)器當(dāng)前的性能指標(biāo),如內(nèi)存與 CPU 占用率,駐留集(RSS,當(dāng)前進(jìn)程獲得分配的物理內(nèi)存,包括堆、棧與執(zhí)行代碼段等),你也可以使用 NodeJs 提供的 --prof --prof-process 等啟動(dòng)參數(shù),或使用 heapdump 提供的內(nèi)存快照打印功能來(lái)幫助分析 Node API 的性能。

尾聲

除了以上介紹的這些自動(dòng)化測(cè)試分類,其實(shí)還有著前端頁(yè)面的性能測(cè)試(如基于 LightHouse、Performance API),主要關(guān)注各種“首次”的指標(biāo),如首屏繪制、可交互時(shí)間、最大內(nèi)容繪制等等,基于 axe-core 的可訪問(wèn)性測(cè)試(Accessibility Testing),關(guān)注網(wǎng)頁(yè)的可訪問(wèn)性,以及一些相對(duì)少見(jiàn)的場(chǎng)景,如基于 Needle 的 CSS 測(cè)試、基于 Coffee 的命令行應(yīng)用測(cè)試,以及混沌工程理念中的混沌測(cè)試等,這些概念要么在社區(qū)里已經(jīng)存在大量的高質(zhì)量介紹文章,要么我并沒(méi)有深入了解過(guò),在這里就不贅述了。

另外,想要進(jìn)一步地保障頁(yè)面的功能穩(wěn)定性,監(jiān)控平臺(tái)(白屏,JS Error,404)這一類的存在也是相當(dāng)有意義的,但這一部分功能已經(jīng)存在太多方案,社區(qū)的 Sentry,以及各大廠內(nèi)部自己建設(shè)的平臺(tái)等等,這里就不再贅述。

這篇不長(zhǎng)也不短的小作文里,我們基本上把前端開(kāi)發(fā)者會(huì)接觸到的自動(dòng)化測(cè)試種類都了解了一遍,包括它們的使用場(chǎng)景,實(shí)踐方式,以及可選的庫(kù)/框架。在完成全文閱讀后,如果你恰好在開(kāi)發(fā)“值得投入精力編寫(xiě)測(cè)試”的應(yīng)用,不妨思考下,上面是否恰好有符合你所需求的部分。




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1504

    瀏覽量

    62157
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4798

    瀏覽量

    84799
  • DOM
    DOM
    +關(guān)注

    關(guān)注

    0

    文章

    18

    瀏覽量

    9589
  • JSON
    +關(guān)注

    關(guān)注

    0

    文章

    119

    瀏覽量

    6980
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    通用自動(dòng)化測(cè)試軟件 - TAE

    INTEWORK-TAE(Test Automation Executor) 是一款通用的測(cè)試用例自動(dòng)化執(zhí)行框架,用于汽車電子自動(dòng)化測(cè)試,可支持仿真( MIL/SIL/HIL)、故障注
    的頭像 發(fā)表于 01-02 13:42 ?74次閱讀
    通用<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>軟件 - TAE

    串口屏自動(dòng)化測(cè)試

    在當(dāng)今智能、高效的工業(yè)4.0時(shí)代,串口屏作為人機(jī)交互的關(guān)鍵組件,在自動(dòng)化設(shè)備、物聯(lián)網(wǎng)應(yīng)用、智能制造等領(lǐng)域發(fā)揮著舉足輕重的作用。為了確保這些界面不僅美觀易用,而且在各種復(fù)雜環(huán)境下穩(wěn)定
    的頭像 發(fā)表于 12-27 17:17 ?1126次閱讀

    潤(rùn)和軟件榮獲IDC測(cè)試自動(dòng)化領(lǐng)域唯一推薦廠商

    近日,國(guó)際知名市場(chǎng)研究機(jī)構(gòu)IDC發(fā)布《中國(guó)生成式人工智能技術(shù)與品牌推薦》報(bào)告,推薦了人工智能領(lǐng)域中表現(xiàn)突出的廠商。江蘇潤(rùn)和軟件股份有限公司(簡(jiǎn)稱“潤(rùn)和軟件”)憑借在AI技術(shù)和金融測(cè)試領(lǐng)域的深厚積累,成為
    的頭像 發(fā)表于 12-24 10:47 ?206次閱讀

    探索Playwright:前端自動(dòng)化測(cè)試的新紀(jì)元

    作者:京東保險(xiǎn) 張新磊 背景 在前端開(kāi)發(fā)中,自動(dòng)化測(cè)試是確保軟件質(zhì)量和用戶體驗(yàn)的關(guān)鍵環(huán)節(jié)。隨著Web應(yīng)用的復(fù)雜性不斷增加,手動(dòng)測(cè)試已經(jīng)無(wú)法滿足快速迭代和持續(xù)交付的需求。
    的頭像 發(fā)表于 10-22 14:27 ?209次閱讀

    開(kāi)關(guān)電源自動(dòng)化測(cè)試設(shè)備:如何實(shí)現(xiàn)自動(dòng)化測(cè)試?

    開(kāi)關(guān)電源自動(dòng)化測(cè)試設(shè)備是將測(cè)試軟件和測(cè)試硬件集成在一個(gè)電源測(cè)試柜中的ate自動(dòng)測(cè)試設(shè)備,其
    的頭像 發(fā)表于 08-30 18:19 ?1322次閱讀
    開(kāi)關(guān)電源<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>設(shè)備:如何實(shí)現(xiàn)<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>?

    OTA自動(dòng)化測(cè)試解決方案——實(shí)車級(jí)OTA測(cè)試系統(tǒng)PAVELINK.OTABOX

    作者|網(wǎng)蟲(chóng)小編|不吃豬頭肉引言往期內(nèi)容里為大家介紹了OTA技術(shù)、OTA后續(xù)的發(fā)展趨勢(shì)預(yù)測(cè)及OTA自動(dòng)化測(cè)試解決方案。本文是OTA系列的第三篇文章,今天主要向大家介紹實(shí)車級(jí)OTA自動(dòng)化測(cè)試
    的頭像 發(fā)表于 07-11 08:26 ?679次閱讀
    OTA<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>解決方案——實(shí)車級(jí)OTA<b class='flag-5'>測(cè)試</b>系統(tǒng)PAVELINK.OTABOX

    機(jī)械自動(dòng)化和電氣自動(dòng)化區(qū)別是什么

    機(jī)械自動(dòng)化和電氣自動(dòng)化是現(xiàn)代工業(yè)生產(chǎn)中兩個(gè)重要的領(lǐng)域,它們?cè)谠S多方面有著密切的聯(lián)系,但也存在一些明顯的區(qū)別。 一、基本概念 機(jī)械自動(dòng)化 機(jī)械自動(dòng)化
    的頭像 發(fā)表于 07-01 09:33 ?4177次閱讀

    機(jī)械自動(dòng)化自動(dòng)化的一種嗎

    各個(gè)領(lǐng)域得到了廣泛的應(yīng)用,如制造業(yè)、農(nóng)業(yè)、醫(yī)療、物流等。 機(jī)械自動(dòng)化的概念 機(jī)械自動(dòng)化是指利用機(jī)械設(shè)備和控制系統(tǒng)來(lái)實(shí)現(xiàn)生產(chǎn)過(guò)程的自動(dòng)化。它包括以下幾個(gè)方面: 2.1
    的頭像 發(fā)表于 07-01 09:32 ?1703次閱讀

    工業(yè)自動(dòng)化包含哪些技術(shù)領(lǐng)域

    工業(yè)自動(dòng)化是指在工業(yè)生產(chǎn)過(guò)程中,通過(guò)使用自動(dòng)化設(shè)備和系統(tǒng),實(shí)現(xiàn)生產(chǎn)過(guò)程的自動(dòng)化控制和管理。工業(yè)自動(dòng)化技術(shù)領(lǐng)域廣泛,涉及多個(gè)學(xué)科和技術(shù),以下是
    的頭像 發(fā)表于 06-11 11:26 ?1052次閱讀

    工業(yè)自動(dòng)化自動(dòng)化區(qū)別是什么

    生產(chǎn)過(guò)程的自動(dòng)控制和管理。自動(dòng)化的目標(biāo)是提高生產(chǎn)效率、降低成本、減少人為錯(cuò)誤和提高產(chǎn)品質(zhì)量。自動(dòng)化技術(shù)廣泛應(yīng)用于各個(gè)領(lǐng)域,包括制造業(yè)、交通運(yùn)輸、醫(yī)療保健、家庭生活等。 二、工業(yè)
    的頭像 發(fā)表于 06-11 11:13 ?1765次閱讀

    納米軟件自動(dòng)化測(cè)試合作:4644芯片與VPX模塊測(cè)試

    近日,納米軟件與西安廣勤電子技術(shù)有限公司就4644電源芯片自動(dòng)化測(cè)試和VPX電源自動(dòng)化測(cè)試達(dá)成戰(zhàn)略合作。在雙方進(jìn)行深入探討后,納米軟件為廣勤電子公司提供了高效、專業(yè)的
    的頭像 發(fā)表于 05-09 15:49 ?470次閱讀
    納米軟件<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>合作:4644芯片與VPX模塊<b class='flag-5'>測(cè)試</b>

    860-930MHz射頻前端芯片GC1109在工業(yè)自動(dòng)化中的應(yīng)用

    860-930MHz射頻前端芯片GC1109在工業(yè)自動(dòng)化中的應(yīng)用
    的頭像 發(fā)表于 05-09 09:59 ?494次閱讀
    860-930MHz射頻<b class='flag-5'>前端</b>芯片GC1109在工業(yè)<b class='flag-5'>自動(dòng)化</b>中的應(yīng)用

    納米軟件分享:電源管理芯片自動(dòng)化測(cè)試方案

    在納米軟件與江蘇某科技公司合作的電源管理芯片產(chǎn)線測(cè)試項(xiàng)目中,需要完成單入單出、單入雙出、單入三出、單入四出系列微模塊的14個(gè)項(xiàng)目的自動(dòng)化測(cè)試。該公司之前是手動(dòng)測(cè)試,沒(méi)有
    的頭像 發(fā)表于 04-23 13:47 ?521次閱讀
    納米軟件分享:電源管理芯片<b class='flag-5'>自動(dòng)化</b><b class='flag-5'>測(cè)試</b>方案

    2.4GHz ISM的射頻前端芯片GC1103用于工業(yè)自動(dòng)化設(shè)備

    2.4GHz ISM的射頻前端芯片GC1103用于工業(yè)自動(dòng)化設(shè)備
    的頭像 發(fā)表于 04-09 10:01 ?499次閱讀
    2.4GHz ISM的射頻<b class='flag-5'>前端</b>芯片GC1103用于工業(yè)<b class='flag-5'>自動(dòng)化</b>設(shè)備

    Eggplant—HMI自動(dòng)化測(cè)試軟件

    Eggplant是英國(guó)TestPlant公司推出的創(chuàng)新性自動(dòng)化測(cè)試工具。通過(guò)VNC或RDP通訊技術(shù)遠(yuǎn)程桌面連接被測(cè)對(duì)象,基于圖像和文字識(shí)別算法進(jìn)行對(duì)象定位,進(jìn)而驅(qū)動(dòng)和確認(rèn)被測(cè)HMI設(shè)備的響應(yīng),能夠
    的頭像 發(fā)表于 01-23 18:00 ?625次閱讀