Integração contínua

Construa a agilidade da sua equipe com feedback mais rápido. Porque você só se move tão rápido quanto seus testes.

Dan Radigan Dan Radigan

Nada cria – ou destrói – agilidade como um compromisso da equipe com a integração contínua (CI). Isso pode parecer ameaçador (especialmente se a equipe ainda não está usando CI), mas as notícias são boas. Independentemente das tecnologias que uma equipe usa, há muitas chances de haver uma integração contínua e uma estrutura de testes automatizados que funcionarão de acordo com a base de código.

Integração contínua

Integração contínua é a prática de integrar, rotineiramente, alterações de código na ramificação principal de um repositório e testar as alterações, o mais cedo e frequente possível. Idealmente, os desenvolvedores integrarão seus códigos diariamente, se não várias vezes ao dia.

Benefícios da integração contínua

Investir em CI resulta em feedback rápido sobre as alterações de código. Tão rápido quanto "em minutos". Uma equipe que se baseia principalmente em teste manual pode receber feedback em algumas horas, mas, na realidade, feedback de teste abrangente só chega em um dia–ou vários dias–depois de o código ser alterado. E, quando mais alterações forem feitas, torne a correção de erros uma "expedição" com os desenvolvedores, analisando várias camadas de código para entender qual é a raiz do problema.

Isso, decididamente, não é rápido.

Proteja a qualidade com compilações contínuas e automação de teste

Quantos de nós já baixou o código fonte mais recente e percebeu que ele não compilava ou tinha um erro significativo? Isso destrói a produtividade!

Duas práticas podem nos manter longe dessa situação:

Compilações contínuas: compilar o projeto assim que uma alteração for feita. Idealmente, o delta entra cada compilação é um conjunto com uma única alteração.

Automação de teste: validação programática do software para garantir a qualidade. Os testes podem iniciar ações no software a partir da IU (falaremos mais sobre isso em breve) ou de uma camada de serviços de back-end.

Pense nessas duas práticas como manteiga de amendoim e geleia: são bons separadamente e melhor juntos! A integração contínua unifica compilações contínuas com automação de teste para garantir que cada compilação também avalie a qualidade da base de código.

E lembre-se: para aproveitar os benefícios, a equipe também deve ter disciplina para pausar o desenvolvimento e abordar os obstáculos imediatamente. A energia que a equipe investe (e não se engane: é um investimento) ao escrever testes e configurar a automação será em vão se as compilações forem deixadas para trás. Proteger o investimento em CI e a qualidade da base de código é a mesma coisa. 

Testes em CI: unidade, API e testes funcionais

As execuções de CI têm duas fases principais. A etapa um garante a compilação do código. (Ou, no caso de linguagens interpretadas, simplesmente reúne todas as partes.) A etapa dois garante que o código funcione do modo esperado. O modo mais seguro de fazer isso é com uma série de testes automatizados que validam todos os níveis do produto. 

Testes de unidade

Os testes de unidade são executados próximos a componentes centrais no código. Eles são a primeira linha de defesa na garantia da qualidade.

Benefícios: fácil de escrever, rápido de executar, modelo de acordo com a arquitetura da base de código.

Desvantagens: os testes de unidade validam apenas os componentes principais do software. Eles não refletem os fluxos de trabalho do usuário que, normalmente, envolvem vários componentes em execução ao mesmo tempo.

Como um teste de unidade explica como o código deve funcionar, os desenvolvedores podem revisar testes de unidade para se atualizarem em relação à área do código.

Testes de API

Um software bom é modular, o que permite uma separação mais clara do trabalho em vários aplicativos. As APIs são os pontos de extremidade nos quais diferentes módulos se comunicam uns com os outros, e os testes de API fazem a validação deles com chamadas de um módulo para o outro.

Benefícios: geralmente fácil de escrever, rápido de executar e pode modelar rapidamente como os aplicativos farão a interação uns com os outros.

Desvantagens: em áreas simples do código, os testes de API podem imitar alguns testes de unidade.

Como as APIs são interfaces entre partes do aplicativo, elas são especialmente úteis ao preparar-se para uma liberação. Quando uma compilação candidata à liberação é aprovada em todos os testes de API, a equipe consegue ser muito mais eficiente na entrega aos clientes. 

Testes funcionais

Testes funcionais são feitos em grandes áreas da base de código e modelam os fluxos de trabalho do usuário. Nos aplicativos web, por exemplo, o HTTPUnit e o Seleniuminteragem diretamente com a interface do usuário para testar o produto.

Benefícios: mais probabilidade de encontrar erros, pois imitam as ações do usuário e testam a interoperabilidade de vários componentes.

Desvantagens: mais lento que os testes de unidade e, às vezes, reporta falsos negativos devido à latência da rede ou a uma interrupção momentânea em algum lugar da pilha de tecnologia.

As equipes, normalmente, percebem que, quando se aproximam do fluxo de trabalho real do usuário, a velocidade da execução dos testes automatizados diminui. O HTTPUnit é mais rápido porque não é um navegador web completo. O Selenium somente pode ser executado na mesma velocidade que o navegador web, mas tem a vantagem de ser executado em vários navegadores web em paralelo. Apesar disso, os testes funcionais são muito valiosos e fornecem feedback muito mais rapidamente do que testadores humanos.

Falando nisso...

Alguns testadores veem os testes automatizados como uma ameaça existencial. Esse pensamento está longe da verdade. Ao não precisarem executar tarefas de teste repetitivas, os testadores podem passar o tempo trabalhando na análise de risco, no planejamento de teste e na criação de outras habilidades – como aprendendo a codificar!

Torne sua integração contínua rápida

Na Atlassian, tentamos manter os desenvolvedores inovando e nossas bases de código funcionando. Colocamos muita ênfase no "ciclo de feedback interno" do desenvolvedor – o tempo necessário para fazer alterações e obter resultados de testes.

Executar testes automatizados pode, rapidamente, adicionar e prolongar a duração da compilação. Uma estratégia é colocar os testes automatizados em paralelo em vários servidores, ou "agentes de compilação", para que o servidor de CI realmente execute 2, 20 ou até mesmo 200 testes simultaneamente. Com as tecnologias de nuvem, a CPU pode ser facilmente escalada para atender as necessidades da sua equipe de desenvolvimento à medida que os conjuntos de testes aumentam. No entanto, a CPU não é ilimitada. Teste cada área do código completamente, mas não de modo redundante. Testes redundantes aumentam a duração da compilação (e desperdiçam CPU). Quanto mais rapidamente os engenheiros recebem a aprovação, mais rapidamente eles conseguem ir para o próximo item da lista de pendências.

Ramificação e CI: uma incrível combinação!

Muitas equipes evitam a ramificação porque as mesclagens são difíceis. Com tecnologias mais recentes no controle de versão, como Git, a ramificação e a mesclagem ficaram mais fáceis. Para garantir que a linha de código primária ("mestre" na linguagem Git) permaneça integra, execute o mesmo nível de integração contínua em todas as ramificações de versão estável e desenvolvimento. Quando a compilação passa por uma ramificação, a equipe tem confiança para mesclar o código na cadeia produtiva.

Com a ramificação, a integração contínua e a automação de teste, as equipes podem ser produtivas e inovadoras enquanto ainda protegem a qualidade do código. Se está pronto para ir para as próximas etapas, confira nosso guia passo a passo para começar a trabalhar com CI.

Esse é o desenvolvimento ágil no seu melhor: fornecimento de software de trabalho regularmente, com débito técnico mínimo e sem comprometer a criatividade.