Introduction à Serenity BDD

1. Introduction

Dans ce didacticiel, nous présenterons Serenity BDD, un excellent outil pour appliquer le Behavior Driven Development (BDD). Il s'agit d'une solution pour les tests d'acceptation automatisés qui génère des rapports de test bien illustrés.

2. Concepts de base

Les concepts derrière Serenity suivent les concepts derrière BDD. Si vous voulez en savoir plus à ce sujet, consultez notre article sur Cucumber et JBehave.

2.1. Exigences

Dans Serenity, les exigences sont organisées en trois niveaux:

  1. capacités
  2. fonctionnalités
  3. histoires

En règle générale, un projet met en œuvre des capacités de haut niveau, des capacités de gestion des commandes et de gestion des membres dans un projet de commerce électronique. Chaque fonctionnalité comprend de nombreuses fonctionnalités et les fonctionnalités sont expliquées en détail par des user stories.

2.2. Étapes et tests

Les étapes contiennent un groupe d'opérations de manipulation de ressources. Il peut s'agir d'une action, d'une vérification ou d'une opération liée au contexte. Le format classique Given_When_Then peut être reflété dans les étapes.

Et les tests vont de pair avec Steps. Chaque test raconte une histoire utilisateur simple, qui est effectuée à l'aide de certaines étapes .

2.3. Rapports

Serenity rapporte non seulement les résultats des tests, mais les utilise également pour produire une documentation vivante décrivant les exigences et les comportements de l'application.

3. Test avec SerenityBDD

Pour exécuter nos tests Serenity avec JUnit, nous devons @RunWith le SerenityRunner , test runner. SerenityRunner instrumente les bibliothèques d'étapes et garantit que les résultats des tests seront enregistrés et rapportés par les rapporteurs de Serenity.

3.1. Dépendances de Maven

Pour utiliser Serenity avec JUnit, nous devons inclure serenity-core et serenity-junit dans le pom.xml:

 net.serenity-bdd serenity-core 1.2.5-rc.11   net.serenity-bdd serenity-junit 1.2.5-rc.11 

Nous avons également besoin de serenity-maven-plugin pour avoir des rapports agrégés à partir des résultats des tests:

 net.serenity-bdd.maven.plugins serenity-maven-plugin 1.2.5-rc.6   serenity-reports post-integration-test  aggregate    

Si nous voulons que Serenity génère des rapports même en cas d'échec du test, ajoutez ce qui suit au pom.xml:

 org.apache.maven.plugins maven-surefire-plugin 2.20  true  

3.2. Un exemple de points d'adhésion

Au départ, nos tests sont basés sur la fonctionnalité typique des points d'adhésion dans une application de commerce électronique. Un client peut rejoindre le programme des membres. Au fur et à mesure que le client achète des marchandises sur la plate-forme, les points d'adhésion augmenteront et le niveau d'adhésion du client augmentera en conséquence.

Écrivons maintenant plusieurs tests par rapport aux scénarios décrits ci-dessus et voyons comment fonctionne Serenity.

Tout d'abord, écrivons le test d'initialisation de l'appartenance et voyons les étapes nécessaires:

@RunWith(SerenityRunner.class) public class MemberStatusIntegrationTest { @Steps private MemberStatusSteps memberSteps; @Test public void membersShouldStartWithBronzeStatus() { memberSteps.aClientJoinsTheMemberProgram(); memberSteps.theMemberShouldHaveAStatusOf(Bronze); } }

Ensuite, nous implémentons les deux étapes comme suit:

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)); } }

Nous sommes maintenant prêts à exécuter un test d'intégration avec mvn clean verify . Les rapports seront situés dans target / site / serenity / index.html :

D'après le rapport, nous pouvons voir que nous n'avons qu'un seul test d'acceptation «Les membres devraient commencer avec le statut de bronze, ont la capacité de» et réussissent. En cliquant sur le test, les étapes sont illustrées:

Comme nous pouvons le voir, le rapport de Serenity nous donne une compréhension approfondie de ce que fait notre application et si elle correspond à nos exigences. Si nous avons des étapes à mettre en œuvre, nous pouvons les marquer comme @Pending :

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

Le rapport nous rappellerait ce qui doit être fait ensuite. Et en cas d'échec d'un test, cela peut également être vu dans le rapport:

Chaque étape échouée, ignorée ou ignorée sera répertoriée respectivement:

4. Intégration avec JBehave

Serenity peut également s'intégrer aux frameworks BDD existants tels que JBehave.

4.1. Dépendances de Maven

To integrate with JBehave, one more dependency serenity-jbehave is needed in the POM:

 net.serenity-bdd serenity-jbehave 1.24.0 

4.2. JBehave Github REST API Test Continued

As we have introduced how to do REST API testing with JBehave, we can continue with our JBehave REST API test and see how it fits in Serenity.

Our story was:

Scenario: Github user's profile should have a login payload same as username Given github user profile api When I look for eugenp via the api Then github's response contains a 'login' payload same as eugenp

The Given_When_Then steps can be migrated to as @Steps without any changes:

public class GithubRestUserAPISteps { private String api; private GitHubUser resource; @Step("Given the github REST API for user profile") public void withUserProfileAPIEndpoint() { api = "//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())); } }

To make JBehave's story-to-code mapping work as expected, we need to implement JBehave's step definition using @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); } }

With SerenityStories, we can run JBehave tests both from within our IDE and in the build process:

import net.serenitybdd.jbehave.SerenityStory; public class GithubUserProfilePayload extends SerenityStory {}

After the verify build finished, we can see our test report:

Compared to plain text report of JBehave, the rich report by Serenity gives us a more eye-pleasing and live overview of our story and the test result.

5. Integration With REST-assured

It is noteworthy that Serenity supports integration with REST-assured. To have a review of REST-assured, take a look at the guide to REST-assured.

5.1. Maven Dependencies

To make use of REST-assured with Serenity, the serenity-rest-assured dependency should be included:

 net.serenity-bdd serenity-rest-assured 1.2.5-rc.11 

5.2. Use REST-assured in Github REST API Test

Now we can replace our web client with REST-assured utilities:

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 = "//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)); } }

After replacing the implementation of userAPISteps in the StepDefition, we can re-run the verify build:

public class GithubUserProfilePayloadStepDefinitions { @Steps GithubRestAssuredUserAPISteps userAPISteps; //... }

In the report, we can see the actual API invoked during the test, and by clicking on the REST Query button, the details of request and response will be presented:

6. Integration With JIRA

As of now, we already have a great test report describing details and status of our requirements with Serenity framework. But for an agile team, issue tracking systems such as JIRA are often used to keep track of requirements. It would be better if we could use them seamlessly.

Luckily, Serenity already supports integration with JIRA.

6.1. Maven Dependencies

To integrate with JIRA, we need another dependency: serenity-jira-requirements-provider.

 net.serenity-bdd serenity-jira-requirements-provider 1.1.3-rc.5 

6.2. One-way Integration

To add JIRA links in the story, we can add the JIRA issue using story's meta tag:

Meta: @issue #BDDTEST-1

De plus, le compte JIRA et les liens doivent être spécifiés dans le fichier serenity.properties à la racine du projet:

jira.url= jira.project= jira.username= jira.password=

Ensuite, il y aurait un lien JIRA ajouté dans le rapport:

Serenity prend également en charge l'intégration bidirectionnelle avec JIRA, nous pouvons nous référer à la documentation officielle pour plus de détails.

7. Résumé

Dans cet article, nous avons présenté Serenity BDD et de multiples intégrations avec d'autres frameworks de test et systèmes de gestion des exigences.

Bien que nous ayons couvert la plupart de ce que Serenity peut faire, il peut certainement en faire plus. Dans notre prochain article, nous expliquerons comment Serenity avec le support WebDriver peut nous permettre d'automatiser les pages d'applications Web à l'aide du scénario.

Comme toujours, le code d'implémentation complet est disponible sur le projet GitHub.