1. Введение
В этом руководстве мы познакомимся с Serenity BDD — отличным инструментом для применения Behavior Driven Development (BDD) . Это решение для автоматизированного приемочного тестирования, которое генерирует хорошо иллюстрированные отчеты о тестировании.
2. Основные концепции
Концепции, лежащие в основе Serenity, следуют концепциям, лежащим в основе BDD. Если вы хотите узнать больше об этом, прочтите нашу статью о Cucumber и JBehave .
2.1. Требования
В Serenity требования разделены на три уровня:
- возможности
- Особенности
- рассказы
Как правило, проект реализует возможности высокого уровня, например, управление заказами и управление членством в проекте электронной коммерции. Каждая возможность состоит из множества функций, и функции подробно объясняются пользовательскими историями.
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
:
Из отчета видно, что у нас есть только один приемочный тест «Члены должны начать с бронзового статуса, имеет возможность», и он проходит. Нажав на тест, шаги проиллюстрированы:
Как мы видим, отчет Serenity дает нам полное представление о том, что делает наше приложение и соответствует ли оно нашим требованиям. Если у нас есть какие-то шаги для реализации, мы можем пометить их как @Pending
:
@Pending
@Step("When the member exchange {}")
public void aMemberExchangeA(Commodity commodity){
//TODO
}
Отчет напомнит нам, что нужно делать дальше. А если какой-то тест не пройден, это видно и в отчете:
Каждый неудачный, проигнорированный или пропущенный шаг будет указан соответственно:
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 {}
После завершения проверки
сборки мы можем увидеть наш тестовый отчет:
По сравнению с обычным текстовым отчетом 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
, будут представлены подробности запроса и ответа:
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:
Serenity также поддерживает двустороннюю интеграцию с JIRA . Подробную информацию можно найти в официальной документации .
7. Резюме
В этой статье мы представили Serenity BDD и несколько интеграций с другими средами тестирования и системами управления требованиями.
Хотя мы рассмотрели большую часть того, что может сделать Serenity, он, безусловно, может больше. В нашей следующей статье мы расскажем о том, как Serenity с поддержкой WebDriver может позволить нам автоматизировать страницы веб-приложений с помощью сценария.
Как всегда, полный код реализации можно найти в проекте GitHub .