«1. Введение

Cucumber — это среда тестирования BDD (Behavioral Driven Development).

Использование фреймворка для написания повторяющихся сценариев с различными перестановками входных/выходных данных может занять довольно много времени, сложно поддерживать и, конечно, разочаровывать.

В Cucumber есть решение для сокращения этих усилий с помощью концепции схемы сценария в сочетании с примерами. В следующем разделе мы попытаемся рассмотреть пример и посмотреть, как мы можем свести к минимуму эти усилия.

Если вы хотите узнать больше о подходе и языке Gherkin, прочтите эту статью.

2. Добавление поддержки Cucumber

Чтобы добавить поддержку Cucumber в простой проект Maven, нам потребуется добавить следующие зависимости:

<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>1.2.5</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>info.cukes</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>1.2.5</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-library</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>

Полезные ссылки на зависимости от Maven Central: огурец-junit, огурец -java, hamcrest-library

Так как это тестовые библиотеки, их не нужно поставлять вместе с развертываемыми — вот почему все они тестируются.

3. Простой пример

Давайте продемонстрируем как раздутый, так и лаконичный способ написания избранных файлов. Давайте сначала определим логику, для которой мы хотим написать тест:

Давайте сначала определим логику, для которой мы хотим написать тест:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

4. Определение тестов Cucumber

4.1. Определение файла функций

Feature: Calculator
  As a user
  I want to use a calculator to add numbers
  So that I don't need to add myself

  Scenario: Add two numbers -2 & 3
    Given I have a calculator
    When I add -2 and 3
    Then the result should be 1
   
  Scenario: Add two numbers 10 & 15
    Given I have a calculator
    When I add 10 and 15
    Then the result should be 25

Как видно здесь, для проверки логики сложения были помещены 2 разные комбинации чисел. Если не считать цифр, все сценарии абсолютно одинаковы.

4.2. «Склеивающий» код

Чтобы протестировать эти сценарии, необходимо определить каждый шаг соответствующим кодом, чтобы преобразовать оператор в функциональный фрагмент кода:

public class CalculatorRunSteps {

    private int total;

    private Calculator calculator;

    @Before
    private void init() {
        total = -999;
    }

    @Given("^I have a calculator$")
    public void initializeCalculator() throws Throwable {
        calculator = new Calculator();
    }

    @When("^I add (-?\\d+) and (-?\\d+)$")
    public void testAdd(int num1, int num2) throws Throwable {
        total = calculator.add(num1, num2);
    }

    @Then("^the result should be (-?\\d+)$")
    public void validateResult(int result) throws Throwable {
        Assert.assertThat(total, Matchers.equalTo(result));
    }
}

4.3. Класс Runner

Чтобы интегрировать функции и связующий код, мы можем использовать JUnit runners:

@RunWith(Cucumber.class)
@CucumberOptions(
  features = { "classpath:features/calculator.feature" },
  glue = {"com.baeldung.cucumber.calculator" })
public class CalculatorTest {}

5. Переписывание функций с использованием структуры сценария

Мы видели в Разделе 4.1. как определение файла функций может быть трудоемкой задачей и более подвержено ошибкам. Тот же самый файл функции можно сократить до нескольких строк, используя схему сценария:

Feature: Calculator
  As a user
  I want to use a calculator to add numbers
  So that I don't need to add myself

  Scenario Outline: Add two numbers <num1> & <num2>
    Given I have a calculator
    When I add <num1> and <num2>
    Then the result should be <total>

  Examples: 
    | num1 | num2 | total |
    | -2 | 3 | 1 |
    | 10 | 15 | 25 |
    | 99 | -99 | 0 |
    | -1 | -10 | -11 |

При сравнении обычного определения сценария со схемой сценария значения больше не нужно жестко задавать в определениях шагов. Значения заменяются параметрами как \u003cимя_параметра\u003e в самом определении шага.

В конце схемы сценария значения определяются в формате таблицы с разделителями вертикальной чертой с использованием примеров.

Образец для определения примеров показан ниже:

Examples:
  | Parameter_Name1 | Parameter_Name2 |
  | Value-1 | Value-2 |
  | Value-X | Value-Y |

6. Заключение

В этой краткой статье мы показали, как можно сделать сценарии общими по своей природе. А также сократить усилия по написанию и сопровождению этих сценариев.

Полный исходный код этой статьи можно найти на GitHub.