蒼時弦也
蒼時弦也
資深軟體工程師
發表於

基本語法:步驟定義 - Cucumber 的文件測試法

使用 Cucumber 的 Gherkin 來撰寫測試是相當直覺的,然而這需要我們付出一些代價去實現「步驟定義」來將文件跟測試整合起來,然而這也是一個很好的機會讓我們去反思如何操作我們的軟體。

步驟定義

步驟定義是將我們在文件中像是 When John 點選 "測試好棒" 的句子提取出來,並且加以定義這個句子實際上該做些什麼,以 JavaScript 來說可以利用 Playwright 這類工具,而 Ruby 則是 Capybara 這類可以模擬瀏覽器操作的工具。

1When('{string} 點擊 {string}') do |user, text|
2  click_on text
3end

以 Ruby 為例子,我們使用 Cucumber 定義的 DSL(Domain Specific Language,領域特定語言) 把 John測試好棒 設定成可以任意填寫的欄位,並且呼叫 Capybara 提供的 DSL 進行「點選」的動作。

如果換成 JavaScript 的版本,除了語言的語法差異外,基本上是相同的。

1When('{string} 點擊 {string}', async function (this: World, user: string text: string) {
2  // ...
3  await page.getByText(text).click();
4});

如果是 Then 或者 Given 的情境,只需要替換內容即可,像是 Then 則是使用 expect 來做斷言。

1Then('我會看到 {string} 在畫面上') do |text|
2  expect(page).to have_text(text)
3end

除此之外,如果我們希望建立多筆測試資料,可以利用 Cucumber 的 Table 機制。

1Feature: 文章列表
2  Scenario: 列出文章
3    Given 這裡有一些文章
4      | title |
5      | 文章一 |
6      | 文章二 |
7    # ...

像上面這樣的表格結構,可以利用 #hashes 方法進行讀取。

1Given('這裡有一些文章') do |table|
2  table.hashes.each do |article|
3    # ...
4  end
5end

場景案例

有時候我們會希望在同一個場景(Scenario)裡面用不同的數值來測試,這個時候可以利用 Example(案例)的功能來舉出不同的例子,使用方式類似步驟定義的表格。

 1Feature: 計算機
 2  Scenario: 加法
 3    When 輸入 <int1>
 4    And 輸入 +
 5    And 輸入 <int2>
 6    And 點選 "計算"
 7    Then 看到 <sum>
 8
 9    Examples:
10      | int1 | int2 | sum |
11      | 1    | 2    | 3   |
12      | 9    | 7    | 16  |

像這樣子,我們可以把舉例中會使用到的內容以 <int1> 這樣的格式標記,在運行測試的時候就會自然的替換進去,也就可以用不同的輸入來進行驗證。

參數類型

回到步驟定義的 When John 點選 "測試好棒" 這段描述,如果我們直接使用前面提到的步驟定義實際上會發生問題,這時候就需要透過指定參數類型來處理。

1When('{string} 點擊 {string}') do |user, text|
2  click_on text
3end

原因在於 John 的格式不符合字串(String)的類型定義,也就是使用 "(雙引號)標記,然而如果加上雙引號寫起來也不是那麼直覺,那麼利用參數類型(Parameter Type)來輔助就變得容易很多。

1# features/supports/env.rb
2
3# ...
4
5ParameterType(
6  name: 'user',
7  regexp: /[A-Za-z]+/,
8  transformer: ->(name) { User.by_name(name) }
9)

我們可以直接定義一個叫做 user 的類型,並且自動的從資料庫中找到這個物件,這樣在步驟定義中就可以像這樣子改寫。

1When('{user} 點擊 {string}') do |user, text|
2  sign_in user # 以指定的使用者登入
3  click_on text
4end

在描述測試的時候,就能夠以更加直觀的方式進行,也更容易理解。