Um pouco de Integração Contínua: Workflow de testes com CircleCI

Há algum tempo que venho pensando em escrever um artigo para compartilhar algum conhecimento adquirido no dia-a-dia, tanto que até para 2018 já havia colocado isto como meta. Então, vamos tirar essa do meta do papel agora!!

Antes de entrar no assunto, vamos ás apresentações. Sou o Victor Hugo, atuo como QA desde 2011, mas foi nos últimos 2 anos que atuei mais fortemente na parte técnica da área, me envolvendo com automação, DevOps, integração contínua, entregas contínuas, etc. Trabalho hoje, especificamente, com testes automatizados (API e UI) com Java, e melhorias no processo de desenvolvimento, sempre buscando entregar o produto com maior qualidade possível.


Pré-requisitos

Para o que quero mostrar hoje, conhecimento em automação de testes com Ruby para entender os testes executados, nada muito avançado.

DICA: O QANinja nos ajudam aqui com uma série de documentos auxiliando na instalação do Ruby em Windows, Linux ou MacOS, além de vários cursos sobre automação.

Para execução local, é necessário ter o Chrome Driver instalado.

Uma conta no GitHub, onde estará nosso projeto com os testes que iremos rodar em nossa ferramenta de Integração Contínua.

Git como ferramenta de versionamento do nosso projeto de testes.

Uma conta no CircleCI, que nada mais é que uma ferramenta de Integração Contínua (Continuous Integration)dentre as várias existentes no mercado, como TravisCI, Jenkins, TeamCity, etc. Sugiro aqui realizar o cadastro já com sua conta github.


Testes automatizados

Para começarmos, vamos então dar um fork no projeto com os testes automatizados e fazer um clone para nosso repositório local. O projeto em questão será o google-test-example criado por mim especificamente para agilizar nossos estudos.

  • Fork: basta apenas clicar no botão Fork no projeto em questão e ele estará no seu repositório no github.
Observação: antes de executar o clone do projeto, sugiro dar uma lida no mesmo, pois, nele contém as explicações de como executar os testes automatizados.
  • Clone: após ter feito o fork, agora na sua máquina com o Git vamos clonar o projeto com o comando:

git clone git@github.com:<SEU_USUARIO>/google-test-example.git

Observação: substituir o ‘<SEU_USUARIO>’ pelo seu usuário do GitHub

Execução dos testes

Bom, agora com o nosso projeto em nossa máquina, ao acessar o diretório google-test-example e executarmos o comando cucumber para que os testes automatizados desenvolvidos com Cucumber sejam executados no browser Google Chrome. Fácil não?!

O resultado esperado deve ser o seguinte:

Além dos testes automatizados, temos também aqui a utilização do RuboCop para análise estática do código. Basta executarmos o comando rubocop teremos o resultado desta análise, garantindo assim um código bem formado e desenvolvido conforme os padrões definidos baseados no Ruby Style Guide. Nosso amigo Wellington Avelino explica o que é análise estática e a sua importância aqui.

Aqui temos a execução do nosso comando:

Legal! Temos nosso projeto de testes e está funcionando perfeitamente, então é só desenvolver mais testes e continuar executando eles? A resposta é não.

Imagine que, dentro da sua equipe, todos comecem a desenvolver testes automatizados, QA’s e Dev’s, logo, o projeto vai começar a crescer mais e mais, então, quem vai ficar responsável por executar todos os testes quando necessário? Quem irá analisar os possíveis erros encontrados pela análise estática do código?

Aqui que entra o mundo maravilhoso da Integração Contínua.


Integração Contínua

Antes de começarmos com a mão na massa, temos que entender o que é Integra Contínua. Segundo Martin Fowler:

“Integração Contínua é uma prática de desenvolvimento de software onde os membros de uma equipe integram seu trabalho frequente, geralmente pelo menos uma vez por dia. Cada integração é verificada por um build automatizado (incluindo testes) para detectar erros e devolver um feedback o mais rápido possível. Muitas equipes viram que essa abordagem reduz significativamente problemas com integração e permite que a equipe desenvolva software mais coeso de forma mais rápida.”

Basicamente, um processo que visa gerar entregas em curtos períodos de tempo, não deixando de lado a qualidade das entregas, easy não?!

Vamos configurar nosso projeto para que, a cada novo commit no nosso projeto de testes, nossa ferramenta de integração contínua execute os testes automatizados e a análise estática do código, assim, transformando o processo manual executado anteriormente em um processo automatizado! Isso é ótimo, certo?!

Configuração do CircleCI:

Como dito no começo, a ferramenta para Integração Contínua que será utilizada será o CircleCI. Optei por essa ferramenta por gostar da forma que os resultados são gerados, sua documentação rica e a facilidade para configuração.

Para configurar o CircleCI é simples, basta acessar o app deles aqui (após estar logado):

Na aba lateral esquerda, acessar a aba Projects e adicionar um novo projeto.

Na tela seguinte, será apresentado todos os projetos existentes no seu github. No nosso caso, vamos selecionar o projeto google-test-example clicando em Setup project.

Aqui existem muitas informações e configurações que podem ser feitas, como seleção do sistema operacional desejado (Linux ou macOS), que no nosso caso será o Linux, plataforma (vamos usar a 2.0 que é a mais atual), e linguagem do projeto que já vem configurada com a linguagem selecionada, no nosso caso, Ruby.

Além disso, o CircleCI nos fala como podemos configurar nosso projeto passo-a-passo para que a execução automática ocorra.

Vamos seguir este passo-a-passo para configurar nosso projeto. Primeiramente, vamos criar o arquivo config.yml dentro do diretório .circleci/ no nosso projeto. Após isto, vamos copiar o conteúdo o Sample.yml sugerido pelo CircleCI para o arquivo config.yml.

A sugestão feita pelo CircleCI é muito boa, mas vamos dar uma melhorada, visto que essa configuração não atende 100% ao que queremos. Basicamente o que queremos é que, a cada novo commit seja feito:

  1. Clone do projeto;
  2. Geração das dependências;
  3. Execução da análise estática do código e, por fim;
  4. Execução dos testes de interface.

Para isso, criei o seguinte arquivo config.yml que contempla os passos citados acima, basta copiar o seguinte arquivo (nele constam alguns comentários para facilitar o entendimento do que é feito):

Vamos a uma breve explicação do que é feito neste arquivo:

  1. checkout_code: Realiza o checkout do nosso projeto de testes e salva o mesmo em cache.
  2. bundle_dependencies: Baixa o projeto e as dependências (se existirem) em cache e executa o comando bundle install para baixar as gem’s utilizadas no projeto. Após isso salva as novas dependências em cache.
  3. code_analyzer: Baixa todas as dependências anteriores geradas e executa a análise estática do código.
  4. chrome_test: Baixa todas as dependências anteriores geradas e executa os testes de interface.
  5. workflow: executa os jobs na ordem definida no arquivo de configuração.

Workflow

Segundo a documentação do CircleCI:

Um workflow é um conjunto de regras para definir uma coleção de tarefas e a sua ordem de execução. Workflow’s suportam orquestração de tarefas complexas usando um conjunto simples de configurações chaves para ajudar a resolver falhas mais cedo.
Observação: Talvez aqui possa parecer complicado, bem por isso aqui vai uma ótima dica, leia a documentação do framework que for utilizar sempre, no nosso caso, do CircleCI sobre configuração, para entender o que está sendo feito em cada passo, e a documentação sobre workflow’s, que explica tudo sobre o workflow.

Após configurado, basta “commitarmos” (adoro essa palavra aportuguesada hahaha) o config.yml, e, no CircleCI clicar em Start building.


Execução do Workflow no CircleCI

Após as configurações feitas, o CircleCI vai começar imediatamente a primeira execução do nosso workflow, respeitando a ordem pré-definida no workflow que fizemos, executando os passos 1 a 1.

Durante a execução dos job’s, podemos acompanhar os dados da execução atual. Veja que a ordem definida foi esta no nosso arquivo.

Após finalizada a execução, podemos ver o resultado da execução, que no nosso caso foi com sucesso. HELL YEAHHH!! Agora a cada commit no nosso projeto de teste, seja de novos testes, refatoração, etc, será executado os testes que configuramos, de análise estática do código e de interface.


Conclusão

Com o objetivo de agilizar o processo de desenvolvimento, a integração contínua é com toda certeza essencial no dia-a-dia de um grupo de desenvolvimento de software, principalmente se a equipe tem como objetivo realizar entregas com mais qualidade em menores períodos de tempo.

Executamos essa integração aqui num fluxo simples onde nosso projeto de testes automatizados é separado da aplicação, mas, pensando num processo de desenvolvimento de software comum nas empresas hoje, os workflow’s podem estar presentes realizando testes automatizados desde o início do desenvolvimento do projeto, até a realização da entrega da aplicação em vários ambientes, estando apto a ir inclusive para produção, garantido assim que a entrega de aplicações de software seja mais rápida e segura; esta abordagem de desenvolvimento é chamada de Entrega Contínua (Continuous Delivery). Mas isso é papo para outro artigo hehe.

Espero que tenham gostado do texto, e que este possa ter-lhe ajudar ou até que possa servir de inspiração para começar a otimizar seu dia-a-dia.

Caso apareça alguma dúvida ou sugestão, se possível, deixar nos comentários para que possamos conversar.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.