Concrete Logo
Hamburger button

Utilizando async/await com Protractor

  • Blog
  • 16 de Abril de 2018

Após o excelente post do Cássio Alves (Primeiros passos do Protractor), somados ao entendimento dos guias criados por ele mesmo, resolvi avançar um pouco para ver o que conseguiria alcançar usando o Protractor integrado ao CucumberJS, com o padrão Page-Objects e a lib de asserts do Chai.

Entendimento básico em chamadas assíncronas e síncronas

Sem entrar muito nesse assunto, as chamadas assíncronas são aquelas que quando feitas não impedem que outros processos sejam executados. Isso possibilita que o usuário continue a interagir com a aplicação enquanto o processo é executado em paralelo e, quando o mesmo é finalizado, o usuário verifica o resultado.

Já nas chamadas síncronas, o processo enviado é bloqueado até que ocorra uma resposta, ou seja, não é possível enviar novas requisições até que a atual seja finalizada. Enfim, existe um sincronismo nas requisições.

Mudando o nosso mundo com async/await

As funções assíncronas do JS quando são chamadas retornam uma Promises. Logo, quando a função assíncrona retorna um valor, a Promise vai ser resolvida com o valor retornado (ou rejeitada com um valor lançado).

A expressão ‘await’ pausa a execução da função assíncrona e espera pela resolução da Promise passada. Após isso, ela retoma a execução e segue o fluxo.

Então, a função async/await é para simplificar o uso de forma síncrona das Promises e executar alguns procedimentos em um grupo de Promises. Agora, em vez de usarmos o fluxo de controle, podemos sincronizar nossas funções com o async/await.

Quer ver as notas sobre async-await? Clique aqui.

Como utilizar async/await?

Ao perceber que os steps estavam dando um falso positivo – mesmo com o .then(callback) e os asserts.equals, comumente usados, que não foram aceitos por retornar um objeto (ao usar getText) –, coloquei na cabeça o seguinte raciocínio:

“Promises nada mais é do que a certeza do que você diz fazer, vai de fato acontecer.”

Então o que fazer para esperar e validar minha execução corretamente? Muito mais simples do que imaginávamos. Vamos lá…

Hands On

Não falaremos sobre a estrutura do projeto em si e tão pouco sobre o passo a passo, apenas focaremos no await e no resultado final disso. Só precisamos lembrar que vamos utilizar a dependência “chai-as-promised”: “^7.1.1” para os asserts.

Vamos utilizar uma aplicação simples em AngularJS, a famosa Super Calculadora. As funcionalidades vão ser basicamentes duas: somar e subtrair. O repositório com o código para rodar localmente está aqui.

Arquivo de page-objects

Nosso PO é bem simples, nada diferente do que costumamos ver.

Linha 4 – Classe Calculadora
Linha 5 – Constructor com os elementos mapeados
Linha 15 – Método para acessar a página (baseUrl que se encontra no arquivo de conf)
Linha 19 – Método de soma
Linha 27 – Método de subtração
Linha 37 – Módulo para exportar o Page

Utilizando os async/await – Arquivo de steps

Vamos à explicação das linhas:

Linha 3 – Gancho para o caminho e utilização do CucumberJS
Linha 4 – Utilização do chai/chai-as-promised nos asserts
Linha 7/8 – Puxando o nosso Page para acessarmos através dos steps
Linha 10 em diante – Steps com async function() e awaits

Conclusão e explicação dos awaits no step

O framework CucumberJS utiliza chamadas assíncronas para ler e executar as features. O uso do async é para podermos utilizar o await, fazendo com que a execução seja forçada a aguardar que a linha seja executada antes de seguir com o fluxo. Assim, garantimos a ordem da execução além de percebermos uma melhoria no código.

No código abaixo, inclusive, o await está pausado, aguardando para seguir ao próximo step quando realizar a adição e/ou esperar por um tempo colocado como default [caso não ache algo].

Agora o mais legal é o uso do chai-as-promised. Basta colocarmos o async function no step() e o await antes do expect. Conforme vamos ver abaixo, o código fica muito mais limpo e objetivo. Neste, especificamente, estamos esperando um certo elemento chamado result pegar o texto dele e validar se o resultado é igual a 30.

Ao utilizamos o .to.eventually estamos expressando o que realmente queremos dizer. Por isso, não é preciso o uso do .then(), apesar que isso vai muito da preferência de cada um, mas para se ter mais controle das promises ele se faz necessário. Por exemplo, caso precise tratar algo no retorno da promises antes de usar o expect, o modo que funcionaria seria com o uso do .then().

Por fim, vamos rodar o projeto para visualizarmos o resultado no terminal e logo em seguida o report do cucumber-html:

Então é isso, pessoal. Espero que tenham gostado dessa minha primeira e pequena introdução.
Lembrando que o link do repositório está aqui e qualquer dúvida basta comentar no post. 🙂

Referências

  • http://www.protractortest.org/#/
  • https://talkingabouttesting.com/
  • https://blog.taller.net.br/testando-aplicacoes-angularjs-com-protractor/
  • https://github.com/angular/protractor
  • https://tableless.com.br/entendendo-o-async-e-o-await-em-javascript/
  • http://www.protractortest.org/#/control-flow
  • http://www.protractortest.org/#/async-await
  • https://github.com/cucumber/cucumber-js

No capítulo de QA da Concrete nós nos importamos com o que criamos. Somos parte fundamental dos times de desenvolvimento, pois garantimos a qualidade de engenharia do produto final. Nosso papel é desenvolver e automatizar a suíte de testes de comportamento, criando e mantendo testes de aceitação, regressão e integração. Para isso, utilizamos tecnologias como Cucumber, Calabash e Ruby. Nosso DNA tem palavras como Agile Testing, Especificação por Exemplo e Automação de Testes.Trabalhe com os melhores! Acesse: concrete.com.br/vagas