Cucumber là công cụ kiểm thử theo hướng BDD (Behavior Driven Development) — mô tả hành vi hệ thống bằng ngôn ngữ tự nhiên (Gherkin), giúp dev, tester và business đều hiểu.


🧠 1. Core Concept

┌─────────────────────────────────────────────────┐
│  Traditional Testing    vs    BDD Testing      │
├─────────────────────────────────────────────────┤
│  Code-first              →    Behavior-first   │
│  Dev hiểu                →    Team hiểu        │
│  Test isolated           →    Living docs      │
└─────────────────────────────────────────────────┘

👉 Tư duy BDD: Không viết test → Viết kịch bản hành vi hệ thống


🔁 2. Cucumber Flow

┌──────────────────────────────────────────────────────────┐
│                    CUCUMBER FLOW                         │
└──────────────────────────────────────────────────────────┘

  BA / Tester / Dev
        │
        ▼
  ┌─────────────────┐
  │  .feature file  │  ← Gherkin syntax
  │  (Ngôn ngữ TN)  │
  └────────┬────────┘
           │
           ▼
  ┌─────────────────┐
  │ Cucumber Engine │  ← Parser + Matcher
  └────────┬────────┘
           │
           ▼
  ┌─────────────────┐
  │ Step Definitions│  ← Code thực thi (JS/TS/Java)
  └────────┬────────┘
           │
           ▼
  ┌─────────────────┐
  │ Test Framework  │  ← Playwright / Selenium / Cypress
  └────────┬────────┘
           │
           ▼
  ┌─────────────────┐
  │   Application   │  ← Web / API / Mobile
  └────────┬────────┘
           │
           ▼
     Result (Pass/Fail)

🧩 3. Gherkin Syntax

File .feature

Feature: User Login

  Scenario: Login thành công
    Given user đang ở trang login
    When user nhập đúng username và password
    And user click nút Login
    Then user được chuyển đến dashboard

Mapping sang Code (Step Definitions)

┌─────────────────────────────────────────────────────────┐
│  Gherkin Step              →    Step Definition        │
├─────────────────────────────────────────────────────────┤
│  Given user ở trang login  →    page.goto('/login')    │
│  When user nhập ...        →    page.fill(...)         │
│  Then user thấy dashboard  →    expect(page).toHave... │
└─────────────────────────────────────────────────────────┘

Code thực tế (TypeScript + Playwright)

import { Given, When, Then } from "@cucumber/cucumber";

Given("user đang ở trang login", async function () {
  await this.page.goto("/login");
});

When("user nhập đúng username và password", async function () {
  await this.page.fill("#username", "admin");
  await this.page.fill("#password", "secret");
});

Then("user được chuyển đến dashboard", async function () {
  await expect(this.page).toHaveURL("/dashboard");
});

🧱 4. Các thành phần chính

┌────────────────┬──────────────────────────────────┐
│  Component     │  Role                            │
├────────────────┼──────────────────────────────────┤
│  Feature       │  Mô tả tính năng (1 file)        │
│  Scenario      │  Kịch bản test cụ thể            │
│  Given         │  Precondition (trạng thái đầu)   │
│  When          │  Action (hành động)              │
│  Then          │  Expected Result (kết quả)       │
│  And / But     │  Nối thêm step                   │
│  Background    │  Setup chung cho mọi scenario    │
│  Scenario Outline │  Data-driven test             │
└────────────────┴──────────────────────────────────┘

🔍 5. Advanced: Scenario Outline (Data-Driven)

Feature: Login Validation

  Scenario Outline: Login với nhiều credentials
    Given user ở trang login
    When user nhập "<username>""<password>"
    Then kết quả là "<result>"

    Examples:
      | username | password | result    |
      | admin    | 123456   | success   |
      | admin    | wrong    | error     |
      | invalid  | 123456   | error     |

👉 1 Scenario Outline = N test cases


📁 6. Project Structure

project/
├── features/
│   ├── login.feature
│   ├── checkout.feature
│   └── step_definitions/
│       ├── login.steps.ts
│       └── checkout.steps.ts
├── support/
│   ├── world.ts          ← Shared context
│   └── hooks.ts          ← Before/After
├── cucumber.js           ← Config
└── package.json

⚡ 7. Khi nào nên dùng Cucumber?

┌─────────────────────────────────────────────────────────┐
│  ✅ NÊN DÙNG                │  ❌ KHÔNG CẦN             │
├─────────────────────────────────────────────────────────┤
│  Team có BA/non-tech        │  Dev tự test là chính     │
│  Cần living documentation   │  Project nhỏ, prototype   │
│  Product lớn, nhiều stakeholder │  Không cần readable test │
│  Compliance/audit required  │  Team chỉ có dev          │
└─────────────────────────────────────────────────────────┘

🎯 8. Best Practices

┌──────────────────────────────────────────────────────────┐
│  DO                          │  DON'T                   │
├──────────────────────────────────────────────────────────┤
│  Viết scenario ngắn gọn      │  Quá nhiều step (>7)     │
│  Dùng Background cho setup   │  Duplicate steps         │
│  Tên step rõ ràng, business  │  Technical details       │
│  Reuse step definitions      │  Hardcode data           │
│  1 scenario = 1 behavior     │  Test nhiều thứ 1 lúc    │
└──────────────────────────────────────────────────────────┘

🚀 9. Setup nhanh (Playwright + Cucumber)

npm init -y
npm install @cucumber/cucumber playwright @playwright/test
npx playwright install

cucumber.js

module.exports = {
  default: {
    require: ["features/step_definitions/*.ts"],
    format: ["progress", "html:reports/cucumber.html"],
    paths: ["features/*.feature"],
  },
};

💡 10. Tóm gọn

┌─────────────────────────────────────────────────────────┐
│  Cucumber = Gherkin (spec) + Step Definitions (code)   │
│                           ↓                             │
│        Test readable by everyone + Automation           │
└─────────────────────────────────────────────────────────┘

“Viết test như kể chuyện → Team hiểu → System đúng hành vi”


📚 Resources