FLUTTER_GHERKIN criando automações de teste de uma forma mais simples
Tags: integrationtest, gherkin, fluttertest
Published: 2024-04-20 04:26:42

O tema “testes automatizados” vem ganhando grande notoriedade pois desta maneira as empresas conseguem entregar mais qualidade em seus projetos a um custo não muito alto.

No Flutter temos diversos tipos de facilidades de criarmos testes (já falamos de alguns tipos aqui) e cada vez mais vão surgindo ferramentas que vem facilitando a escrita de testes, mas convenhamos que por mais simples que seja escrever um teste de widget ou de integração ainda precisamos ter um conhecimento técnico dentro do Flutter e dentro do DART.

Entretanto a comunidade Flutter viu este problema e criou um pacote que irá ajudar muito uma pessoa sem conhecimento nenhum no Flutter a criar cenários de testes utilizando o GHERKIN, estou falando do flutter_gherkin([https://pub.dev/packages/flutter_gherkin/](https://pub.dev/packages/flutter_gherkin/versions/3.0.0-rc.17#restartappbetweenscenarios)).

### Mas afinal o que é GHERKIN?

O GHERKIN é um técnica de padronização de escrita de especificações de cenários de testes baseada em seu negocio.

O objetivo de sua utilização e deixar os testes automatizados de fácil leitura e compreensão para qualquer pessoa, inclusive pessoas totalmente leigas no assunto. O GHERKIN deve seguir alguns padrões seguindo a regra de negocio da aplicação e deve ser escrito em forma de “passos”(“steps”) para especificar cada etapa e interação que o usuário irá ter com o sistema.

Imagine o cenário que iremos testar uma calculadora e iremos testar de 3+ 38 esta apresentando o resultado 41.

    Pré condição: Abrir a calculador  
    Pressionar o botão de 3  
    Pressionar o botão de +  
    Pressionar o botão de 3  
    Pressionar o botão de 8  
    Pressionar o botão de =  
    Deve mostrar o resultado 41

### Esperar o que apareça o resultado 41

Dado este cenário agora só precisamos converter para o padrão do GHERKIN, ele possui algumas palavras-chave que talvez você já tenha ouvido, os famosos (**GIVEN-WHEN-THEN**).

> **Given** (pt: Dado): Utilizado para especificar uma pré condição que deverá ser executado antes do cenário de teste. Por se tratar de uma pré condição, normalmente vem escrito no passado;
> **When** (pt: Quando): Utiliza-se o When quando alguma ação é executada no cenário de teste e isso irá gerar uma reação que será testada no Then.
> **Then** (pt: Então): É a etapa de validação do cenário, basicamente iremos validar as reações geradas pelas ações do When
> **And** (pt: E): Caso seja necessário mais uma interação com o sistema para complementar um fluxo.
> **But** (pt: Mas): No geral serve a mesma funcionalidade do “And”, porém é normalmente utilizado após uma validação negativa depois do “Then”

Sendo assim nosso cenário reescrito ficaria

>**Dado** que o usuário abriu a calculadora  
>**Quando** o usuário pressionar o botão 3  
>**E** o usuário pressionar o botão +  
>**E** o usuário pressionar o botão 3  
>**E** o usuário pressionar o botão 8  
>**E** o usuário pressionar o botão =  
>**Então** o resultado deverá aparecer 41

Muito legal esse conceito se quiser saber mais sobre GHERKIN recomendo a leitura [https://blog.onedaytesting.com.br/gherkin/](https://blog.onedaytesting.com.br/gherkin/)

Só aplicando essa técnica e escrevendo cenários desta forma para o critério de aceite de uma feature já ajudaria bastante a vida e ajudaria ainda mais saber que poderemos pegar essa escrita de cenário e automatizar utilizando o flutter_gherkin.

### flutter_gherkin(https://pub.dev/packages/flutter_gherkin/)

Hoje (05/06/2022) o flutter_gherkin está na versão estável 2.0.0, **NÃO RECOMENDO** usar esta versão, ao invés disso utilize a versão em pré release mais atual pois ela já roda em cima da nova API de integration_test do Flutter

![](https://cdn-images-1.medium.com/max/800/1*QjVcUcI_EzbnwFxYy_pIIQ.png)

Além do **flutter_gherkin** precisaremos ter mais 2 dependências em nosso projeto, o **integration_test** que poderá ser pego diretamente do sdk do flutter e o **build_runner**. Podem deixa-los como dev_dependencies
{% gist https://gist.github.com/toshiossada/88bc86bd3e4c71079ae7b6daa6c3e5e8 file=pubspec.yaml %}
A primeira coisa que precisamos fazer no diretório **test_driver** arquivo que será nosso ponto de entrada dos testes **integration_test_driver.dart**

![](https://cdn-images-1.medium.com/max/800/1*zBEbV1CnuXdHM5Dg03aFjQ.png)
{% gist https://gist.github.com/toshiossada/2b2d18bf0ae961fe9a667b556f765726 file=integration_test_driver.dart %}
Também será necessário criar o arquivo **build.yaml** na raiz do projeto para configuração do build_runner para gerar os testes
{% gist https://gist.github.com/toshiossada/65bb9e5725e31c77739f80299a973e50 file=build.yaml %}
Crie o diretório **integration_test** na raiz do projeto que agora iremos começar a trabalhar em cima dele.

Agora podemos começar a escrever nossos cenários de testes, eu geralmente se, criaremos por exemplo o teste da calculadora, devera conter a extensão **.feature**

![](https://cdn-images-1.medium.com/max/800/1*y6PreyxsjIwnAjIBTgHPQA.png)
{% gist https://gist.github.com/toshiossada/ed422facddfb123c7a89c5acd33fe100 file=2_calculator.feature %}
Agora precisamos criar o arquivo de configuração dos testes de integração para isto crie o arquivo **gherkin_suite_test.dart** dentro do diretório **integration_test**.

![](https://cdn-images-1.medium.com/max/800/1*1mYNYhmAq_yks6iCXiXwvg.png)
{% gist https://gist.github.com/toshiossada/c8899a582b9a70db67bf14cddf71d9f1 file=gherkin_suite_test.dart %}
note que ele tem um atributo _@GherkinTestSuite_() isso indica que essa classe terá um código que será gerado através do build_runner, então não se preocupe com os erros.

Para gerar o arquivo **.g.dart** pelo **build_runner** execute

```
flutter pub run build_runner build
```

Se não é a primeira vez que esta rodando o build_runner aconselho a dar um clean

```
flutter pub run build_runner clean
```

```
flutter pub run build_runner build
```

Agora precisamos programar os passos, temos os seguintes passos

    Abrir calculadora -> I open calculator  
    Pressionar um numero -> I press number 3  
    Pressionar operaçao -> I press operation '+'  
    Pressionar igual -> I press operation '='  
    Verificar resultado -> I expect result '41'

Na pasta steps criamos nossos arquivos de steps

![](https://cdn-images-1.medium.com/max/800/1*0bW3Q_OOvtxIDlKExBj0xA.png)

### Given

![](https://cdn-images-1.medium.com/max/800/1*uZ6DyotRX4FVb7GU_OYWhw.png)

Primeiro vamos fazer o **given** criamos uma função que retorna um **StepDefinitionGeneric** e utilizando a função **given()** passo a expressão do passo e no corpo dela o que será feito, como se fosse um teste de widget. Podemos usar os finders e as actions (enterText, Tap, etc).
{% gist https://gist.github.com/toshiossada/21b2ade0490ec3f1ecfb17d866945e76 file=given_I_open_calculator.dart %}
Se precisarmos passar algum parâmetro utilizamos as variações do given… given1, given2, e…
{% gist https://gist.github.com/toshiossada/5b7350ca0375de02d3e7c2e3dcc264d1 file=given_I_type.dart %}

**WHEN**

![](https://cdn-images-1.medium.com/max/800/1*sGrdjXLacjWanG_iLIy6JA.png)

Para construir os steps de When é bem simular, utilizo a função when de acordo com a quantidade de parâmetros que tenho no passo.
{% gist https://gist.github.com/toshiossada/c91a2a3fc77eb74fd46daa2c746b3752 file=when_I_press.dart %}
Consigo recuperar o widget por diversos paramentos, como string, tipo, chave.

![](https://cdn-images-1.medium.com/max/800/1*wQE48KBLGefJkvCGd6yjJg.png)

Também consigo recuperar os descendentes ou acedentes

![](https://cdn-images-1.medium.com/max/800/1*r7LylhpewfFtn7EfSDfBAQ.png)

E diversas outras ações assim como nos testes de widgets, consulte a documentação.

### Then

_No then é a mesma coisa, utilizo a função then() conforme a quantidade de parâmetros e tenho disponível todos os métodos de um teste de integração, neste passo geralmente é onde irei testar os expect()_
{% gist https://gist.github.com/toshiossada/08c4a8e814832ac125767328d9f873ff file=then_I_expect_result.dart %}
Agora lá no arquivo de configuração do GHERKIN preciso adicionar essas definições de passos (gherkin_suite_test.dart)

![](https://cdn-images-1.medium.com/max/800/1*sCbxOKXMXsiZ7jERmttUqA.png)

Execute novamente o build_runner

```
flutter pub run build_runner clean
flutter pub run build_runner build
```

E agora para ver os testes executar bastar executar

    flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/gherkin_suite_test.dart

E o resultado será

![](https://cdn-images-1.medium.com/max/800/1*5RicK0FSMdUkYMgrmhumag.gif)

Para conseguir debuggar no Visual Studio CODE colocando breaking points e tudo mais basta adicionar o launch.json
{% gist https://gist.github.com/toshiossada/d79caa3775afc17096bec3a4273cfceb file=launch.json %}
![](https://cdn-images-1.medium.com/max/800/1*UudvHIg4IPgNyuSD5zinEQ.png)

![](https://cdn-images-1.medium.com/max/800/1*YyGx4y_hCm9pHWtFpUEA-A.png)

Desta forma com todos os passos programados qualquer um pode chegar e montar vários cenários de testes

![](https://cdn-images-1.medium.com/max/800/1*a4Nknte3EiDwQtvs7ZHOiw.png)

Também consigo criar ganchos(hooks) para ter funções que sejam executadas antes/depois de cada cenário e antes/depois de cada passo, basta criar uma classe estendendo de Hook e sobrescrever os métodos.
{% gist https://gist.github.com/toshiossada/bf47866f0a2c448e2aa65fdbe36d616b file=reset_app_hook.dart %}
Dai no arquivo de suit só adicionar a propriedade hooks.

![](https://cdn-images-1.medium.com/max/800/1*67OdYgU7uxNOan7HXI3Puw.png)

Traduções

Se o inglês é um problema não se preocupe, o **flutter_gherkin** tem traduções para a maioria das linguagens e o português é uma delas, você pode conferir em [https://github.com/cucumber/common/blob/main/gherkin/gherkin-languages.json](https://github.com/cucumber/common/blob/main/gherkin/gherkin-languages.json)

Basta trocar as palavras chaves do **GHERKIN** para este dicionário
{% gist https://gist.github.com/toshiossada/fec01a84fb062f18e8c2a5d33413452c file=gherkin-languages.json %}
No seu arquivo de freature basta adicionar no começo de cada funcionalidade **# language: codigo do pais**, no caso do português utilize **pt**.

	# language: pt

Nossa funcionalidade ficará da seguinte forma
{% gist https://gist.github.com/toshiossada/9695a205232bf845ba34f35c35286bd6 file=1_home.feature %}
Agora basta configurar as **Steps** e rodar o teste e voilá tem seu **gherkin** em português.
{% gist https://gist.github.com/toshiossada/4e0e99d1399c092ce434c9551a35fe0e file=steps.dart %}
Legal ne? É impressionante como vem surgindo ferramentas para que facilitam cada dia mais nossa vida, principalmente se tratando de testes.

Segue o projeto de exemplo

https://github.com/toshiossada/flutterIntegrationTest

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obcg0d2y00yddve9quky.png)


Entre em nosso discord para interagir com a comunidade: https://discord.com/invite/flutterbrasil
https://linktr.ee/flutterbrasil