Mobile

13 ago, 2015

Boas práticas de Cucumber e Calabash – Parte 01

Publicidade

O objetivo desse artigo é expor algumas técnicas, recursos e boas práticas que são úteis para quem está implementando testes para Calabash, mas boa parte das dicas é destinada também para Cucumber. É importante lembrar que temos no blog alguns posts introdutórios sobre BDD e Calabash, que podem ajudar a entender melhor esse primeiro artigo.

Destaco que nem todas as dicas são obrigatórias de serem utilizadas, porque não existe um padrão a ser seguido. A decisão de usá-las só depende de você e do seu nível de experiência, mas, de qualquer forma, saber que esses conselhos existem será proveitoso também para iniciantes, que poderão saber quais ferramentas utilizar dependendo do problema que encontrarem em seus projetos.

No próximo artigo, vou falar sobre dois padrões de projeto de testes para Calabash, nos quais as dicas de hoje serão úteis. Vamos começar, então?

Use tags

A utilidade do uso de tags está na separação de cenários de diferentes funcionalidades por assuntos que eles tenham em comum. É simples! Basta usar

@<nome_da_tag>

antes de cada cenário.

Por exemplo, você pode querer separar seus cenários:

  • por tempo de execução: @rápido, @médio ou @demorado;
  • por tipo: casos de @sucesso ou de @erro;
  • por momento de execução: @diário, @semanal, @mensal etc;
  • por dependências: @database, @network etc.

Em suma, use-as quando não quiser rodar todos os cenários de uma funcionalidade ou quiser rodar cenários com características específicas. Você pode usar quantas tags quiser para cada cenário. Para isso, basta separá-las por espaço.

Para excluir tags, uma sintaxe bem útil é:

~@<nome_da_tag>

Com isso, você fará com que todos os cenários sejam executados, menos aqueles com as tags indicadas.

Rodando funcionalidades

Aproveitando o ensejo, é bom lembrar que se você quiser testar uma funcionalidade específica, você pode simplesmente chamar diretamente o arquivo .feature dessa funcionalidade. Para Calabash usando Android, por exemplo, você pode invocar assim: 

calabashandroid run<demais _parametros>/config/<nome_da_feature>.apk <caminho_para_arquivo_de_funcionalidade<strong>></strong>

Como já citamos que podemos utilizar tags para separar por caso de sucesso ou erro do nosso sistema, aqui vai a próxima recomendação…

Teste os casos de erro

Embora pareça um pouco óbvio, despenda o máximo de esforço que puder em buscar o máximo de erros possível e documente tudo, juntamente com a equipe desenvolvedora e o seu P.O., para terem certeza que consideraram todos os erros possíveis de serem testados. Não queremos nenhuma surpresa desagradável para o nosso cliente, não é?

Refatore sempre que possível

Durante o andamento do projeto de testes, à medida em que os casos de teste forem aumentando, é essencial que você refatore sempre que possível. Sempre que houver chamadas a métodos de screens ou steps de Cucumber que possuam comportamentos parecidos e sempre que a probabilidade desse método ser chamado com frequência for suficientemente alta, tente extrair essa funcionalidade e encapsulá-la para não depender de contexto, reduzindo o trabalho de reimplementação em futuras evoluções do seu projeto de testes. 

Adote o Page Object Pattern

Essa dica foi extraída do próprio site do Calabash e se refere ao padrão de testes adotado comumente por engenheiros de QA. Basicamente, ele prega que devemos abstrair nosso projeto de testes levando em conta cada page (página), tela ou screen (no caso de aplicativos).

Dessa forma, devemos considerar a criação de classes que representem as telas dos nossos aplicativos e implementar propriedades e métodos que simulem as possíveis ações sobre a tela.

Além disso, eles mostram que devemos nos preocupar em tornar os códigos que implementam essas classes totalmente modularizados e desacoplados dos steps provenientes do Cucumber, e os steps não devem conter nenhum resquício de implementação específico de alguma plataforma, como Android ou iOS.

Vale a pena dar uma lida no site do Calabash. Além de dar uma explicação detalhada, ele ainda oferece um projetinho de exemplo. Eu, particularmente, achei bastante útil – especialmente no que se refere à utilização de funções do Calabash. Para quem está começando nessa área, é uma boa oportunidade de aprendizado. Esse exemplo apresenta coisas que talvez você, se estiver começando agora, ainda não conheça e que podem ser úteis nos seus testes.

Agrupe steps

Essa é uma boa maneira de deixar um determinado step mais sucinto: você pode fazer com que ele contenha substeps. Por exemplo, eu posso fazer com que o meu step:

#...
Quando o usuário fizer login válido
#...

Se torne um container de sub steps. Dessa forma, o step definition dele se tornaria:

Quando(/^o usuário fizer login válido$/) do
 
step 'o usuário digitar o login válido'
 
step 'o usuário digitar  senha válida'
 
step 'o usuário clicar em logar'
 
end

Observe que os substeps devem ser definidos em outro lugar.

Agrupar steps é bastante útil quando os substeps utilizados não são muito relevantes para aqueles que lêem a descrição do cenário a ser testado. De fato, pode haver situações que é preferível ler:

Quando o usuário fizer login válido

Do que ler:

Quando o usuário digitar o login válido
 
E o usuário digitar senha válida
 
E o usuário clicar em logar

Mas usar esse último tipo de agrupamento tem uma desvantagem: quando ocorrerem erros na execução dos testes, o Calabash não conseguirá informar de onde veio o erro, pois não é possível averiguar em qual substep o erro apareceu.

Porém, é possível contornar isso com o uso do many_steps helper, um módulo em Ruby disponível aqui. Ele permite que o Calabash informe qual substep deu erro em tempo de execução. Basta colocar o arquivo many_steps.rb na pasta support do seu projeto.

Modularize seus steps

Buscando em muitos sites, eu concordei com essa ideia:

Deixe seus steps o mais robustos e independentes possível, ou seja, um step não deve depender do resultado de outro e steps não devem compartilhar do mesmo contexto. Consequentemente, os steps precisam ser determinísticos, ou seja, cada step precisa trazer consigo o seu próprio contexto e resultados predefinidos.

Dessa forma, não teremos dor de cabeça para manter um step atualizado só porque outrostep que compartilha do mesmo contexto precisou ser modificado. Também não precisaríamos aumentar a complexidade dos nossos steps definitions para levar em conta os possíveis contextos de execução do step a ser implementado.

Em resumo: nada de levar em conta se o app está de um jeito ou de outro na hora de testar um cenário! O app só deve estar de um único jeito, e é preocupação do desenvolvedor garantir um único resultado. Afinal, teste comportamental é como qualquer outro caso de teste: deve conter “entradas” e “saídas”  bem estabelecidas.

Reset Between Scenarios

Uma dica muito boa que encontrei foi como configurar para que cada cenário limpe os dados do aplicativo de forma que ele fique totalmente sem contexto, como se fosse executado pela primeira vez. Para fazer isso, você pode “setar” a seguinte variável:

RESET_BETWEEN_SCENARIOS=1

Ela pode ser “setada” de duas formas:

1. Por linha de comando. Para Android, por exemplo:

$ RESET_BETWEEN_SCENARIOS=1 calabash androidrun (...)<strong><strong> </strong></strong>

2. Ou colocá-la em no arquivo cucumber.yml:

# config/cucumber.yml

##YAML Template

---

android: RESET_BETWEEN_SCENARIOS=1 PLATFORM=android -r features/support -r features/android -r features/step_definitions --exclude features/ios
ios: PLATFORM=ios -r RESET_BETWEEN_SCENARIOS=1 features/support -r features/ios -r features/step_definitions --exclude features/android

A vantagem desta última é funciona para todos os cenários da sua bateria de testes.

Algumas considerações:

  • Utilize esse recurso “com moderação”: reinstalar cada cenário consumirá mais tempo do que o usual.
  • Muito provavelmente esse recurso não estará funcionando para iOS, conforme a própria Xamarin alega, o que pode requerer que você configure manualmente via código (veja a primeira resposta desta discussão).

Tag @reinstall

Dentro da gem CS-BDD foi criada a tag @reinstall. Você pode utilizá-la caso queira reinstalar alguns cenários específicos. Normalmente o aplicativo já é reinstalado entre um arquivo.feature e outro, mas pode ser que você ache necessário reinstalar o aplicativo para alguns cenários dentro de uma mesma feature, e nesse caso a tag pode te ajudar.

Conclusão

Muitas das dicas deste artigo estão aqui porque são um consenso entre várias fontes. Outras são conselhos isolados, mas que igualmente úteis e merecem exposição. A ideia foi fazer um resumo com muitas dessas dicas, que facilitam a vida de quem trabalha com QA e procura automatizar os testes para mobile.

Na próximo artigo vou mostrar dicas mais subjetivas, usando duas abordagens na hora de projetar os testes com Calabash. Esses dois padrões são os mais discutidos na web e faremos uma análise sobre ao custo x benefício de usar um ou outro.

É isso, pessoal! Espero que tenham gostado. Quaisquer observações e comentários concordando, ou não, com as dicas são muito bem-vindos.

Até a próxima!