---
title: "基本語法：驗證行為 - Cucumber 的文件測試法"
date: 2024-01-19T00:00:00+08:00
publishDate: 2024-01-19T00:00:00+08:00
lastmod: 2023-12-06T15:50:15+08:00
tags: ["Cucumber","教學","測試","Gherkin"]
series: "test-with-cucumber"
toc: true
permalink: "https://blog.aotoki.me/posts/2024/01/19/test-with-cucumber-syntax-assert/"
language: "zh-tw"
---


對功能描述之後，我們需要將詳細的步驟寫下來，讓 Cucumber 知道該怎麼做來檢查這個功能是否符合預期，因此我們可以使用 Given、When、Then 來進行描述。

<!--more-->

## Given

Given 的用途是用來提供背景資訊，通常就是建立假資料的處理，讓我們可以繼續後續的處理。

```gherkin
Feature: 喜歡文章
  Scenario: 當 John 第一次點選「測試好棒」喜歡按鈕時時，喜歡次數增加
    Given 這裡有一篇文章 "測試好棒"
    # ...
```

如果要建立多筆資料 Cucumber 提供了 Table（表格）的機制，可以改寫為這樣的描述。

```gherkin
Feature: 喜歡文章
  Scenario: 當 John 第一次點選「測試好棒」喜歡按鈕時時，喜歡次數增加
    Given 這裡有幾篇文章
      | title   | author |
      | 測試好棒 | 蒼時    |
      | 好用密技 | 蒼時    |
    # ...
```

可以根據需求提供單數或者複數的描述，為了確保背景資訊是完善被提供的，盡可能的把完整資訊寫下來會有更好的效果。

## When

When 用來指定進行的動作，也就是這個測試的行為，但不一定是只限一個，我們可以有複數的操作來進行動作的對應。

```gherkin
Feature: 喜歡文章
  Background:
    When John 打開文章列表

  Scenario: 當 John 第一次點選「測試好棒」喜歡按鈕時時，喜歡次數增加
	Given 有一個作者叫做 "蒼時"
    And 這裡有幾篇文章
      | title   | author |
      | 測試好棒 | 蒼時    |
      | 好用密技 | 蒼時    |
    When John 點選 "測試好棒"
    And John 點選 "喜歡"
    # ...
```

以上面的 Cucumber 測試當作範例，我們可以看到 John 會先點選「測試好棒」這篇文章，並且再去點選「喜歡」完成我們預期的動作，他會是複數的操作來完成，這樣也更能清楚的說明完整的使用者操作。

在 Gherkin 的語法裡面，如果跟前一個動作是相同的類型，可以用 And 來連接，而不需要寫兩次 Given 或者 When 會更接近人類閱讀的習慣。

> 假設所有操作都是以文章列表為起點，我們還可以在背景資訊預先放好一些 When 的動作

## Then

Then 是用來進行斷言（Assertion）的方法，跟大多數測試框架一樣，可以在一個測試中做多次斷言，也可以只使用一個，我們也可以在需要多次斷言時使用 And 來連接。

```gherkin
Feature: 喜歡文章
  Background:
    When John 打開文章列表

  Scenario: 當 John 第一次點選「測試好棒」喜歡按鈕時時，喜歡次數增加
	Given 有一個作者叫做 "蒼時"
    And 這裡有幾篇文章
      | title   | author | like_count |
      | 測試好棒 | 蒼時    | 0          |
      | 好用密技 | 蒼時    | 0          |
    When John 點選 "測試好棒"
    And John 點選 "喜歡"
    Then John 會看到 "感謝你的支持"
    And John 會看到喜歡統計變成 1
```

在 Cucumber 的測試中，因為不太會有執行兩次比較前後差異的情境，因此在撰寫 Then 類型的斷言時，比起用「增加 1」我會使用更明確的「變成 1」來描述，如果想要表現出每次點選都是增加 1 的意圖，我們可以用多個測試案例來呈現這樣的意圖。

目前我們有了完整的測試，然而還是無法運行的，現階段我們會先熟悉 Gherikn 相關的語法後，再針對 Ruby 和 TypeScript 是如何將這些句子轉換成真實的行為進行說明。

