Testes automatizados de UI com Cypress e Shippable
Antes de dar minha receita, me deixe compartilhar algumas informações. Se você estiver com pressa, pode ir direto até as Instruções de Instalação.
Quase sempre fazer testes de UI automatizados recaem no uso do Selenium, e várias outros pacotes node
. Basicamente o setup que eu usava até 2 anos atrás para testar uma aplicação react
consistia das seguintes dependências:
mocha
(biblioteca de testes)chai
(para as assertions)chai-as-promised
(assertions com menos código)selenium-webdriver
(para automação do navegador)phantomjs-prebuilt
(navegador headless, para executar os testes na linha de comando)chromedriver
(para executar os testes no Chrome, bom para depurar)coffee-script
(para sintaxe mais limpa)
Sem mencionar que o phantomjs
foi descontinuado em favor do Chrome Headless.
De qualquer forma, essa saladinha era um tanto quanto instável: como o Selenium é um framework externo que usa uma arquitetura cliente/servidor, e o phantomjs
não era um navegador real, muitas vezes nossos testes que funcionavam davam falso negativo, para tempos depois voltarem a funcionar novamente.
Eis que então surge o cypress
e suas incríveis dependências:
cypress
É isso mesmo: ele é um pacote node
auto contido, usando o Electron
para executar nossos testes, de modo headless ou usando uma interface amigável:
Instruções de Instalação
Execute na pasta do seu projeto:
npm install cypress --save-dev
Depois disso, vamos mudar algumas configurações padrão:
- vamos adicionar comandos amigáveis para iniciar o
cypress
- vamos tirar a pasta do
cypress
da raiz do nosso projeto - não queremos salvar vídeos quando os testes passam
- não queremos salvar evidências
cypress
nogit
Comandos amigáveis para iniciar o cypress
Abra o package.json
do seu projeto e adicione isso a seção scripts
:
"scripts": {
"cypress:open": "cypress open",
"cypress": "cypress run"
},
Agora podemos usar npm run cypress
para executar os testes no terminal ou npm run cypress:open
para abrir a interface de execução.
Mudando algumas configurações padrão
Por padrão, o cypress
se instala na pasta raiz do projeto, numa sub pasta chamada cypress
. Eu preferi mover para react/spec/system
.
Além disso, eu mudei a configuração para não salvar vídeos de evidência quando os testes passam. Também quis já colocar um valor padrão para baseUrl
(veja mais opções de configuração na documentação).
Pra que todas essas alterações funcionem, precisamos criar um arquivo cypress.json
na pasta do projeto com o seguinte conteúdo:
{
"baseUrl": "http://localhost",
"fixturesFolder": "react/spec/system/fixtures",
"integrationFolder": "react/spec/system/integration",
"pluginsFile": "react/spec/system/plugins/index.js",
"screenshotsFolder": "react/spec/system/screenshots",
"supportFile": "react/spec/system/support/index.js",
"videosFolder": "react/spec/system/videos",
"video": false
}
Não save evidências on git
Eu deixei a opção padrão do cypress
de salvar screenshots quando os testes executados pelo terminal falham.
Mas não quero que estas evidências sejam salvas no repositório git
do projeto. Então vamos editar o .gitignore
e acrescentar essas linhas:
# Cypress test results assets
react/spec/system/screenshots/*
react/spec/system/videos/*
Escrevendo um teste simples
Se você quiser aprender mais sobre os testes do cypress
, veja a documentação sobre Escrever Seu Primeiro Teste page.
Então crie um arquivo chamado react/spec/system/integration/sample_spec.js
com o seguinte conteúdo:
describe('My First Test', function() {
it('Visits Home', function() {
cy.visit('/')
})
})
Veja que nosso teste irá abrir a página /
, o que significa usar o endereço de baseUrl
que definimos no arquivo cypress.json
.
Como você imaginar, o comando visit
abre uma URL. Veja a documentação da API com todos os comandos disponíveis. Você pode também criar comandos personalizados salvando eles dentro do arquivo react/spec/system/support/commands.js
.
Agora teste nosso exemplo simples executando npm run cypress:open
e veja a mágica acontecer!
Integração Contínua com Shippable
Agora vamos configurar nossa Integração Contínua (ou CI, nas siglas em inglês). Costumo usar o Shippable pra isso, mas qualquer outra ferramenta de CI usará uma configuração similar.
Por que o Shippable? O SaaS deles é fácil de configurar (basicamente é um arquivo shippable.yml
no projeto), tem plano gratuito ou com preços razoáveis, integração com GitHub e BitBucket e funciona muito bem!
De qualquer forma, conforme eu falei acima, é bem provável que qualquer outra ferramenta de CI tenha uma configuração muito parecida. Dê uma olhada na documentação do cypress
sobre Integração Contínua com receitas para o Jenkins, TrevisCI, CircleCI e vários outros.
O objetivo deste post não é ensinar como configurar o Shippable do zero, mas de uma maneira rápida, se for sua primeira vez usando a ferramenta, você precisa:
Agora, assumindo que você já tenha o Shippable funcionando em um ambiente node_js
, vamos alterar a seção ci
do seu shippable.yml
para adicionar os testes do cypress
:
ci:
# Redirect the output to `/dev/null` due long outputs freezing the build
- npm install --quiet >> /dev/null
# Starting app server
- rails server -d
# cypress specs
- npm run cypress
Conforme você pode notar, estou usando o Shippable com o Ubuntu como sistema operacional em uma aplicação rails
. Se você estiver usando outro sistema operacional, basta substituir a linha do apt-get
pelo gerenciador de pacotes do seu sistema. Também substitua a linha que inicia o servidor web (rails server -d
) pelo servidor da sua aplicação.