TL;DR

  • Cucumber обеспечивает BDD с тестами на простом английском (Gherkin-синтаксис)
  • Feature-файлы описывают поведение: Given (предусловия), When (действия), Then (результаты)
  • Step definitions связывают Gherkin-шаги с реальным тестовым кодом
  • Scenario Outlines позволяют data-driven тестирование с таблицами Examples
  • Интегрируется с Selenium, TestNG, JUnit для полной автоматизации тестирования

Идеально для: Команд, желающих бизнес-читаемые тесты, сотрудничество между QA и стейкхолдерами Пропусти, если: Маленькая команда, где разработчики пишут все тесты (традиционное тестирование быстрее) Время чтения: 15 минут

Твои тест-кейсы в Jira. Тестовый код в репозитории. Бизнес-требования в Confluence. Никто не знает, покрывают ли тесты требования на самом деле. Каждый спринт QA объясняет одни и те же сценарии стейкхолдерам.

Cucumber устраняет этот разрыв. Тесты пишутся на простом английском. Бизнес-стейкхолдеры могут их читать. Разработчики их реализуют. Все говорят на одном языке.

Этот туториал покрывает Cucumber от основ Gherkin до интеграции с CI/CD — всё для внедрения BDD в твоей команде.

Что такое BDD?

Behavior Driven Development (BDD) — это подход к разработке, где тесты пишутся на естественном языке, описывающем бизнес-поведение. Тесты становятся живой документацией, понятной всем.

Преимущества BDD:

  • Общее понимание — бизнес, QA и разработка говорят на одном языке
  • Живая документация — тесты описывают текущее поведение системы
  • Раннее обнаружение дефектов — требования валидируются до написания кода
  • Меньше переработок — чёткие спецификации предотвращают недопонимание

Что такое Cucumber?

Cucumber — это инструмент, поддерживающий BDD через выполнение plain-text спецификаций тестов, написанных на Gherkin. Он связывает человекочитаемые сценарии с автоматизированным тестовым кодом.

Как работает Cucumber:

  1. Пишешь feature-файлы на Gherkin (простой английский)
  2. Создаёшь step definitions (код, реализующий каждый шаг)
  3. Запускаешь Cucumber — он сопоставляет шаги с definitions и выполняет тесты
  4. Получаешь отчёты, показывающие какие сценарии прошли/упали

Установка

Java (Maven)

<dependencies>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>7.15.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>7.15.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.17.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

JavaScript (npm)

npm install @cucumber/cucumber --save-dev

Структура проекта

src/test/
├── java/
│   └── com/example/
│       ├── steps/
│       │   └── LoginSteps.java
│       ├── pages/
│       │   └── LoginPage.java
│       └── runners/
│           └── TestRunner.java
└── resources/
    └── features/
        └── login.feature

Gherkin-синтаксис

Feature-файл

# login.feature
Feature: User Login
  As a registered user
  I want to log into my account
  So that I can access my dashboard

  Background:
    Given the user is on the login page

  Scenario: Successful login with valid credentials
    When the user enters email "user@example.com"
    And the user enters password "password123"
    And the user clicks the login button
    Then the user should see the dashboard
    And the welcome message should contain "Welcome"

  Scenario: Failed login with invalid password
    When the user enters email "user@example.com"
    And the user enters password "wrongpassword"
    And the user clicks the login button
    Then the user should see an error message "Invalid credentials"

Ключевые слова

Ключевое словоНазначениеПример
FeatureОписывает тестируемую функциюFeature: User Login
ScenarioОдин тест-кейсScenario: Successful login
GivenПредусловия (setup)Given the user is on the login page
WhenВыполняемые действияWhen the user clicks login
ThenОжидаемые результатыThen the dashboard is displayed
And/ButДополнительные шагиAnd the user is logged in
BackgroundОбщие шаги для всех сценариевВыполняется перед каждым сценарием

Step Definitions

Базовые шаги

// LoginSteps.java
package com.example.steps;

import io.cucumber.java.en.*;
import static org.testng.Assert.*;

public class LoginSteps {

    private LoginPage loginPage;
    private DashboardPage dashboardPage;

    @Given("the user is on the login page")
    public void userIsOnLoginPage() {
        loginPage = new LoginPage(driver);
        loginPage.navigateTo();
    }

    @When("the user enters email {string}")
    public void userEntersEmail(String email) {
        loginPage.enterEmail(email);
    }

    @When("the user enters password {string}")
    public void userEntersPassword(String password) {
        loginPage.enterPassword(password);
    }

    @When("the user clicks the login button")
    public void userClicksLoginButton() {
        dashboardPage = loginPage.clickLogin();
    }

    @Then("the user should see the dashboard")
    public void userShouldSeeDashboard() {
        assertTrue(dashboardPage.isDisplayed());
    }

    @Then("the welcome message should contain {string}")
    public void welcomeMessageShouldContain(String expectedText) {
        String actualMessage = dashboardPage.getWelcomeMessage();
        assertTrue(actualMessage.contains(expectedText));
    }

    @Then("the user should see an error message {string}")
    public void userShouldSeeErrorMessage(String expectedError) {
        String actualError = loginPage.getErrorMessage();
        assertEquals(actualError, expectedError);
    }
}

Scenario Outline (Data-Driven Testing)

Feature: Login Validation

  Scenario Outline: Login with various credentials
    Given the user is on the login page
    When the user enters email "<email>"
    And the user enters password "<password>"
    And the user clicks the login button
    Then the login result should be "<result>"
    And the message should be "<message>"

    Examples:
      | email              | password    | result  | message              |
      | user@example.com   | password123 | success | Welcome back         |
      | admin@example.com  | admin123    | success | Welcome admin        |
      | user@example.com   | wrongpass   | failure | Invalid credentials  |
      |                    | password123 | failure | Email is required    |
      | user@example.com   |             | failure | Password is required |
@Then("the login result should be {string}")
public void loginResultShouldBe(String expectedResult) {
    if (expectedResult.equals("success")) {
        assertTrue(dashboardPage.isDisplayed());
    } else {
        assertTrue(loginPage.hasError());
    }
}

@Then("the message should be {string}")
public void messageShouldBe(String expectedMessage) {
    String actual = getCurrentMessage();
    assertEquals(actual, expectedMessage);
}

Hooks

// Hooks.java
package com.example.steps;

import io.cucumber.java.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Hooks {

    private static WebDriver driver;

    @BeforeAll
    public static void beforeAll() {
        // Выполняется один раз перед всеми сценариями
        System.out.println("Запуск тестового suite");
    }

    @Before
    public void before(Scenario scenario) {
        // Выполняется перед каждым сценарием
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        System.out.println("Запуск: " + scenario.getName());
    }

    @Before("@smoke")
    public void beforeSmoke() {
        // Только для сценариев с тегом @smoke
        System.out.println("Запуск smoke теста");
    }

    @After
    public void after(Scenario scenario) {
        // Выполняется после каждого сценария
        if (scenario.isFailed()) {
            // Скриншот при падении
            byte[] screenshot = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.BYTES);
            scenario.attach(screenshot, "image/png", "failure-screenshot");
        }
        driver.quit();
    }

    @AfterAll
    public static void afterAll() {
        // Выполняется один раз после всех сценариев
        System.out.println("Тестовый suite завершён");
    }

    public static WebDriver getDriver() {
        return driver;
    }
}

Теги

@regression
Feature: User Management

  @smoke @critical
  Scenario: Create new user
    Given I am logged in as admin
    When I create a new user
    Then the user should be created

  @slow
  Scenario: Generate user report
    Given I am on the reports page
    When I generate a full user report
    Then the report should be downloaded

Запуск тегированных сценариев

# Только smoke тесты
mvn test -Dcucumber.filter.tags="@smoke"

# Regression но не slow тесты
mvn test -Dcucumber.filter.tags="@regression and not @slow"

# smoke ИЛИ critical
mvn test -Dcucumber.filter.tags="@smoke or @critical"

Интеграция с Page Object

// LoginPage.java
public class LoginPage {
    private WebDriver driver;
    private WebDriverWait wait;

    private By emailField = By.id("email");
    private By passwordField = By.id("password");
    private By loginButton = By.id("login-btn");
    private By errorMessage = By.className("error");

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    public void navigateTo() {
        driver.get("https://example.com/login");
    }

    public void enterEmail(String email) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(emailField))
            .sendKeys(email);
    }

    public void enterPassword(String password) {
        driver.findElement(passwordField).sendKeys(password);
    }

    public DashboardPage clickLogin() {
        driver.findElement(loginButton).click();
        return new DashboardPage(driver);
    }

    public String getErrorMessage() {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(errorMessage))
            .getText();
    }
}

Test Runner

TestNG Runner

// TestRunner.java
package com.example.runners;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;

@CucumberOptions(
    features = "src/test/resources/features",
    glue = "com.example.steps",
    plugin = {
        "pretty",
        "html:target/cucumber-reports/report.html",
        "json:target/cucumber-reports/report.json"
    },
    tags = "@smoke or @regression"
)
public class TestRunner extends AbstractTestNGCucumberTests {

    @Override
    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        return super.scenarios();
    }
}

Интеграция с CI/CD

GitHub Actions

name: Cucumber Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Run Cucumber tests
        run: mvn test -Dcucumber.filter.tags="@smoke"

      - name: Publish report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: cucumber-report
          path: target/cucumber-reports/

Cucumber с помощью ИИ

ИИ-инструменты могут помочь писать и поддерживать Cucumber-тесты.

Что ИИ делает хорошо:

  • Генерация Gherkin-сценариев из user stories
  • Создание step definitions из feature-файлов
  • Предложение тестовых данных для scenario outlines
  • Выявление недостающих edge cases

Что всё ещё требует людей:

  • Определение бизнес-релевантных сценариев
  • Баланс покрытия и поддерживаемости
  • Валидация сценариев со стейкхолдерами
  • Рефакторинг дублирующихся шагов

FAQ

Что такое Cucumber?

Cucumber — это BDD (Behavior Driven Development) инструмент для тестирования, позволяющий писать тесты на простом английском с Gherkin-синтаксисом. Feature-файлы описывают поведение приложения, которое могут понять как технические, так и нетехнические члены команды. Step definitions связывают эти человекочитаемые спецификации с реальным кодом автоматизации.

Что такое Gherkin?

Gherkin — это предметно-ориентированный язык Cucumber для написания тестовых сценариев в виде простого текста. Он использует ключевые слова Feature, Scenario, Given, When, Then для структурирования тестов в читаемом формате. Синтаксис спроектирован быть понятным всем в команде — разработчикам, QA-инженерам, продакт-менеджерам и бизнес-стейкхолдерам.

Cucumber бесплатный?

Да, Cucumber полностью бесплатен и open-source. Он доступен для множества языков программирования, включая Java, JavaScript, Ruby, Python и Kotlin. Нет платных версий или enterprise-функций — вся функциональность доступна бесплатно.

Cucumber vs Selenium — в чём разница?

Cucumber и Selenium служат разным целям и работают вместе. Cucumber определяет что тестировать через Gherkin-сценарии (спецификация). Selenium выполняет браузерную автоматизацию (исполнение). В типичной настройке Cucumber-сценарии описывают ожидаемое поведение, а step definitions используют Selenium для взаимодействия с браузером и проверки результатов.

Официальные ресурсы

Смотрите также