搜尋
首頁web前端js教程BDD在JavaScript:開始使用Cucumber和Gherkin

BDD in JavaScript: Getting Started with Cucumber and Gherkin

BDD in JavaScript: Getting Started with Cucumber and Gherkin

測試驅動開發 (TDD) 的好處已廣為人知,它能提升產品質量和開發效率。每次編寫代碼測試時,都能確保代碼的正確性,並能及時發現未來可能出現的代碼錯誤。

行為驅動開發 (BDD) 在此基礎上更進一步,它測試的是產品的行為,而非僅僅是代碼,確保產品行為符合預期。本文將介紹如何使用 Cucumber 框架編寫 BDD 風格的自動化驗收測試。 Cucumber 的優勢在於,測試用例可以用簡潔的自然語言編寫,方便項目中非技術人員理解。閱讀本文後,您可以判斷 Cucumber 是否適合您的團隊,並開始編寫自己的驗收測試。準備好了嗎?讓我們開始吧!

關鍵要點

  • BDD 在 TDD 的基礎上,測試的是產品的行為而非代碼,使其更易於被包括非技術人員在內的更廣泛的利益相關者理解。
  • Cucumber 是一個 BDD 框架,它使用 Gherkin(一種易於理解的語言)來定義測試用例,確保所有利益相關者都能理解並參與測試過程。
  • Gherkin 語法將測試結構化為場景和特性,使用簡單的 Given、When、Then 步驟來描述行為,而無需規定技術實現。
  • Cucumber.js 與 JavaScript 項目集成,運行 Gherkin 定義的測試,並通過各種插件和配置支持異步操作和外部測試工具。
  • Cucumber.js 的設置包括通過 npm 安裝模塊,配置它來查找特性文件和步驟定義,以及將其可選地集成到構建腳本或任務運行器(如 Grunt 或 Gulp)中。
  • 本文提供了一個基本的 Cucumber 測試示例,演示了為加法和乘法設置 Gherkin 場景,使用簡單的斷言來驗證這些操作的正確性。
  • 本文還概述了 Cucumber.js 的高級功能,例如對異步測試的支持、用於參數化測試的場景大綱以及用於設置前提條件和後置條件的鉤子,以增強測試能力。

BDD 與 TDD 的區別

主要體現在測試的結構和編寫方式上。在 TDD 中,測試由編寫代碼的開發人員編寫、維護和理解。其他人可能根本不需要閱讀測試,這完全沒問題。但在 BDD 中,測試需要被比編寫功能的開發人員多得多的人理解。許多利益相關者都關心產品行為是否正確,例如 QA 人員、產品分析師、銷售人員,甚至高層管理人員。這意味著,理想情況下,BDD 測試需要以任何理解產品的人都能理解的方式編寫。區別在於:

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const browser = new webdriver.Builder()
  .usingServer()
  .withCapabilities({'browserName': 'chrome' })
  .build();

browser.get('http://en.wikipedia.org/wiki/Wiki');
browser.findElements(webdriver.By.css('[href^="/wiki/"]'))
.then(function(links){
  assert.equal(19, links.length); // 假设的数字
  browser.quit();
});

以及:

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const browser = new webdriver.Builder()
  .usingServer()
  .withCapabilities({'browserName': 'chrome' })
  .build();

browser.get('http://en.wikipedia.org/wiki/Wiki');
browser.findElements(webdriver.By.css('[href^="/wiki/"]'))
.then(function(links){
  assert.equal(19, links.length); // 假设的数字
  browser.quit();
});

這兩個測試執行相同的操作,但一個是可讀的自然語言,另一個只能被了解 JavaScript 和 Selenium 的人理解。本文將向您展示如何使用 Cucumber.js 框架在 JavaScript 項目中實現 BDD 測試,從而使您的產品受益於這種級別的測試。

什麼是 Cucumber/Gherkin?

Cucumber 是一個用於行為驅動開發的測試框架。它允許您以 Gherkin 格式定義測試,並通過將其與代碼綁定來使這些 Gherkin 可執行。 Gherkin 是一種領域特定語言 (DSL),用於編寫 Cucumber 測試。它允許以人類可讀的格式編寫測試腳本,然後可以在產品開發中的所有利益相關者之間共享。 Gherkin 文件是包含用 Gherkin 語言編寫的測試的文件。這些文件通常具有 .feature 文件擴展名。這些 Gherkin 文件的內容通常簡稱為“Gherkin”。

Gherkin

在 Gherkin 定義的測試中,您有特性場景的概念。它們類似於其他測試框架中的測試套件和測試用例,提供了一種清晰的測試結構方式。場景只是一個單獨的測試。它應該只測試應用程序中的一個方面。特性是一組相關的場景。因此,它將測試應用程序中許多相關的方面。理想情況下,Gherkin 文件中的特性將與應用程序中的特性緊密映射——因此得名。每個 Gherkin 文件都包含一個特性,每個特性都包含一個或多個場景。場景然後由步驟組成,這些步驟按特定順序排列:

  • Given – 這些步驟用於在執行測試之前設置初始狀態
  • When – 這些步驟是實際要執行的測試
  • Then – 這些步驟用於斷言測試結果

理想情況下,每個場景都應該是一個單獨的測試用例,因此 When 步驟的數量應該保持非常少。步驟是完全可選的。例如,如果您根本不需要設置任何內容,則可能沒有 Given 步驟。 Gherkin 文件旨在易於閱讀,並使參與產品開發的任何人都能受益。這包括非技術人員,因此 Gherkin 文件應始終使用業務語言而不是技術語言編寫。這意味著,例如,您不引用單個 UI 組件,而是描述您想要測試的產品概念。

Gherkin 測試示例

以下是搜索 Google 的 Cucumber.js 的 Gherkin 示例:

Given I have opened a Web Browser
When I load the Wikipedia article on "Wiki"
Then I have "19" Wiki Links

我們可以立即看到,此測試告訴我們做什麼,而不是如何做。它使用任何人都能理解的語言編寫,並且——重要的是——無論最終產品如何調整,它都最有可能保持正確。 Google 可能會決定完全更改其 UI,但只要功能等效,則 Gherkin 仍然準確。您可以在 Cucumber wiki 上閱讀更多關於 Given When Then 的信息。

Cucumber.js

在以 Gherkin 格式編寫測試用例後,您需要一種方法來執行它們。在 JavaScript 世界中,有一個名為 Cucumber.js 的模塊允許您執行此操作。它允許您定義 JavaScript 代碼,Cucumber.js 可以將其連接到 Gherkin 文件中定義的各種步驟。然後,它通過加載 Gherkin 文件並按正確的順序執行與每個步驟關聯的 JavaScript 代碼來運行測試。例如,在上面的示例中,您將擁有以下步驟:

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const browser = new webdriver.Builder()
  .usingServer()
  .withCapabilities({'browserName': 'chrome' })
  .build();

browser.get('http://en.wikipedia.org/wiki/Wiki');
browser.findElements(webdriver.By.css('[href^="/wiki/"]'))
.then(function(links){
  assert.equal(19, links.length); // 假设的数字
  browser.quit();
});

不必過於擔心所有這些含義——稍後將詳細解釋。但本質上,它定義了一些方法,Cucumber.js 框架可以使用這些方法將您的代碼綁定到 Gherkin 文件中的步驟。

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

將 Cucumber.js 包含在您的構建中

將 Cucumber.js 包含在您的構建中,只需將 cucumber 模塊添加到您的構建中,然後配置它即可運行。第一步如下所示:

Given I have opened a Web Browser
When I load the Wikipedia article on "Wiki"
Then I have "19" Wiki Links

第二步取決於您如何執行構建。

手動運行

手動執行 Cucumber 相對容易,最好先確保您可以這樣做,因為以下解決方案都是自動執行相同操作的方法。安裝後,可執行文件將是 ./node_modules/.bin/cucumber.js。運行它時,它需要知道在文件系統上的哪個位置可以找到所有必需的文件。這些文件既包括 Gherkin 文件,也包括要執行的 JavaScript 代碼。按照慣例,所有 Gherkin 文件都將保存在 features 目錄中,如果您沒有指示它執行其他操作,則 Cucumber 也將在同一目錄中查找要執行的 JavaScript 代碼。但是,指示它查找這些文件的位置是一種明智的做法,這樣您可以更好地控制構建過程。例如,如果您將所有 Gherkin 文件保存在 myFeatures 目錄中,並將所有 JavaScript 代碼保存在 mySteps 中,則可以執行以下操作:

Given I have loaded Google
When I search for "cucumber.js"
Then the first result is "GitHub - cucumber/cucumber-js: Cucumber for JavaScript"

-r 標誌是一個包含 JavaScript 文件的目錄,Cucumber 會自動加載這些文件用於測試。還有一些其他標誌可能也很有趣——只需閱讀幫助文本即可了解它們的工作方式:$ ./node_modules/.bin/cucumber.js --help。這些目錄會遞歸掃描,因此您可以根據具體情況將文件嵌套得淺或深。

npm 腳本

手動運行 Cucumber 後,將其添加到構建中作為 npm 腳本是一個簡單的情況。您只需將以下命令(無需完全限定路徑,因為 npm 會為您處理)添加到您的 package.json 中,如下所示:

Given('I have loaded Google', function() {});
When('I search for {stringInDoubleQuotes}', function() {});
Then('the first result is {stringInDoubleQuotes}', function() {});

完成後,您可以執行:

$ npm install --save-dev cucumber

它將完全按照您之前所做的那樣執行 Cucumber 測試。

Grunt

確實存在一個用於執行 Cucumber.js 測試的 Grunt 插件。不幸的是,它已經過時了,並且不適用於更新版本的 Cucumber.js,這意味著如果您使用它,您將錯過許多改進。相反,我更喜歡的方法是簡單地使用 grunt-shell 插件以與上述完全相同的方式執行命令。安裝後,配置它只需將以下插件配置添加到您的 Gruntfile.js 中:

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const browser = new webdriver.Builder()
  .usingServer()
  .withCapabilities({'browserName': 'chrome' })
  .build();

browser.get('http://en.wikipedia.org/wiki/Wiki');
browser.findElements(webdriver.By.css('[href^="/wiki/"]'))
.then(function(links){
  assert.equal(19, links.length); // 假设的数字
  browser.quit();
});

現在,和以前一樣,您可以通過運行 grunt shell:cucumber 來執行測試。

Gulp

Gulp 與 Grunt 的情況完全相同,因為現有的插件已經過時,並且將使用舊版本的 Cucumber 工具。同樣,在這裡您可以使用 gulp-shell 模塊像在其他場景中一樣執行 Cucumber.js 命令。設置它很簡單:

Given I have opened a Web Browser
When I load the Wikipedia article on "Wiki"
Then I have "19" Wiki Links

現在,和以前一樣,您可以通過運行 gulp cucumber 來執行測試。

您的第一個 Cucumber 測試

請注意,本文中的所有代碼示例都可以在 GitHub 上找到。

現在我們知道瞭如何執行 Cucumber,讓我們實際編寫一個測試。在這個示例中,我們將做一些相當人為的事情,只是為了展示系統的工作原理。實際上,您會做更複雜的事情,例如直接調用您正在測試的代碼、對正在運行的服務進行 HTTP API 調用或控制 Selenium 來驅動 Web 瀏覽器以測試您的應用程序。我們的簡單示例將證明數學仍然有效。我們將有兩個特性——加法和乘法。首先,讓我們進行設置。

Given I have loaded Google
When I search for "cucumber.js"
Then the first result is "GitHub - cucumber/cucumber-js: Cucumber for JavaScript"

您如何執行測試完全取決於您。在這個示例中,為了簡單起見,我將手動執行它。在一個真實的項目中,您將使用上述選項之一將其集成到您的構建中。

Given('I have loaded Google', function() {});
When('I search for {stringInDoubleQuotes}', function() {});
Then('the first result is {stringInDoubleQuotes}', function() {});

現在,讓我們編寫我們的第一個實際特性。這將放在 features/addition.feature 中:

$ npm install --save-dev cucumber

非常簡單,非常易於閱讀。它準確地告訴我們正在做什麼,而沒有告訴我們如何去做。讓我們嘗試一下:

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

然後讓我們編寫我們的第一個步驟文件。這將簡單地按照 Cucumber 輸出告訴我們的方式實現步驟,這不會做任何有用的事情,但會整理輸出。這將放在 steps/maths.js 中:

const assert = require('assert');
const webdriver = require('selenium-webdriver');
const browser = new webdriver.Builder()
  .usingServer()
  .withCapabilities({'browserName': 'chrome' })
  .build();

browser.get('http://en.wikipedia.org/wiki/Wiki');
browser.findElements(webdriver.By.css('[href^="/wiki/"]'))
.then(function(links){
  assert.equal(19, links.length); // 假设的数字
  browser.quit();
});

defineSupportCode 鉤子是 Cucumber.js 的一種方法,允許您提供它將用於各種不同情況的代碼。所有這些都將被涵蓋,但本質上,任何時候您想要編寫 Cucumber 將直接調用的代碼,它都需要在這些塊中的一個內部。您會注意到,此處的示例代碼定義了三個不同的步驟——每個 Given、When 和 Then 一個。每個塊都給出一個字符串(或者如果您需要的話,是一個正則表達式),該字符串與特性文件中的步驟匹配,以及在該步驟匹配時執行的函數。佔位符可以放在步驟字符串中(或者如果您使用的是正則表達式,則使用捕獲表達式代替),這些佔位符將被提取出來並作為參數提供給您的函數。執行此操作將提供更簡潔的輸出,同時仍然實際上什麼也不做:

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

現在讓我們讓它全部工作。我們只需要在我們步驟定義中實現代碼即可。我們還將進行一些整理,以使閱讀更容易。這實際上消除了對回調參數的需求,因為我們沒有做任何異步操作。之後,我們的 steps/maths.js 將如下所示:

Given I have opened a Web Browser
When I load the Wikipedia article on "Wiki"
Then I have "19" Wiki Links

執行它看起來像這樣:

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

就這樣,我們得到了一個非常易於擴展的測試套件,它證明了數學是正確的。作為一個練習,為什麼不嘗試擴展它以支持減法呢?如果您遇到困難,可以在評論中尋求幫助。

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換,並對部分章節進行合併和簡化)

更高級的 Cucumber.js技巧

這都很好,但是 Cucumber 可以做一些更高級的事情,這將使我們的生活更輕鬆。

異步步驟定義

到目前為止,我們只編寫了同步步驟定義。但是,在 JavaScript 世界中,這通常不夠好。 JavaScript 中的很多東西都需要異步,因此我們需要一些方法來處理它。謝天謝地,Cucumber.js 有幾種內置的方法來處理這個問題,這取決於您的喜好。上面暗示過的方法,這是處理異步步驟的更傳統的 JavaScript 方法,是使用回調函數。如果您指定步驟定義應該將回調函數作為其最後一個參數,則只有在觸發此回調後,才認為步驟已完成。在這種情況下,如果回調使用任何參數被觸發,則這被認為是一個錯誤,並且步驟將失敗。如果它在沒有任何參數的情況下被觸發,則認為步驟已成功。但是,如果根本沒有觸發回調,則框架最終會超時並使步驟失敗。故事的寓意?如果您接受回調參數,請確保調用它。例如,使用回調進行 HTTP API 調用的步驟定義可能如下所示。這是使用 Request 編寫的,因為它在響應上使用回調。

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

另一種方法,也是更優選的方法是通過返回類型。如果您從步驟返回一個 Promise,則只有當 Promise 完成時,才認為步驟已完成。如果 Promise 被拒絕,則步驟將失敗;如果 Promise 被 fulfilled,則步驟將成功。或者,如果您返回的內容不是 Promise,則步驟將立即被認為已成功。這包括返回 undefined 或 null。這意味著您可以在步驟執行期間選擇是否需要返回 Promise,並且框架將根據需要進行調整。例如,使用 Promises 進行 HTTP API 調用的步驟定義可能如下所示。這是使用 Fetch API 編寫的,因為它在響應上返回一個 Promise。

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換,並對部分章節進行合併和簡化)

特性背景、場景大綱、數據表、鉤子、事件和世界

這些高級特性,例如特性背景、場景大綱、數據表,以及鉤子函數(Before, After, BeforeStep, AfterStep等)和事件處理機制,都能夠極大地提高測試效率和可讀性。通過合理運用這些功能,可以編寫更簡潔、更易維護的BDD測試。 World 對象允許在不同的步驟定義之間共享數據和狀態,從而簡化測試邏輯。

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

總結

行為驅動開發是一種確保產品具有正確行為的絕佳方法,而Cucumber 作為一種工具,是一種非常強大的方法,可以實現這一點,以便產品的每個利益相關者都能閱讀、理解甚至編寫行為測試。本文只是觸及了 Cucumber 能夠實現的皮毛,因此我鼓勵您自己嘗試一下,以了解其強大功能。 Cucumber 還擁有一個非常活躍的社區,他們的郵件列表和 Gitter 頻道是尋求幫助的好方法,如果您需要的話。您是否已經在使用 Cucumber?本文是否鼓勵您嘗試一下?無論哪種方式,我都想在下面的評論中聽到您的聲音。 本文由 Jani Hartikainen 進行了同行評審。感謝所有 SitePoint 的同行評審者,使 SitePoint 內容達到最佳狀態!

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

關於使用 Cucumber 和 Gherkin 的 JavaScript 中 BDD 的常見問題 (FAQ)

(以下內容與原文基本一致,略作調整以保持流暢性和可讀性,並對部分語句進行同義詞替換)

以上是BDD在JavaScript:開始使用Cucumber和Gherkin的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境