Что такое BDD (Behavior-Driven Development)?
BDD (Behavior-Driven Development) — это методология разработки, основанная на принципах TDD (Test-Driven Development), но с акцентом на поведение приложения с точки зрения бизнеса. Вместо написания тестов, проверяющих как реализована функциональность, BDD фокусируется на что должна делать система. Ключевым аспектом является использование простого, понятного для всех заинтересованных сторон языка (например, Gherkin) для описания сценариев поведения.
Обзор Selenium WebDriver: автоматизация браузера
Selenium WebDriver — это мощный инструмент для автоматизированного тестирования веб-приложений. Он позволяет программно управлять браузером, имитируя действия пользователя: клики, ввод текста, навигацию по страницам и т.д. Selenium WebDriver поддерживает различные браузеры (Chrome, Firefox, Safari, Edge) и языки программирования (Java, Python, C#, Ruby и др.).
TestNG: фреймворк для тестирования Java
TestNG — это популярный фреймворк для тестирования Java, вдохновленный JUnit и NUnit. Он предоставляет широкие возможности для организации тестов, управления их выполнением, создания отчетов и параллельного запуска. TestNG поддерживает аннотации, параметризацию тестов, группы тестов и другие полезные функции.
Cucumber: связующее звено для BDD
Cucumber — это инструмент, реализующий принципы BDD. Он позволяет описывать поведение приложения на естественном языке (Gherkin) и связывать эти описания с кодом, который выполняет автоматизированные проверки. Cucumber выступает в роли связующего звена между бизнес-требованиями и технической реализацией.
Настройка окружения разработки
Установка Java Development Kit (JDK)
Убедитесь, что у вас установлена Java Development Kit (JDK) версии 8 или выше. Скачать JDK можно с официального сайта Oracle или использовать OpenJDK. После установки необходимо настроить переменную окружения JAVA_HOME, указывающую на каталог установки JDK.
Установка и настройка Integrated Development Environment (IDE) (IntelliJ IDEA, Eclipse)
Для разработки рекомендуется использовать интегрированную среду разработки (IDE), такую как IntelliJ IDEA или Eclipse. IntelliJ IDEA является более популярным выбором благодаря своей удобной интеграции с Maven и Cucumber. Установите IDE и настройте ее для работы с Java.
Установка Maven и добавление зависимостей (Selenium WebDriver, TestNG, Cucumber)
Maven — это инструмент для управления зависимостями и сборки проектов Java. Установите Maven и создайте новый Maven-проект. Добавьте следующие зависимости в файл pom.xml:
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.15.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>7.15.0</version>
</dependency>
</dependencies>
Настройка WebDriver (ChromeDriver, GeckoDriver и т.д.)
Selenium WebDriver требует наличия драйверов для управления конкретными браузерами. Скачайте драйвер для нужного браузера (ChromeDriver для Chrome, GeckoDriver для Firefox и т.д.) и укажите путь к нему в коде или добавьте его в переменную окружения PATH.
Пример установки пути к ChromeDriver:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class WebDriverSetup {
public static WebDriver setupDriver() {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
return new ChromeDriver();
}
}
Создание структуры проекта BDD
Организация каталогов: feature-файлы, step definitions, page objects, runner-классы
Рекомендуемая структура проекта:
src/
main/
java/
- (исходный код приложения, если это необходимо)
test/
java/
runners/ (Runner-классы Cucumber)
stepDefinitions/ (Step definitions)
pageObjects/ (Page objects)
resources/
features/ (Feature-файлы)
Написание feature-файлов с использованием Gherkin (Given, When, Then, And, But)
Feature-файлы описывают поведение приложения на языке Gherkin. Каждый файл описывает одну функциональность (feature) и состоит из сценариев (scenarios). Сценарии состоят из шагов, начинающихся с ключевых слов Given, When, Then, And, But.
Пример feature-файла (login.feature):
Feature: Login functionality
As a user
I want to be able to log in to the system
So that I can access my account
Scenario: Successful login with valid credentials
Given I am on the login page
When I enter valid username "user123" and password "password123"
And I click the login button
Then I should be redirected to the home page
And I should see a welcome message
Scenario: Unsuccessful login with invalid credentials
Given I am on the login page
When I enter invalid username "invalid_user" and password "invalid_password"
And I click the login button
Then I should see an error message
Реализация step definitions: связывание Gherkin-шагов с кодом Selenium
Step definitions — это классы Java, которые связывают шаги Gherkin с кодом Selenium. Для каждого шага в feature-файле должна быть соответствующая step definition. Step definitions используют аннотации Cucumber (@Given, @When, @Then, @And, @But) для сопоставления шагов с методами Java.
Пример step definitions (LoginSteps.java):
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
public class LoginSteps {
private WebDriver driver;
public LoginSteps(WebDriver driver) { // Dependency Injection
this.driver = driver;
}
@Given("I am on the login page")
public void iAmOnTheLoginPage() {
driver.get("http://example.com/login");
}
@When("I enter valid username {string} and password {string}")
public void iEnterValidUsernameAndPassword(String username, String password) {
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
}
@When("I click the login button")
public void iClickTheLoginButton() {
driver.findElement(By.id("login_button")).click();
}
@Then("I should be redirected to the home page")
public void iShouldBeRedirectedToTheHomePage() {
Assert.assertEquals(driver.getCurrentUrl(), "http://example.com/home");
}
@Then("I should see a welcome message")
public void iShouldSeeAWelcomeMessage() {
WebElement welcomeMessage = driver.findElement(By.id("welcome_message"));
Assert.assertTrue(welcomeMessage.isDisplayed());
}
@When("I enter invalid username {string} and password {string}")
public void iEnterInvalidUsernameAndPasswordInvalid(String username, String password) {
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
}
@Then("I should see an error message")
public void iShouldSeeAnErrorMessage() {
WebElement errorMessage = driver.findElement(By.id("error_message"));
Assert.assertTrue(errorMessage.isDisplayed());
}
}
Важно: Обратите внимание на использование параметризации в шагах Gherkin ({string}) и передачу параметров в step definitions.
Создание page object-ов: инкапсуляция элементов веб-страницы и действий с ними
Page objects — это классы Java, которые представляют веб-страницы и инкапсулируют элементы веб-страницы (WebElements) и действия с ними. Использование page objects позволяет упростить и поддерживать код step definitions, а также избежать дублирования кода.
Пример page object (LoginPage.java):
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class LoginPage {
private WebDriver driver;
private By usernameField = By.id("username");
private By passwordField = By.id("password");
private By loginButton = By.id("login_button");
private By errorMessage = By.id("error_message");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void enterUsername(String username) {
driver.findElement(usernameField).sendKeys(username);
}
public void enterPassword(String password) {
driver.findElement(passwordField).sendKeys(password);
}
public void clickLoginButton() {
driver.findElement(loginButton).click();
}
public boolean isErrorMessageDisplayed() {
return driver.findElement(errorMessage).isDisplayed();
}
}
Использование Page Objects в Step Definitions:
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import org.openqa.selenium.WebDriver;
import org.testng.Assert;
public class LoginSteps {
private WebDriver driver;
private LoginPage loginPage;
public LoginSteps(WebDriver driver) {
this.driver = driver;
this.loginPage = new LoginPage(driver);
}
@Given("I am on the login page")
public void iAmOnTheLoginPage() {
driver.get("http://example.com/login");
}
@When("I enter valid username {string} and password {string}")
public void iEnterValidUsernameAndPassword(String username, String password) {
loginPage.enterUsername(username);
loginPage.enterPassword(password);
}
@When("I click the login button")
public void iClickTheLoginButton() {
loginPage.clickLoginButton();
}
@Then("I should see an error message")
public void iShouldSeeAnErrorMessage() {
Assert.assertTrue(loginPage.isErrorMessageDisplayed());
}
// ... остальные шаги
}
Интеграция TestNG и Cucumber
Создание Runner-класса с использованием аннотаций @RunWith и @CucumberOptions
Runner-класс — это класс Java, который запускает тесты Cucumber. Он использует аннотации @RunWith и @CucumberOptions для настройки запуска тестов.
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;
@CucumberOptions(
features = "src/test/resources/features",
glue = "stepDefinitions",
plugin = {"pretty", "html:target/cucumber-report.html", "json:target/cucumber.json"}
)
public class RunCucumberTest extends AbstractTestNGCucumberTests {
@Override
@DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}
features: указывает путь к feature-файлам.glue: указывает путь к step definitions.plugin: определяет форматы отчетов.
Настройка TestNG suite для запуска Cucumber-тестов
Можно создать файл testng.xml для настройки запуска тестов TestNG и Cucumber. Этот файл позволяет определить группы тестов, параметры и другие настройки.
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Cucumber Tests">
<test name="Login Tests">
<classes>
<class name="RunCucumberTest"/>
</classes>
</test>
</suite>
Использование хуков TestNG (BeforeSuite, AfterSuite, BeforeTest, AfterTest) для настройки и завершения работы
Хуки TestNG позволяют выполнять код до и после выполнения тестов. Например, можно использовать @BeforeSuite для инициализации WebDriver, а @AfterSuite для его завершения. Это может быть удобно, если требуется настроить окружение один раз для всех тестов, а не для каждого сценария.
Параллельный запуск тестов с TestNG и Cucumber
TestNG поддерживает параллельный запуск тестов, что позволяет значительно ускорить выполнение тестов. Для включения параллельного запуска необходимо настроить файл testng.xml или использовать аннотацию @DataProvider(parallel = true) в Runner-классе. Правильная настройка параллельного запуска с Cucumber требует внимания к управлению состоянием WebDriver, чтобы избежать конфликтов между потоками. В большинстве случаев, использование dependency injection для передачи экземпляра WebDriver в step definitions помогает избежать проблем.
Запуск тестов и анализ результатов
Запуск тестов из IDE (IntelliJ IDEA, Eclipse)
Тесты Cucumber можно запустить непосредственно из IDE, запустив Runner-класс как обычный Java-класс или используя контекстное меню для запуска TestNG suite.
Запуск тестов из командной строки с использованием Maven
Для запуска тестов из командной строки используйте команду Maven:
mvn test
Maven автоматически запустит тесты, определенные в файле testng.xml или в Runner-классе.
Генерация отчетов Cucumber (HTML, JSON, JUnit)
Cucumber может генерировать отчеты в различных форматах, таких как HTML, JSON и JUnit. Формат отчета указывается в аннотации @CucumberOptions в Runner-классе. HTML-отчет является наиболее удобным для анализа результатов тестов.
Интеграция с системами CI/CD (Jenkins, TeamCity)
Интеграция с системами CI/CD (Continuous Integration/Continuous Delivery) позволяет автоматизировать запуск тестов при каждом изменении кода. Системы CI/CD, такие как Jenkins или TeamCity, могут запускать Maven-команду mvn test и собирать отчеты Cucumber для анализа результатов. Также, эти системы могут использоваться для автоматического развертывания приложения после успешного прохождения тестов.