分享7個(gè)專業(yè)級(jí)的JavaScript測試庫,提高你的工作效率

創(chuàng)建一個(gè)不會(huì)崩潰的應(yīng)用程序

在現(xiàn)代軟件開發(fā)中,編寫和維護(hù)高質(zhì)量的測試用例已經(jīng)成為我們?nèi)粘9ぷ鞯闹匾糠帧6鳭avaScript作為全球最流行的編程語言之一,擁有大量的庫和框架,能夠幫助我們更好地進(jìn)行測試。
在這篇文章中,我將向大家介紹七個(gè)優(yōu)秀的JavaScript測試庫,包括Jest、Sinon、Detox、Cucumber、Stryker、TestDouble和Mockttp。這些庫在各自的領(lǐng)域中都有出色的表現(xiàn),如單元測試、功能測試、模擬、集成測試和突變測試等。通過本文的介紹,我希望你能更深入地了解這些庫,找到適合你項(xiàng)目的測試工具。
1、Jasmine

這是GitHub上星標(biāo)超過15500的頂級(jí)庫之一。如果你想在你的項(xiàng)目中進(jìn)行行為驅(qū)動(dòng)開發(fā)(Behavior Driven Development)測試,那么這將是一個(gè)非常好的資源。它不依賴于瀏覽器、DOM或任何JavaScript框架,因此非常適合用于網(wǎng)站、Node.js項(xiàng)目,或者任何能運(yùn)行JavaScript的地方。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/jasmine/jasmine
使用示例
Jasmine是一個(gè)用于JavaScript代碼的行為驅(qū)動(dòng)開發(fā)(BDD)測試框架。它無需DOM和它可以在任何JavaScript支持的環(huán)境中運(yùn)行,包括Node.js和瀏覽器。
首先,你需要安裝Jasmine。在Node.js環(huán)境中,你可以通過npm(Node包管理器)來安裝:
npm install --save-dev jasmine
安裝完Jasmine后,你可以在你的項(xiàng)目中創(chuàng)建一些測試文件。這些測試文件通常稱為"spec"文件,在這些文件中你可以寫下測試用例。下面是一個(gè)簡單的示例:
// myFunction.spec.js
const myFunction = require('./myFunction.js');
describe("myFunction", function() {
it("應(yīng)該返回 'Hello, World!'", function() {
expect(myFunction()).toEqual('Hello, World!');
});
});
在上述代碼中,describe函數(shù)定義了一組相關(guān)的測試,it函數(shù)定義了一個(gè)單獨(dú)的測試。expect函數(shù)和toEqual函數(shù)一起構(gòu)成一個(gè)測試斷言,它們判斷myFunction的返回值是否為Hello, World!。
假設(shè)我們有如下的被測試函數(shù):
// myFunction.js
function myFunction() {
return 'Hello, World!';
}
module.exports = myFunction;
當(dāng)你想運(yùn)行測試時(shí),可以在終端中運(yùn)行以下命令:
npx jasmine myFunction.spec.js
如果myFunction函數(shù)的行為符合我們的預(yù)期(也就是返回Hello, World!),那么測試就會(huì)通過。如果函數(shù)的行為與我們的預(yù)期不符,那么測試就會(huì)失敗,并顯示一條描述失敗原因的消息。
以上就是對(duì)Jasmine庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。
2、Sinon

這是一個(gè)獨(dú)立的庫,用于在JavaScript測試中創(chuàng)建測試替身(偵查、樁和模擬)。它通過提供工具來驗(yàn)證函數(shù)調(diào)用、控制行為等,幫助你編寫隔離的測試。它在GitHub上有超過9000顆星標(biāo)。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/sinonjs/sinon
3、Detox

如果你想對(duì)你的移動(dòng)應(yīng)用進(jìn)行測試,這將是一個(gè)非常好的資源。高速度的原生移動(dòng)開發(fā)需要我們采用持續(xù)集成工作流,這就意味著我們對(duì)人工質(zhì)量保證的依賴需要大大降低。這個(gè)庫可以在真實(shí)設(shè)備或模擬器上運(yùn)行你的移動(dòng)應(yīng)用進(jìn)行測試,就像真正的用戶一樣與它進(jìn)行交互。它在GitHub上有超過10000顆星標(biāo)。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/wix/Detox
使用示例
Detox是一個(gè)用于端到端測試React Native和其他原生移動(dòng)應(yīng)用的庫。與其他庫不同,Detox提供了一種方式來自動(dòng)模擬真實(shí)用戶的行為并且測試應(yīng)用在真實(shí)設(shè)備或模擬器上的表現(xiàn)。
首先,你需要在你的項(xiàng)目中安裝Detox和它的命令行工具。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:
npm install detox --save-dev
npm install -g detox-cli
然后,你需要在你的項(xiàng)目中配置Detox。在你的package.json文件中,你需要添加一個(gè)名為"detox"的新字段:
"detox": {
"configurations": {
"ios.sim.debug": {
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/YourApp.app",
"build": "xcodebuild -project ios/YourApp.xcodeproj -scheme YourApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11"
}
}
}
}
在上述配置中,我們定義了一個(gè)測試配置,命名為"ios.sim.debug"。這個(gè)配置指定了你的應(yīng)用在哪里構(gòu)建、應(yīng)用的類型以及你想在哪種設(shè)備上運(yùn)行測試。
接下來,你可以編寫一些端到端的測試用例。這些測試用例會(huì)在你指定的設(shè)備上運(yùn)行你的應(yīng)用并模擬真實(shí)用戶的行為。以下是一個(gè)簡單的示例:
// e2e/firstTest.spec.js
describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should have welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
});
在上述代碼中,我們首先調(diào)用device.reloadReactNative()來確保每個(gè)測試用例開始時(shí)應(yīng)用都是在一個(gè)新的狀態(tài)。然后我們使用expect和toBeVisible來斷言歡迎界面是否可見。
當(dāng)你想運(yùn)行測試時(shí),你需要先構(gòu)建你的應(yīng)用,然后再運(yùn)行測試:
detox build --configuration ios.sim.debug
detox test --configuration ios.sim.debug
如果你的應(yīng)用的行為符合我們的預(yù)期,那么測試就會(huì)通過。如果應(yīng)用的行為與我們的預(yù)期不符,那么測試就會(huì)失敗,并顯示一條描述失敗原因的消息。
以上就是對(duì)Detox庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。
4、Cucumber

Cucumber是一個(gè)運(yùn)行用簡單語言編寫的自動(dòng)化測試的工具。因?yàn)樗鼈兪怯煤唵握Z言編寫的,所以你的團(tuán)隊(duì)中的任何人都可以閱讀。因?yàn)槿魏稳硕伎梢蚤喿x,所以你可以使用它們來幫助提高團(tuán)隊(duì)的溝通、協(xié)作和信任。這是Cucumber的JavaScript實(shí)現(xiàn)。它在GitHub上有超過4500顆星標(biāo)。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/cucumber/cucumber-js
使用示例
Cucumber是一種行為驅(qū)動(dòng)開發(fā)(BDD)的工具,它允許開發(fā)者用簡潔的、近乎自然語言的文本語句(如英語)來描述應(yīng)用程序的行為,然后可以將這些語句轉(zhuǎn)換為可執(zhí)行的測試。
首先,你需要在你的項(xiàng)目中安裝Cucumber。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:
npm install --save-dev @cucumber/cucumber
接下來,你需要?jiǎng)?chuàng)建一個(gè)功能文件(通常以 .feature 結(jié)尾)。這個(gè)文件使用一種名為Gherkin的語言來描述應(yīng)用程序的行為。例如,你可能有一個(gè)如下的功能文件:
# myFeature.feature
Feature: Saying hello
Scenario: User says hello
Given the user has opened the application
When the user says hello
Then the application should reply with "Hello, User!"
然后,你需要?jiǎng)?chuàng)建一些步驟定義(step definitions)。步驟定義是用JavaScript編寫的函數(shù),這些函數(shù)會(huì)被Cucumber用來執(zhí)行功能文件中的每一步。例如,你可能有一個(gè)如下的步驟定義文件:
// mySteps.js
const { Given, When, Then } = require('@cucumber/cucumber');
let appOpen = false;
let saidHello = false;
Given('the user has opened the application', function () {
appOpen = true;
});
When('the user says hello', function () {
if (appOpen) saidHello = true;
});
Then('the application should reply with "Hello, User!"', function () {
if (appOpen && saidHello) {
console.log('Hello, User!');
}
});
最后,你可以通過Cucumber CLI來運(yùn)行你的功能文件:
npx cucumber-js myFeature.feature
以上就是對(duì)Cucumber庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。
5、Stryker

變異測試會(huì)對(duì)你的代碼進(jìn)行更改,然后針對(duì)更改后的代碼運(yùn)行你的單元測試。預(yù)期你的單元測試現(xiàn)在會(huì)失敗。如果它們沒有失敗,那可能意味著你的測試并沒有足夠覆蓋到代碼。正如你所猜測的,這個(gè)庫將幫助你在項(xiàng)目中進(jìn)行變異測試。它在GitHub上有超過2000顆星標(biāo)。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/stryker-mutator/stryker-js
使用示例
Stryker是一個(gè)變異測試框架,可以幫助你提高單元測試的質(zhì)量。變異測試的工作原理是通過對(duì)代碼進(jìn)行小的修改(稱為“變異”),然后運(yùn)行你的單元測試以查看哪些修改沒有被測試捕獲,這可以幫助揭示代碼覆蓋率的盲點(diǎn)。
首先,你需要在你的項(xiàng)目中安裝Stryker和它需要的插件。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:
npm install --save-dev @stryker-mutator/core @stryker-mutator/mocha-runner @stryker-mutator/javascript-mutator
在上面的示例中,我們安裝了Stryker的核心庫,用于運(yùn)行Mocha測試的運(yùn)行器以及JavaScript變異器。
然后,你需要?jiǎng)?chuàng)建一個(gè)Stryker配置文件。這個(gè)文件名通常為stryker.conf.js,并且應(yīng)該位于項(xiàng)目的根目錄下。在這個(gè)文件中,你可以定義Stryker應(yīng)該如何運(yùn)行你的測試和創(chuàng)建變異。
// stryker.conf.js
module.exports = function(config){
config.set({
mutator: "javascript",
packageManager: "npm",
reporters: ["clear-text", "progress"],
testRunner: "mocha",
transpilers: [],
coverageAnalysis: "off",
mutate: ["src/**/*.js"],
});
};
在上述代碼中,我們告訴Stryker使用JavaScript變異器,使用npm作為包管理器,以及使用Mocha作為測試運(yùn)行器。我們還告訴Stryker需要變異哪些文件。
現(xiàn)在,你可以運(yùn)行Stryker來執(zhí)行變異測試了:
npx stryker run
Stryker會(huì)生成一份報(bào)告,顯示每個(gè)變異是否被測試覆蓋。如果你的單元測試沒有捕獲到某個(gè)變異,那么你可能需要增加或改進(jìn)你的測試。
以上就是對(duì)Stryker庫的基本介紹和示例。你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。
6、TestDouble

你在編寫JavaScript測試,并在尋找一個(gè)模擬庫來替你模擬真實(shí)的東西嗎?這是一個(gè)有自己獨(dú)特見解的,設(shè)計(jì)精心的測試替身庫。該庫旨在適用于Node.js和瀏覽器解釋器。它也是測試框架無關(guān)的,所以你可以將它放入使用Jasmine、Mocha、Tape、Jest或我們自己的teenytest的代碼庫中。它在GitHub上有超過1000顆星標(biāo)。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/testdouble/testdouble.js
使用示例
TestDouble.js 是一個(gè)用于在JavaScript中創(chuàng)建測試替身(test doubles)的庫。它的設(shè)計(jì)原則是讓你能夠在單元測試中輕松地模擬或偽造(fake)依賴,從而讓你能夠更好地隔離和控制你的測試環(huán)境。
首先,你需要在你的項(xiàng)目中安裝TestDouble。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:
npm install --save-dev testdouble
接下來,你可以在你的單元測試中使用TestDouble。例如,你可以使用td.function()來創(chuàng)建一個(gè)模擬函數(shù):
const td = require('testdouble');
// 創(chuàng)建一個(gè)模擬函數(shù)
const mockFunction = td.function();
// 使模擬函數(shù)在調(diào)用時(shí)返回特定的值
td.when(mockFunction('hello')).thenReturn('world');
// 現(xiàn)在,當(dāng)你調(diào)用 mockFunction('hello') 時(shí),它將返回 'world'
console.log(mockFunction('hello')); // 輸出: 'world'
你也可以使用TestDouble來模擬對(duì)象,例如使用td.object()來創(chuàng)建一個(gè)模擬對(duì)象:
const td = require('testdouble');
// 創(chuàng)建一個(gè)模擬對(duì)象
const mockObject = td.object(['method1', 'method2']);
// 使模擬對(duì)象的方法在調(diào)用時(shí)返回特定的值
td.when(mockObject.method1()).thenReturn('hello');
// 現(xiàn)在,當(dāng)你調(diào)用 mockObject.method1() 時(shí),它將返回 'hello'
console.log(mockObject.method1()); // 輸出: 'hello'
TestDouble.js 還提供了許多其他用于創(chuàng)建和管理測試替身的功能,例如驗(yàn)證函數(shù)是否被調(diào)用,替換模塊等。以上就是對(duì)TestDouble庫的基本介紹和示例,你可以訪問其GitHub頁面獲取更多的信息和詳細(xì)的文檔。
7、Mockttp

HTTP測試是最常見且支持最好的用例。這個(gè)庫讓你能夠在JavaScript中快速、可靠、在任何地方攔截、轉(zhuǎn)換或測試HTTP請(qǐng)求和響應(yīng)。你可以在集成測試中使用這個(gè)庫,作為你的測試套件的一部分來攔截真實(shí)的請(qǐng)求,或者你可以使用它來構(gòu)建自定義的HTTP代理,捕獲、檢查和/或以任何你喜歡的方式重寫HTTP。你可以點(diǎn)擊這里查看這個(gè)庫。
https://github.com/httptoolkit/mockttp
使用示例
Mockttp是一個(gè)強(qiáng)大的庫,它允許你在JavaScript中攔截、檢查和修改HTTP請(qǐng)求和響應(yīng)。這對(duì)于集成測試和調(diào)試HTTP通信非常有用。
首先,你需要在你的項(xiàng)目中安裝Mockttp。在Node.js環(huán)境中,你可以使用npm(Node包管理器)來安裝:
npm install --save-dev mockttp
接下來,我們將介紹一些基本的使用方式:
// 引入需要的庫
const superagent = require("superagent");
const mockServer = require("mockttp").getLocal();
// 在測試開始前啟動(dòng)Mock服務(wù)器,并在測試結(jié)束后關(guān)閉服務(wù)器
beforeEach(() => mockServer.start(8080));
afterEach(() => mockServer.stop());
// 模擬請(qǐng)求,并對(duì)結(jié)果進(jìn)行斷言
it("lets you mock requests, and assert on the results", async () => {
// 模擬你的端點(diǎn)
await mockServer.forGet("/mocked-path").thenReply(200, "A mocked response");
// 發(fā)送一個(gè)請(qǐng)求
const response = await superagent.get("http://localhost:8080/mocked-path");
// 對(duì)結(jié)果進(jìn)行斷言
expect(response.text).to.equal("A mocked response");
});
以上代碼創(chuàng)建了一個(gè)Mock服務(wù)器,并設(shè)置了一個(gè)模擬的GET請(qǐng)求。然后,我們發(fā)送一個(gè)實(shí)際的GET請(qǐng)求,并斷言返回的響應(yīng)文本是否等于我們?cè)O(shè)置的模擬響應(yīng)。
Mockttp還提供了更多高級(jí)特性,例如:
無需指定端口,允許并行測試
驗(yàn)證Mock服務(wù)器接收的請(qǐng)求詳情
代理請(qǐng)求到任何其他主機(jī)
以下是一些更高級(jí)的示例:
const superagent = require("superagent");
require('superagent-proxy')(superagent);
const mockServer = require("mockttp").getLocal();
describe("Mockttp", () => {
beforeEach(() => mockServer.start());
afterEach(() => mockServer.stop());
// 不指定端口,允許并行測試
it("lets you mock without specifying a port, allowing parallel testing", async () => {
await mockServer.forGet("/mocked-endpoint").thenReply(200, "Tip top testing");
let response = await superagent.get(mockServer.urlFor("/mocked-endpoint"));
expect(response.text).to.equal("Tip top testing");
});
// 驗(yàn)證mock服務(wù)器接收的請(qǐng)求詳情
it("lets you verify the request details the mockttp server receives", async () => {
const endpointMock = await mockServer.forGet("/mocked-endpoint").thenReply(200, "hmm?");
await superagent.get(mockServer.urlFor("/mocked-endpoint"));
const requests = await endpointMock.getSeenRequests();
expect(requests.length).to.equal(1);
expect(requests[0].url).to.equal(`http://localhost:${mockServer.port}/mocked-endpoint`);
});
// 代理請(qǐng)求到任何其他主機(jī)
it("lets you proxy requests made to any other hosts", async () => {
await mockServer.forGet("http://google.com").thenReply(200, "I can't believe it's not google!");
let response = await superagent.get("http://google.com").proxy(mockServer.url);
expect(response.text).to.equal("I can't believe it's not google!");
});
});
這些示例使用了Mocha,Chai和Superagent,但并非必須使用這些:Mockttp可以與任何可以處理promise的測試工具配合使用,可以模擬來自任何庫、工具或設(shè)備的請(qǐng)求。
結(jié)尾
在這篇文章中,我們了解了七個(gè)JavaScript測試庫:Jest、Sinon、Detox、Cucumber、Stryker、TestDouble和Mockttp。每一個(gè)庫都有其獨(dú)特的功能和特點(diǎn),可以幫助我們更高效地編寫和管理測試用例,確保代碼的質(zhì)量和穩(wěn)定性。
不論你是初學(xué)者還是資深開發(fā)者,這些庫都將是你開發(fā)過程中強(qiáng)大的工具。我希望通過本文的介紹,你能更深入地了解這些庫,找到最適合你的工具。
在結(jié)束本文之前,我想說,測試是軟件開發(fā)中不可或缺的一部分,選擇和掌握合適的測試工具,可以讓我們的工作變得更加輕松。最后,希望本文能對(duì)你的開發(fā)工作帶來幫助,如果你有任何問題或者建議,歡迎在評(píng)論區(qū)留言。感謝閱讀,我們下次再見。
由于文章內(nèi)容篇幅有限,今天的內(nèi)容就分享到這里,文章結(jié)尾,我想提醒您,文章的創(chuàng)作不易,如果您喜歡我的分享,請(qǐng)別忘了點(diǎn)贊和轉(zhuǎn)發(fā),讓更多有需要的人看到。同時(shí),如果您想獲取更多前端技術(shù)的知識(shí),歡迎關(guān)注我,您的支持將是我分享最大的動(dòng)力。我會(huì)持續(xù)輸出更多內(nèi)容,敬請(qǐng)期待。
