Publicidade
Desenvolvimento de software
Testes de regressão visual no fluxo de CI: assim o layout entra na pipeline
Os testes unitários verificam a lógica, mas ninguém verifica o layout: como os testes de regressão visual encaixam numa pipeline de CI, quando devem correr e onde estão os seus limites — explicado com o exemplo do serviço de capturas de ecrã ScanU.
As equipas de desenvolvimento modernas confiam na sua pipeline de integração contínua: cada push desencadeia uma build, os testes unitários correm até ao fim, o linter verifica o estilo, e só quando tudo está verde é que o código passa para o ramo principal. Esta salvaguarda tem, no entanto, um ponto cego. Se o site continua, depois da alteração, com o aspeto que deve ter, isso a pipeline clássica não verifica. Uma refactorização de CSS pode passar em todos os testes e, ainda assim, empurrar o formulário de contacto para trás do rodapé.
A razão está na natureza dos tipos de teste habituais. Os testes unitários verificam funções contra valores de retorno esperados, os testes de integração a interação entre componentes, os testes ponta a ponta percorrem fluxos com cliques e controlam se os elementos definidos estão presentes. Nenhuma destas abordagens vê a página como um ser humano a vê: como imagem renderizada. Um botão pode estar tecnicamente presente, ser clicável e estar corretamente rotulado — e, ainda assim, permanecer invisível, branco sobre branco.
Como surgem essas roturas, mostra-o um olhar sobre o dia a dia: uma atualização de dependências arrasta uma nova versão da framework de CSS, que define alguns espaçamentos predefinidos de outra maneira. Uma refactorização muda o nome a uma classe utilitária que ainda é usada num sítio esquecido. Um ficheiro de tipo de letra é substituído e fica minimamente mais largo, ao que uma navegação passa para a linha seguinte. Nada disto lança um erro, nada disto falha na build — e cada uma destas alterações parece completamente inofensiva na vista de código.
Os testes de regressão visual fecham essa lacuna com um princípio simples. De páginas definidas é fixado um estado de referência, a chamada baseline. Depois de cada alteração surgem novas capturas de ecrã, que uma ferramenta compara com essa baseline. Se a imagem atual divergir, a verificação dispara, e um ser humano decide: alteração desejada ou regressão?
A pergunta interessante para a prática é, nisto, menos o se do que o onde: em que ponto do fluxo de CI têm estas verificações o seu lugar? Ao contrário dos testes unitários, que trabalham diretamente sobre o código-fonte, os testes visuais precisam de uma página renderizada e acessível pela rede. Isso desloca-os para o fim da cadeia — para onde já existe uma versão funcional da aplicação.
Serviços como o ScanU trabalham por isso com base em URL: fornece-se o endereço de uma página acessível e o serviço cria, em cerca de 30 segundos, capturas de ecrã em vários navegadores e classes de dispositivo — Chrome, Firefox e Safari, cada um em vistas de telemóvel, tablet e computador. Como o ScanU monta passo a passo uma dessas séries de verificação descreve-o o próprio fornecedor; o padrão de base vale, porém, para qualquer ferramenta baseada em URL: sem um ambiente que sirva o novo estado, não há nada para fotografar.
De forma mais elegante, isto encaixa em fluxos com as chamadas pré-visualizações de implementação. Muitas plataformas de alojamento constroem automaticamente, para cada pull request, um ambiente de pré-visualização próprio com endereço próprio. É precisamente esse endereço o ponto de partida natural para a comparação visual: a pré-visualização mostra o estado depois da alteração, a baseline o estado aprovado anterior. Se a comparação assinalar um desvio, todos os envolvidos veem o problema antes de o código chegar ao ramo principal — e a discussão acontece onde deve acontecer: na revisão.
Em concreto, a ordem numa pipeline dessas fica assim: primeiro a CI constrói o novo estado, depois a plataforma de alojamento publica o ambiente de pré-visualização e devolve o respetivo endereço, e só depois pode arrancar o passo de verificação visual. É exatamente aqui que, na prática, mais coisas correm mal. Quem desencadeia a série de capturas antes de a pré-visualização estar completamente disponível fotografa uma página meio carregada ou uma mensagem de erro — e compara-a depois, muito a sério, com a baseline. Uma breve verificação de acessibilidade do endereço de pré-visualização antes da série propriamente dita poupa este tipo de confusão. Quando o relatório estiver pronto, a sua ligação pertence ao pull request, como comentário ou no texto da descrição, para que a avaliação aconteça onde já se fala da alteração de qualquer maneira. Os relatórios partilháveis, como os que o ScanU gera, existem precisamente para esse gesto: o relatório é a base comum de discussão, não uma janela de ferramenta que só uma pessoa tem aberta.
As equipas sem ambientes de pré-visualização recorrem ao ambiente de staging e verificam depois do merge, mas antes da implementação em produção. É a segunda melhor solução: as regressões notam-se mais tarde, quando já se misturaram várias alterações, e a procura do causador torna-se mais penosa. Uma série regular adicional contra o site em produção apanha, além disso, alterações que nem sequer vêm do código próprio — por exemplo, quando um script externo integrado ou uma atualização do CMS desloca o aspeto.
A integração técnica é, nisto, a parte menor do trabalho. A maior é uma questão de processo: a manutenção da baseline. Uma baseline não é um artefacto técnico, mas um acordo — é assim que a página deve ficar. Quem lança uma alteração de design desejada tem de atualizar depois a baseline conscientemente, caso contrário cada série seguinte assinala o mesmo desvio esperado. Quem, pelo contrário, a atualiza por reflexo depois de cada alarme acaba um dia por declarar um erro verdadeiro como estado devido.
Provou dar resultado tratar as atualizações de baseline como alterações de código: alguém olha, alguém aprova, e a aprovação é rastreável. O ScanU mostra para isso a baseline e o estado atual lado a lado e gera relatórios partilháveis. Parece pouco espetacular, mas muda a colaboração: também as colegas e os colegas do design ou da gestão de produto conseguem julgar um desvio sem arrancar um ambiente de desenvolvimento — e a decisão «desejado ou estragado» muitas vezes não é puramente técnica.
Uma equipa deveria ainda esclarecer a quem pertence a verificação. Os testes visuais que não estão atribuídos a ninguém ficam órfãos com toda a fiabilidade: os relatórios acumulam-se, ninguém se sente responsável, ao fim de um mês toda a gente os ignora. Provou dar resultado a mesma regra das builds partidas — quem causou a alteração trata do desvio assinalado, e um turno rotativo mantém as séries regulares debaixo de olho.
Do planeamento faz também parte a pergunta sobre a frequência da verificação. Nem todos os commits precisam da série completa sobre todas as páginas e combinações de dispositivo. Modelos de faturação como o sistema de créditos do ScanU tornam esta reflexão concreta: o nível gratuito abrange 500 créditos por mês para um projeto, os níveis pagos vão de 3000 créditos por 19 euros até 50000 créditos por 49 euros por mês. Quem faz passar cada execução da pipeline por todos os perfis de dispositivo esgota depressa a sua quota — e gera, já agora, mais relatórios do que a equipa consegue sequer ver.
Mais sensato é um escalonamento. Os pull requests com alterações em estilos ou templates recebem a comparação sobre as páginas mais importantes; uma série diária ou semanal cobre o conjunto mais alargado em todos os navegadores; antes de uma release corre tudo uma vez. Assim a relação sinal-ruído mantém-se saudável, e cada alarme tem uma hipótese real de ser levado a sério. Um teste visual cujas mensagens a equipa despacha com um clique de rotina vale menos do que nenhum.
Na escolha das páginas vale: templates em vez de instâncias. Uma loja online não tem de fotografar 2000 páginas de produto, mas uma página representativa por tipo de layout. A página inicial, uma página de produto ou de artigo por modelo, o carrinho, os formulários e a página de erro cobrem, na maioria dos projetos, a maior parte do risco. As páginas com elevado valor de negócio — por exemplo, o processo de pagamento — merecem então mais combinações de dispositivo do que o Impressum, a ficha técnica obrigatória por lei nos sítios alemães.
A mesma ponderação vale para os perfis de dispositivo. Os níveis de preço do ScanU distinguem-se também no número de dispositivos disponíveis — de dez no nível gratuito até 98 no maior. Isso seduz para a exaustividade, mas mais perfis significam mais imagens, mais créditos e mais trabalho de triagem. Mais praticável é orientar-se pelos números de acesso próprios: as três, quatro combinações de dispositivo por onde chega efetivamente a maioria das visitantes e dos visitantes, mais um representante de cada um dos extremos — muito estreito, muito largo.
Um obstáculo merece atenção especial: os conteúdos dinâmicos. Destaques rotativos, recomendações personalizadas, avisos de cookies, horas exibidas ou publicidade mudam a imagem a cada carregamento — sem qualquer regressão. Estes falsos alarmes são a razão mais frequente para as equipas voltarem a desligar os testes visuais ao fim de poucas semanas. Os antídotos são conhecidos: ambientes de teste com dados de exemplo fixos, animações desativadas, estados iniciais consistentes. Os falsos alarmes nunca desaparecem por completo, mas conseguem reduzir-se a uma medida suportável.
Da honestidade faz também parte nomear os limites. Uma comparação de capturas bem-sucedida nada diz sobre se o formulário envia efetivamente dados, se a pesquisa devolve resultados ou se o processo de pagamento chega ao fim. Os testes visuais verificam a apresentação, não a função — complementam os testes unitários e os testes ponta a ponta, não os substituem. Quem reduz a sua cobertura de testes funcionais a favor de capturas de ecrã troca um risco por outro.
Também a força de prova depende do ambiente. As verificações baseadas em URL fotografam aquilo que o endereço indicado serve. Se o ambiente de staging diferir claramente da produção — outros dados, outras feature flags, scripts de terceiros em falta —, verifica-se uma imagem distorcida. E as áreas atrás de um início de sessão exigem considerações à parte antes de um serviço externo as poder sequer captar.
Para que a verificação continue ancorada na equipa, ajuda um trato sóbrio com os seus resultados. Vale a pena fazer o balanço de vez em quando: quantos desvios assinalados foram regressões verdadeiras, quantos falsos alarmes, quantas alterações desejadas? Se a relação pender para o falso alarme, isso não é motivo para desligar, mas uma ordem de trabalho para o ambiente de verificação. E se a comparação simplesmente nada encontrar durante meses, uma equipa também pode baixar a frequência de verificação — disciplina de teste não quer dizer expansão máxima, mas adequação.
Um aspeto subestimado é o histórico. Se uma regressão só se nota ao fim de dias, ajuda olhar para trás: quando é que a página esteve correta pela última vez, que período entra em causa como causador? O ScanU guarda os historiais, consoante o nível de preço, entre três e 90 dias. Também isso pertence ao planeamento — um histórico de três dias esgota-se depressa num fim de semana prolongado, ao passo que 90 dias respondem também à pergunta de saber se um problema já existia antes da última release trimestral.
Para começar, há muito a favor de um início pequeno: um projeto, um punhado de páginas, uma série semanal mais uma série por release. Quando cresce a confiança nos alarmes, segue-se o entrosamento mais estreito com a pipeline. Os detalhes sobre o modo de funcionamento estão na documentação do ScanU; uma panorâmica em português é dada pela página do produto em português do fornecedor.
Fica a pergunta de fundo: compensa o esforço? A resposta depende menos da dimensão da equipa do que da frequência das alterações. Quem implementa semanalmente produz semanalmente oportunidades para roturas de layout silenciosas — e descobre-as, sem verificação sistemática, apenas quando as utilizadoras e os utilizadores já as viram há muito. A pipeline de CI ensinou o dia a dia do desenvolvimento a apanhar erros de lógica antes da publicação. Há poucas razões para negar à camada mais visível de um site a mesma proteção.