Automação de Testes em Ruby com RSpec e Selenium

O mundo da automação!

Igor Octaviano
Training Center
11 min readJun 11, 2018

--

Um desenvolvedor começando a entrar no mundo dos testes automatizados! esse sou eu. Espero que esse post dê uma ideia, mesmo que simples, de como realizar automação de testes em uma página web utilizando a linguagem de programação Ruby. Existem diversos tópicos e ferramentas que estão em torno dessa ideia que não vou cobrir neste post, mas não se preocupe, lá no final eu faço algumas recomendações!

Vamos testar uma página web estática simplíssima com um único evento e estilo simples. A ideia é focar em como podemos realizar automação de testes em uma página qualquer por meio de uma URL utilizando RSpec e Selenium, e de quebra, aprender como subir essa página web no Heroku (pense nisso como um bônus).

Mas por que automatizar testes?

Todo grupo de desenvolvimento de software testa seus produtos, ou pelo menos deveriam testar, e ainda assim, como diz um dos princípios de teste, aplicações podem possuir defeitos e o teste não garante a isenção deles. Engenheiros de Teste ou QAs buscam pegar eles antes mesmo que o produto seja lançado mas mesmo assim esses defeitos acabam aparecendo novamente com a entrada de novas features, até mesmo com o melhor dos processos de teste.

A automação de testes é uma forma melhor e mais eficiente de teste quando você está visando uma maior cobertura de testes. A automação visa garantir a saúde da aplicação de uma maneira automática e principalmente rápida para não afetar o fluxo de desenvolvimento, como poderia ocorrer, se todos os testes tivessem sido feitos de maneira puramente manual.

Ok! vamos começar!

  • Primeiramente é preciso ter o suporte da linguagem de programação Ruby instalado em sua máquina.

A primeira coisa que precisamos fazer é criar a estrutura do projeto (você pode substituir o nome da pasta site por qualquer nome que desejar), para isso execute os 3 comandos abaixo:

  • Caso o comando bundle acima não funcionar, instale o Bundler.

Na última linha executamos o comando cd para entrar na pasta do site juntamente com o comando bundle init para gerar um arquivo para o gerenciamento das dependências do projeto. Isso seria o que é o package.json para os desenvolvedores JavaScript e tipo um pom.xml file para os desenvolvedores Java, só que para os desenvolvedores Ruby.

Apresentando o Bundler

O comando bundle vem da ferramenta Bundler que fornece um ambiente consistente para projetos Ruby rastreando e instalando as gems (dependências) e versões exatas que são necessárias para o seu projeto.

Isso seria o que o NPM é para apps JavaScript porém para Ruby.

O Bundler é uma saída de escape da confusão entre dependências e garante que as gemas necessárias estejam presentes no desenvolvimento, na preparação e na produção.

Isso tudo vai resultar na seguinte estrutura:

  • Gemfile: Explicação adiante.
  • config.ru: É um arquivo de configuração da ferramenta Rack que vai ser executado automaticamente pelo Rack se caso o mesmo existir no diretório onde o comando do Rack for executado. O Rack disponibiliza uma interface entre os webservers que suportam Ruby e seus frameworks. *config.ru (.ru é uma abreviação de "rackup").

Adicione o código abaixo ao arquivo index.html:

index.html

Uma página HTML bem simples com um formulário de login.

Adicione o conteúdo abaixo ao arquivo index.js:

index.js

Nesse momento, após o carregamento da página o evento onload vai executar a função. A função basicamente pega o elemento login e adiciona alguma lógica ao evento de submissão de formulário.

Adicione o conteúdo abaixo ao arquivo index.css:

index.css

Como pode ver, os estilos não são tão importantes nesse momento. Tudo muito simples.

Para seguirmos adiante, preciso que você já esteja nivelado nos seguintes pré requisitos:

Como podemos ver, temos um arquivo novo chamado Gemfile que foi gerado quando executamos o comando bundle init anteriormente.

O arquivo Gemfile é onde vamos colocar as nossas dependências Ruby. A primeira dependência que vamos precisar é o framework Rack (lembra do arquivo de configuração config.ru que foi gerado?). Podemos apagar o conteúdo gerado e adicionar a dependência do Rack:

Sites Estáticos em Ruby

Os sites estáticos são sites que não possuem nenhuma funcionalidade dinâmica do lado do servidor ou lógica do aplicativo. Os exemplos incluem sites de brochura compostos completamente de HTML e CSS ou mesmo jogos interativos do lado do cliente criados no Flash que não interagem com um componente de servidor. Embora esses sites apenas exijam um servidor web para entregar seu conteúdo aos usuários, ainda é útil usar uma plataforma como o Heroku para fornecer e implantar rapidamente essa infra-estrutura.
Usando o framework Rack, sites estáticos podem ser implantados rapidamente para o Heroku.

Heroku Dev Center

Esse trecho é do site do Heroku, essa é a ideia de usar o Rack para podermos subir nossa aplicação para o Heroku, daí podemos rodar nossos testes futuramente. *Como que o Rack faz isso nos detalhes está fora do escopo desse post justamente para não ficar muito denso, recomendo você ler um pouco mais sobre ele aqui.

Depois que colocamos o Rack como gem/dependência no nosso arquivo Gemfile, vamos rodar o comando abaixo:

Se tiver problemas com autorização, utilize sudo antes do comando.

Configuração do servidor de arquivos

Pois bem, aqui estamos, agora precisamos dizer para o Rack quais arquivos ele deve servir como ativos estáticos (assets). Para fazermos isso, vamos precisar configurar o arquivo config.ru que geramos junto com o arquivo Gemfile no comando que rodamos anteriormente, lembra?

Adicione o conteúdo abaixo ao arquivo config.ru.

Este template assume que suas imagens e seus arquivos JavaScript e CSS estejam dentro dos diretórios images, js e css respectivamente, e também que utilize referências relativas a eles em seu arquivo HTML.

Esse arquivo de configuração vai dizer para o Rack as informações necessárias para servir esses arquivos. Ao chamar o comando rackup, o Rack vai verificar se existe esse arquivo de configuração e vai utiliza-lo.

Rodando localmente

Para executar o seu site localmente e visualizar as modificações antes da implantação lá no Heroku, execute o seguinte comando no diretório raiz do site:

Para ver o seu site estático carregado você pode abrir o link http://localhost:9292. À medida que você fizer alterações no site, você só precisa recarregar o seu navegador para ver as mudanças.

Deploy no Heroku

A Heroku é uma plataforma como um serviço (PaaS) que permite aos desenvolvedores criar, executar e operar aplicativos inteiramente na nuvem.

Antes de implantar seu site no Heroku, você precisará armazenar seu código no sistema de controle de versão Git que foi instalado para você como parte do CLI do Heroku. CLI significa interface de linha de comando, é um meio de interagir com um programa de computador, nesse caso, o programa do Heroku que faz o intermédio entre a nuvem (onde ele mora) e sua máquina local.

No diretório raiz do site, execute os seguintes comandos:

*Se por algum motivo você ainda não tem o Git instalado em sua máquina, você pode seguir o tutorial de instalação clicando aqui.

Antes de subir nossa aplicação para o Heroku, precisamos antes entender um detalhe. Quando executamos o comando bundle install é gerado uma porção de arquivos referentes a nossas dependências como o estado local, a localização do pacote instalado, bem como as gems/dependências locais configuradas, e outras configurações que não precisam ser enviadas para o Heroku.

Pra evitarmos que isso aconteça, precisamos criar um arquivo chamado .gitignore na raiz do projeto que vai ignorar esses arquivos desnecessários quando subirmos atualizações para o Heroku.

Dentro do arquivo .gitignore adicione as linhas:

Para fazermos o deploy para o Heroku, vamos utilizar o Git!

Nesse ponto o seu site já está implantado no Heroku e você irá receber uma URL que é gerada automaticamente. Agora você pode abrir o seu site utilizando o comando:

*Guarde essa URL! vamos utilizar ela depois.

Agora você pode fazer um break e tomar seu café sossegado! A primeira etapa está feita, agora em diante vamos nos preocupar em automação de testes!

Tyler The Sloth by allheartsgoboom

Agora podemos mascarar a preguiça, seguir adiante e configurarmos o WebDriver!

Selenium WebDriver

Conduzir um navegador de forma nativa como um usuário, localmente ou em uma máquina remota usando o servidor Selenium, marca um salto em frente em termos de automação do navegador.

Selenium WebDriver faz chamadas diretas para o navegador usando o suporte nativo de cada navegador para automação.

Vamos adicionar uma nova gem/dependência ao nosso arquivo Gemfile. Essa gem é o Selenium WebDriver.

Gemfile

Agora podemos rodar o comando novamente para instalar a nova dependência:

RSpec

Uma biblioteca/ferramenta para testes para Ruby, possui também uma linguagem de domínio específico (DSL) para ajudar a escrever testes, o RSpec também é considerado um framework de Desenvolvimento Orientado a Comportamento (BDD) que lhe ajuda a testar comportamentos ao invés de apenas métodos/funções específicas.

Mais adiante, podemos notar que para conseguirmos um ciclo completo de BDD, precisaríamos de uma ferramenta como o Cucumber para escrever cenários externos (separados/não técnicos) em linguagem humana. Isso também serve como um teste de integração de alto nível, certificando que a aplicação funciona como esperado, na perspectiva do usuário. Podemos dizer que a diferença principal entre RSpec e o Cucumber (ambos frameworks de teste) seja no fator de negócio. A ideia mais forte no Cucumber é que a especificação (features) são separadas do código de teste, dessa forma o dono do produto pode prover ou revisar a especificação sem ter que olhar pros detalhes do código.

Vamos adicionar a gem/dependência do RSpec em nosso arquivo chamado Gemfile que é o arquivo onde descrevemos as dependências de apps Ruby.

Gemfile

Agora precisamos instalar essa gem chamando os comandos abaixo:

Feito isso podemos observar que um novo diretório foi criado, ele é chamado spec e é dentro deste diretório que iremos criar os nossos testes.

Organizando a estrutura

Agora vamos reorganizar a estrutura do nosso projeto. Vamos colocar a pasta spec dentro de uma outra pasta chamada test:

Escrevendo o primeiro teste

Vamos criar um arquivo chamado login_spec.rb dentro do diretório spec:

Na linha 14 você vai precisar atualizar o URL para o de sua aplicação que você subiu no Heroku anteriormente.

Como podemos ver, usamos a diretiva require para adicionar o Selenium como dependência para o nosso arquivo de teste, dai podemos ter acesso a instância do navegador que queremos utilizar. Para esse exemplo eu estou utilizando o navegador Chrome.

Dado o código acima, vamos executar os testes com o RSpec dentro da pasta test com o comando abaixo:

Eita!!!

Drivers

O ChromeDriver é um executável separado que WebDrivers utilizam para controlar o navegador Chrome. Ele é mantido pela equipe do Chromium com a ajuda dos colaboradores do WebDriver.

O WebDriver é uma ferramenta de software livre para testes automatizados de apps Web. Ele fornece recursos para navegar em páginas da Web, realizar entrada de dados, execução de JavaScript e muito mais.

O erro anterior ocorreu porque os drivers de navegador (controladores de navegador) agora são fornecidos pelos distribuidores de navegadores. Dessa forma, precisamos instalar o servidor/chromedriver como é recomendado pela linha de comando. Para isso precisando acessar o link:

Vamos encontrar várias versões neste link e recomendo utilizar a versão 2.40 que é a versão que utilizei em tempo de escrita. *Nada te impede de tentar utilizar uma versão mais nova!

*Como nesse exemplo estou utilizando o sistema operacional Mac 64, vou selecionar o arquivo chromedriver_mac64.zip.

Após o carregamento, precisamos informar o caminho do chromedriver para o Selenium.

Um novo diretório

Para facilitar, vamos mover o arquivo chromedriver (já descompactado) para um novo diretório chamado browsers que vai ficar dentro do nosso diretório test e atualizar o nosso arquivo login_spec.rb com o novo caminho para o driver.

Agora vamos rodar o RSpec mais uma vez!

Perfeito! o teste passou. Podemos ter certeza disso quando quebramos o teste, isso é um passo necessário para confirmar que o teste realmente está passando.

Para fazer isso você precisa atualizar o spec e comentar a ação de submit do form. Isso faz com que o evento que exige o paragrafo de sucesso na autenticação nunca apareça na tela (vai continuar escondido), fazendo com que o teste quebre efetivamente.

Uma dos maiores desafios com testes em Selenium é que eles podem ser difíceis para manter ao longo do tempo.

Na vida real os projetos vivem mudando, sendo assim, precisamos dar um jeito de nos preparar pra isso. Ai que entra os Page Objects.

Page Objects!

Ao invés de escrever nosso teste diretamente contra nosso site, podemos modelar o comportamento do app em simples objetos e escrever os testes contra eles. Desse jeito quando seu site mudar (app) e seus testes quebrarem, você vai mudar apenas em um lugar.

Não só temos benefício de remover o caos como também de reutilizar funcionalidade ao longo do processo.

Bora atualizar o nosso teste e adicionar o Page Object!

Criando um Page Object

Vamos criar mais um diretório chamado pages dentro de spec onde vamos colocar nosso Page Object de login:

Agora temos mapeado todos os elementos que estamos usando para testar em constantes bem nomeadas. Usamos o método initializer para receber uma instância do driver para o Selenium e fazer uma requisição para visitar a pagina de login.

No nosso método with estamos capturando o comportamento principal da página de login que pode ser reutilizado em diversos cenários no futuro.

Agora que nossos elementos vivem mapeados no Page Object, podemos fazer assertiva mais limpa em nosso teste. Daí que vem o método success_message_present, bem mais descritivo no teste (onde é utilizado o ponto de interrogação que faz parte da sintaxe Ruby que implicitamente diz que o método vai retornar um valor booleano, sim ou não).

Atualizando nosso teste em conformidade com nosso Page Object:

*Não se esqueça de alterar o URL do seu projeto Heroku!

No topo do arquivo incluímos o Page Object de login usando o require_relative que nos permite referenciar outro arquivo baseado no caminho atual.

Execute novamente os testes!

Image by The Practical Developer

Conclusão

Agora você sabe como subir um site estático no Heroku e executar alguma automação de testes nele. De agora em diante é com você, recomendo já ir lendo as documentações e os tutoriais dessas ferramentas que utilizamos!

Não coloquei tudo que eu queria nesse post porque se não ficaria enorme (como já ficou). Existe alguns tópicos e ferramentas em torno desse conteúdo de automação, então segue alguns links interessantes:

Bons testes!!!

e valeu por ter chegado até aqui! 🤓

Está interessado ou já é explorador do mundo React? dê uma olhada no meu outro post sobre tutoriais fantásticos e onde habitam!

--

--

Igor Octaviano
Training Center

Senior Software Engineer at @RadicalImaging. @OHIF core team member.