Cucumber + Java Annotation (@BeforeAll e @AfterAll)

Paulo Lobo Neto
3 min readFeb 25, 2019

--

Utilizando o recurso de anotações Java para o Cucumber

O cucumber possui muitas facilidades, porém há uma deficiência em relação as suas anotações After e Before. Como assim, Paulo? Do que você está falando?

Bem, pra começar, vou exemplificar como funciona a thread do cucumber.

O cucumber possui uma classe principal (Figura 1), de onde se partirão as execuções dos seus testes:

Figura 1 — Classe principal para execução dos testes

À partir dessa classe, nós iniciamos as execuções dos nossos testes.

No início da execução o cucumber procura todas as features anexadas ao projeto. Após encontrá-las, os métodos responsáveis por implementar os passos das nossas features são executados e ao final é gerado um relatório “.json” com o resultado dos testes. Veja exemplificação abaixo:

Figura 2 — Thread do cucumber sem utilizar @Before e @After

Prosseguindo um pouco mais, digamos que queremos executar um bloco de código antes de cada cenário, utilizamos o “@Before” para isso. E se quisermos executar após cada cenário, utilizamos o “@After”. No caso de querermos executarmos blocos antes ou após de cada step, poderemos utilizar o “@BeforeStep” e “@AfterStep”, respectivamente (veja a documentação: https://docs.cucumber.io/cucumber/api/#hooks).

Então temos aqui uma thread do cucumber:

Figura 3 — Thread do cucumber com o uso das anotações

O que podemos notar disso?

Bem, repare que se eu quiser executar qualquer bloco antes da leitura das features e após a geração dos relatórios, eu não vou conseguir, porque o cucumber não fornece solução para isso.

Mas, Paulo, Porque eu iriar querer executar blocos de código antes e depois do fluxo de execução dos testes?

Há alguns motivos:

  • Manipular o relátorio .json, acrescentando dados personalizados. O .json é o último passo a ser executado. Ele é executado após a finalização de todos os testes. Ele é o último método a ser executado. Após ele, o programa encerra. Isso quer dizer que só é possível analisá-lo após a finalização do programa, ou seja, o código já vai estar finalizado.
  • Gerar um documento .doc ou .pdf ao final da execução;
  • Disparar uma requisição para algum servidor externo ou ferramenta de gerenciamento de testes, dentre outros.

Eu não quero e não posso executar os passos acima após cada cenário ou após cada passo. Eu quero executá-los após a finalização de todo o fluxo, após o .json ser gerado e não houver mais nenhum passo relacionado à execução dos testes.

De acordo com meus motivos, veja abaixo qual é a thread desejada:

Figura 4 — thread desejada

O cucumber não fornece essa possibilidade, e também não foi possível resolver com as anotações do junit. A solução que eu encontrei foi a de reflexão e anotação:

  • Primeiro, criei as duas anotações:
Figura 5 — Anotação BeforeAll
Figura 6 — Anotações AfterAll
  • Em seguida eu criei uma classe que estende a classe “Runner” e sobrescreve o método “run”. Após a sobrescrita, eu consegui definir um fluxo de execução da forma que eu queria. Primeiro eu percorro os métodos anotados com “@BeforeAll” e em seguida notifico o “Cucumber” para que ele possa iniciar a execução. Após a execução, os métodos anotados com o “@AfterAll” são executados. Veja a classe abaixo:
Figura 7 — Classe responsável pelo novo fluxo de execução dos testes

Dessa forma consigo executar minhas personalizações sem perder os benefícios do Cucumber. Após a criação destes arquivos, você precisa alterar o “@RunWith” para o nome da nossa classe que estende a Runner e acrescentar os métodos que você quer utilizar antes e depois da execução do cucumber, anotando-os com as anotações “@BeforeAll” e “@AfterAll”. Veja exemplo abaixo:

Figura 8 — Classe principal com a utilização dos novos recursos

Pronto! Seu código já pode utilizar os novos recursos. :)

Muito obrigado e até a próxima!

--

--