Introducción a Serenity BDD

1. Introducción

En este tutorial, daremos una introducción a Serenity BDD, una gran herramienta para aplicar el desarrollo impulsado por el comportamiento (BDD). Esta es una solución para pruebas de aceptación automatizadas que genera informes de prueba bien ilustrados.

2. Conceptos básicos

Los conceptos detrás de Serenity siguen los conceptos detrás de BDD. Si quieres leer más al respecto, consulta nuestro artículo sobre Cucumber y JBehave.

2.1. Requisitos

En Serenity, los requisitos se organizan en tres niveles:

  1. capacidades
  2. caracteristicas
  3. cuentos

Por lo general, un proyecto implementa capacidades de alto nivel, gestión de pedidos ex y capacidades de gestión de membresía en un proyecto de comercio electrónico. Cada capacidad se compone de muchas características, y las características se explican en detalle por historias de usuarios.

2.2. Pasos y pruebas

Los pasos contienen un grupo de operaciones de manipulación de recursos. Puede ser una acción, verificación o una operación relacionada con el contexto. El formato clásico Given_When_Then se puede reflejar en los pasos.

Y las pruebas van de la mano con Steps. Cada prueba cuenta una historia de usuario simple, que se lleva a cabo mediante un determinado paso .

2.3. Informes

Serenity no solo informa los resultados de las pruebas, sino que también los utiliza para producir documentación dinámica que describe los requisitos y los comportamientos de la aplicación.

3. Prueba con SerenityBDD

Para ejecutar nuestras pruebas de Serenity con JUnit, necesitamos @RunWith el SerenityRunner , corredor de pruebas. SerenityRunner instrumenta las bibliotecas de pasos y garantiza que los reporteros de Serenity registren y notifiquen los resultados de las pruebas.

3.1. Dependencias de Maven

Para hacer uso de Serenity con JUnit, deberíamos incluir serenity-core y serenity-junit en el pom.xml:

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

También necesitamos serenity-maven-plugin para tener informes agregados de los resultados de las pruebas:

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

Si queremos que Serenity genere informes incluso si hay una falla en la prueba, agregue lo siguiente al pom.xml:

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

3.2. Un ejemplo de puntos de membresía

Inicialmente, nuestras pruebas se basan en la característica típica de puntos de membresía en una aplicación de comercio electrónico. Un cliente puede unirse al programa para miembros. A medida que el cliente compra productos en la plataforma, los puntos de membresía aumentarán y el grado de membresía del cliente crecerá en consecuencia.

Ahora escribamos varias pruebas contra los escenarios descritos anteriormente y veamos cómo funciona Serenity.

Primero, escribamos la prueba para la inicialización de la membresía y veamos qué pasos necesitamos:

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

Luego implementamos los dos pasos de la siguiente manera:

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

Ahora estamos listos para ejecutar una prueba de integración con mvn clean verify . Los informes se ubicarán en target / site / serenity / index.html :

En el informe, podemos ver que solo tenemos una prueba de aceptación 'Los miembros deben comenzar con el estado de bronce, tienen la capacidad de hacerlo' y está pasando. Al hacer clic en la prueba, se ilustran los pasos:

Como podemos ver, el informe de Serenity nos brinda una comprensión profunda de lo que está haciendo nuestra aplicación y si se alinea con nuestros requisitos. Si tenemos algunos pasos para implementar, podemos marcarlos como @Pending :

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

El informe nos recordaría lo que se debe hacer a continuación. Y en caso de que alguna prueba falle, también se puede ver en el informe:

Cada paso fallido, ignorado u omitido se enumerará respectivamente:

4. Integración con JBehave

Serenity también puede integrarse con marcos BDD existentes como JBehave.

4.1. Dependencias 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

Además, la cuenta JIRA y los enlaces deben especificarse en el archivo serenity.properties en la raíz del proyecto:

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

Luego habría un enlace de JIRA adjunto en el informe:

Serenity también admite la integración bidireccional con JIRA, podemos consultar la documentación oficial para obtener más detalles.

7. Resumen

En este artículo, presentamos Serenity BDD y múltiples integraciones con otros marcos de prueba y sistemas de gestión de requisitos.

Aunque hemos cubierto la mayor parte de lo que Serenity puede hacer, ciertamente puede hacer más. En nuestro próximo artículo, cubriremos cómo Serenity con el soporte de WebDriver puede permitirnos automatizar las páginas de aplicaciones web utilizando guiones.

Como siempre, el código de implementación completo se puede encontrar en el proyecto GitHub.