Перейти к основному содержимому

Введение в Serenity BDD

· 7 мин. чтения

1. Введение

В этом руководстве мы познакомимся с Serenity BDD — отличным инструментом для применения Behavior Driven Development (BDD) . Это решение для автоматизированного приемочного тестирования, которое генерирует хорошо иллюстрированные отчеты о тестировании.

2. Основные концепции

Концепции, лежащие в основе Serenity, следуют концепциям, лежащим в основе BDD. Если вы хотите узнать больше об этом, прочтите нашу статью о Cucumber и JBehave .

2.1. Требования

В Serenity требования разделены на три уровня:

  1. возможности
  2. Особенности
  3. рассказы

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

2.2. Шаги и тесты

Шаги содержат группу операций по управлению ресурсами. Это может быть действие, проверка или операция, связанная с контекстом. Классический формат Given_When_Then может быть отражен в шагах.

И тесты идут рука об руку с Шагами. Каждый тест рассказывает простую пользовательскую историю, которая выполняется с помощью определенного Step .

2.3. Отчеты

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

3. Тестирование с SerenityBDD

Чтобы запустить наши тесты Serenity с JUnit, нам нужно @RunWith SerenityRunner , средство запуска тестов. SerenityRunner использует библиотеки шагов и гарантирует, что результаты теста будут записаны и представлены репортерами Serenity.

3.1. Зависимости Maven

Чтобы использовать Serenity с JUnit, мы должны включить serenity-core и serenity-junit в pom.xml:

<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-core</artifactId>
<version>1.2.5-rc.11</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
<version>1.2.5-rc.11</version>
</dependency>

Нам также нужен плагин serenity-maven-plugin для агрегирования отчетов по результатам тестирования:

<plugin>
<groupId>net.serenity-bdd.maven.plugins</groupId>
<artifactId>serenity-maven-plugin</artifactId>
<version>1.2.5-rc.6</version>
<executions>
<execution>
<id>serenity-reports</id>
<phase>post-integration-test</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>

Если мы хотим, чтобы Serenity генерировала отчеты даже в случае сбоя теста, добавьте в pom.xml следующее:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>

3.2. Пример членских баллов

Первоначально наши тесты основаны на типичной функции членских баллов в приложении электронной коммерции. Клиент может присоединиться к членской программе. По мере того, как клиент покупает товары на платформе, баллы членства будут увеличиваться, и соответственно будет расти уровень членства клиента.

Теперь давайте напишем несколько тестов для описанных выше сценариев и посмотрим, как работает Serenity.

Во-первых, давайте напишем тест для инициализации членства и посмотрим, какие шаги нам нужны:

@RunWith(SerenityRunner.class)
public class MemberStatusIntegrationTest {

@Steps
private MemberStatusSteps memberSteps;

@Test
public void membersShouldStartWithBronzeStatus() {
memberSteps.aClientJoinsTheMemberProgram();
memberSteps.theMemberShouldHaveAStatusOf(Bronze);
}
}

Затем мы реализуем два шага следующим образом:

public class MemberStatusSteps {

private Member member;

@Step("Given a member has {0} points")
public void aMemberHasPointsOf(int points) {
member = Member.withInitialPoints(points);
}

@Step("Then the member grade should be {0}")
public void theMemberShouldHaveAStatusOf(MemberGrade grade) {
assertThat(member.getGrade(), equalTo(grade));
}
}

Теперь мы готовы запустить интеграционный тест с mvn clean verify . Отчеты будут расположены по адресу target/site/serenity/index.html :

./24b220b76412e92554b0074ad7501adb.png

Из отчета видно, что у нас есть только один приемочный тест «Члены должны начать с бронзового статуса, имеет возможность», и он проходит. Нажав на тест, шаги проиллюстрированы:

./e664f5fddf02deaa2f34d0dab83bb0be.png

Как мы видим, отчет Serenity дает нам полное представление о том, что делает наше приложение и соответствует ли оно нашим требованиям. Если у нас есть какие-то шаги для реализации, мы можем пометить их как @Pending :

@Pending
@Step("When the member exchange {}")
public void aMemberExchangeA(Commodity commodity){
//TODO
}

Отчет напомнит нам, что нужно делать дальше. А если какой-то тест не пройден, это видно и в отчете:

./35d81ec4220529e0696664e4c73b30bc.png

Каждый неудачный, проигнорированный или пропущенный шаг будет указан соответственно:

./bff892f553ddbb5d29c5a7822cd500a8.png

4. Интеграция с JBehave

Serenity также может интегрироваться с существующими платформами BDD, такими как JBehave.

4.1. Зависимости Maven

Для интеграции с JBehave в POM нужна еще одна зависимость serenity-jbehave :

<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-jbehave</artifactId>
<version>1.24.0</version>
</dependency>

4.2. Продолжение тестирования JBehave Github REST API

Поскольку мы представили, как выполнять тестирование REST API с помощью JBehave , мы можем продолжить наш тест JBehave REST API и посмотреть, как он вписывается в Serenity.

Наша история была:

Scenario: Github user's profile should have a login payload same as username

Given github user profile api
When I look for foreach via the api
Then github's response contains a 'login' payload same as foreach

Шаги Given_When_Then можно перенести в @Steps без каких-либо изменений:

public class GithubRestUserAPISteps {

private String api;
private GitHubUser resource;

@Step("Given the github REST API for user profile")
public void withUserProfileAPIEndpoint() {
api = "https://api.github.com/users/%s";
}

@Step("When looking for {0} via the api")
public void getProfileOfUser(String username) throws IOException {
HttpResponse httpResponse = getGithubUserProfile(api, username);
resource = retrieveResourceFromResponse(httpResponse, GitHubUser.class);
}

@Step("Then there should be a login field with value {0} in payload of user {0}")
public void profilePayloadShouldContainLoginValue(String username) {
assertThat(username, Matchers.is(resource.getLogin()));
}

}

Чтобы сопоставление истории и кода JBehave работало должным образом, нам нужно реализовать определение шага JBehave с помощью @Steps :

public class GithubUserProfilePayloadStepDefinitions {

@Steps
GithubRestUserAPISteps userAPISteps;

@Given("github user profile api")
public void givenGithubUserProfileApi() {
userAPISteps.withUserProfileAPIEndpoint();
}

@When("looking for $user via the api")
public void whenLookingForProfileOf(String user) throws IOException {
userAPISteps.getProfileOfUser(user);
}

@Then("github's response contains a 'login' payload same as $user")
public void thenGithubsResponseContainsAloginPayloadSameAs(String user) {
userAPISteps.profilePayloadShouldContainLoginValue(user);
}
}

С SerenityStories мы можем запускать тесты JBehave как из нашей IDE, так и в процессе сборки:

import net.serenitybdd.jbehave.SerenityStory;

public class GithubUserProfilePayload extends SerenityStory {}

После завершения проверки сборки мы можем увидеть наш тестовый отчет:

./c4a027576f80ae312ea4679fb0e88f8f.png

По сравнению с обычным текстовым отчетом JBehave, расширенный отчет Serenity дает нам более приятный для глаз и живой обзор нашей истории и результатов теста.

5. Интеграция с REST-гарантией

Примечательно, что Serenity поддерживает интеграцию с REST-assured . Чтобы получить обзор REST-assured, ознакомьтесь с руководством по REST-assured .

5.1. Зависимости Maven

Чтобы использовать REST-assured с Serenity, необходимо включить зависимость serenity-rest-assured :

<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-rest-assured</artifactId>
<version>1.2.5-rc.11</version>
</dependency>

5.2. Используйте REST-assured в Github REST API Test

Теперь мы можем заменить наш веб-клиент REST-утилитами:

import static net.serenitybdd.rest.SerenityRest.rest;
import static net.serenitybdd.rest.SerenityRest.then;

public class GithubRestAssuredUserAPISteps {

private String api;

@Step("Given the github REST API for user profile")
public void withUserProfileAPIEndpoint() {
api = "https://api.github.com/users/{username}";
}

@Step("When looking for {0} via the api")
public void getProfileOfUser(String username) throws IOException {
rest().get(api, username);
}

@Step("Then there should be a login field with value {0} in payload of user {0}")
public void profilePayloadShouldContainLoginValue(String username) {
then().body("login", Matchers.equalTo(username));
}

}

После замены реализации userAPISteps в StepDefition мы можем повторно запустить сборку с проверкой :

public class GithubUserProfilePayloadStepDefinitions {

@Steps
GithubRestAssuredUserAPISteps userAPISteps;

//...

}

В отчете мы можем увидеть фактический API, вызванный во время теста, и, нажав кнопку REST Query , будут представлены подробности запроса и ответа:

./36c9d146c8cd693163bd6dc27fc0b35d.png

6. Интеграция с JIRA

На данный момент у нас уже есть отличный отчет о тестировании, описывающий детали и статус наших требований к фреймворку Serenity. Но для гибкой команды часто используются системы отслеживания проблем, такие как JIRA, для отслеживания требований. Было бы лучше, если бы мы могли использовать их беспрепятственно.

К счастью, Serenity уже поддерживает интеграцию с JIRA.

6.1. Зависимости Maven

Для интеграции с JIRA нам нужна еще одна зависимость: serenity-jira-requirements-provider .

<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-jira-requirements-provider</artifactId>
<version>1.1.3-rc.5</version>
</dependency>

6.2. Односторонняя интеграция

Чтобы добавить ссылки JIRA в историю, мы можем добавить задачу JIRA, используя метатег истории:

Meta:
@issue #BDDTEST-1

Кроме того, JIRA-аккаунт и ссылки должны быть указаны в файле serenity.properties в корне проекта:

jira.url=<jira-url>
jira.project=<jira-project>
jira.username=<jira-username>
jira.password=<jira-password>

Затем в отчет будет добавлена ссылка JIRA:

./6281900bc9548210af4a0f01dd108825.png

Serenity также поддерживает двустороннюю интеграцию с JIRA . Подробную информацию можно найти в официальной документации .

7. Резюме

В этой статье мы представили Serenity BDD и несколько интеграций с другими средами тестирования и системами управления требованиями.

Хотя мы рассмотрели большую часть того, что может сделать Serenity, он, безусловно, может больше. В нашей следующей статье мы расскажем о том, как Serenity с поддержкой WebDriver может позволить нам автоматизировать страницы веб-приложений с помощью сценария.

Как всегда, полный код реализации можно найти в проекте GitHub .