Análise Estática – Da Introdução à Integração

Cansado de revisões de código intermináveis ou de depurações, às vezes você se pergunta como simplificar sua vida. E, depois de uma breve pesquisa, ou talvez por acaso, você pode se deparar com a mágica expressão: "Análise Estática". Vamos ver o que é isso e como pode interagir com o seu projeto.

Análise Estática – Da Introdução à Integração
Na verdade, se você está programando em alguma linguagem moderna, então, mesmo sem saber, você a passou por um analisador estático. A questão é que qualquer compilador moderno fornece, ainda que em um nível mínimo, um conjunto de avisos sobre problemas potenciais no código. Por exemplo, ao compilar código C++ no Visual Studio, você pode ver o seguinte:

Análise Estática – Da Introdução à Integração
Nesta saída, vemos que a variável var não foi utilizada em nenhum lugar da função. Portanto, na verdade, você quase sempre usou um simples analisador estático de código. No entanto, ao contrário de analisadores profissionais como Coverity, Klocwork ou PVS-Studio, os avisos fornecidos pelo compilador podem apontar apenas para um pequeno espectro de problemas.

Se você não sabe ao certo o que é análise estática e como implementá-la, leia este artigo, para se familiarizar melhor com essa metodologia.

Para que serve a análise estática?

Em poucas palavras: acelerar e simplificar.

A análise estática permite encontrar uma série de problemas diversos no código: desde o uso incorreto de construções da linguagem até erros de digitação. Por exemplo, em vez de

auto x = obj.x;
auto y = obj.y;
auto z = obj.z;

Você escreveu o seguinte código:

auto x = obj.x;
auto y = obj.y;
auto z = obj.x;

Como você pode ver, na última linha houve um erro de digitação. Por exemplo, o PVS-Studio emite o seguinte aviso:

V537 Considere revisar a correção da utilização do item 'y'.

Se você quiser interagir com esse erro manualmente, experimente o exemplo disponível no Compiler Explorer: *clique*.

E como você entende, nem sempre é possível prestar atenção a essas partes do código imediatamente, e por causa disso, você pode passar horas depurando, sem entender por que tudo está funcionando de forma tão estranha.

No entanto, esse é um erro evidente. E se o desenvolvedor escreveu um código não otimizado porque esqueceu algum detalhe da linguagem? Ou mesmo cometeu um comportamento indefinido no código?? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.

Foi para essas situações que a análise estática surgiu. É uma ferramenta para o desenvolvedor que aponta diversos problemas no código e explica na documentação por que não se deve escrever assim, quais consequências isso pode ter e como corrigir. Aqui está um exemplo de como isso pode parecer:clique*.

Mais erros interessantes que o analisador pode detectar podem ser encontrados nos artigos:

Agora que você leu este material e se convenceu da utilidade da análise estática, pode estar se perguntando como aplicá-la na prática. Mas por onde começar? Como integrar uma nova ferramenta ao projeto atual? E como apresentar isso à equipe? Você encontrará respostas para essas perguntas abaixo.

Observação. A análise estática não substitui nem anula algo tão útil como as revisões de código. Ela complementa esse processo, ajudando a detectar e corrigir erros de digitação, imprecisões e construções perigosas de forma antecipada. É muito mais produtivo focar nas revisões de código nos algoritmos e na clareza do código, em vez de ficar buscando um parêntese colocado em um lugar errado ou ler funções de comparação entediantes..

0. Apresentação da ferramenta

Tudo começa com uma versão de teste. De fato, é difícil decidir implementar qualquer coisa no processo de desenvolvimento se nunca viu a ferramenta ao vivo. Portanto, o primeiro passo é baixar a versão de teste..

O que você aprenderá nesta etapa:

  • Quais são as maneiras de interagir com o analisador;
  • Se o analisador é compatível com o seu ambiente de desenvolvimento;
  • Quais problemas atualmente existem em seus projetos.

Depois de instalar tudo o que você precisa, o primeiro passo é iniciar a análise de todo o projeto (Windows, Linux, macOS). No caso do PVS-Studio no Visual Studio, você verá uma imagem semelhante (clicável):

Análise Estática – Da Introdução à Integração
A questão é que, normalmente, projetos com uma grande base de código geram uma enorme quantidade de avisos por parte dos analisadores estáticos. Não há necessidade de corrigir todos, pois seu projeto já está funcionando, o que significa que esses problemas não são críticos. No entanto, você pode verificar os avisos mais interessantes. e corrigi-los se necessário. Para isso, é preciso filtrar a saída e deixar apenas as mensagens mais confiáveis. No plugin PVS-Studio para Visual Studio, isso é feito filtrando por níveis e categorias de erros. Para uma saída mais precisa, mantenha habilitadas apenas Alto e Geral (também clicável):

Análise Estática – Da Introdução à Integração
Realmente, 178 avisos são muito mais fáceis de revisar do que vários milhares...

Nas abas Medium e Baixo frequentemente aparecem bons avisos, porém nessas categorias estão incluídas aquelas diagnósticas que têm menor precisão (confiabilidade). Mais informações sobre os níveis de avisos e opções de funcionamento no Windows podem ser vistas aqui: *clique*.

Depois de revisar os erros mais interessantes (e corrigi-los com sucesso), é hora de silenciar os avisos restantes. Isso é necessário para que novos avisos não se percam entre os antigos. Além disso, o analisador estático é uma ferramenta para o programador, e não uma lista de bugs. 🙂

1. Automação

Após a introdução, chega o momento de configurar plugins e integrá-los ao CI. Isso deve ser feito antes que os programadores comecem a usar o analisador estático. A questão é que o programador pode esquecer de ativar a análise ou simplesmente não querer. Para isso, é necessário fazer uma verificação final para que o código não verificado não possa entrar na branch principal de desenvolvimento.

O que você descobrirá nesta etapa:

  • Quais opções de automação a ferramenta oferece;
  • Se o analisador é compatível com seu sistema de build.

Como não existe documentação perfeita, às vezes é necessário escrever para suporte. Isso é normal, e ficamos felizes em ajudar você. 🙂

Agora vamos abordar os serviços de integração contínua (CI). Qualquer analisador pode ser integrado a eles sem grandes problemas. Para isso, é preciso criar uma etapa separada no pipeline, que geralmente fica após a build e os testes unitários. Isso é feito usando várias ferramentas de console. Por exemplo, o PVS-Studio oferece as seguintes ferramentas:

Para integrar a análise ao CI, é necessário fazer três coisas:

  • Instalar o analisador;
  • Iniciar a análise;
  • Entregar os resultados.

Por exemplo, para instalar o PVS-Studio no Linux (base Debian), você deve executar os seguintes comandos:

wget -q -O - https://files.viva64.com/etc/pubkey.txt 
    | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list 
  https://files.viva64.com/etc/viva64.list
  
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio

Nos sistemas operacionais Windows, não há como instalar o analisador pelo gerenciador de pacotes, porém é possível implantar o analisador a partir da linha de comando:

PVS-Studio_setup.exe /verysilent /suppressmsgboxes 
/norestart /nocloseapplications

Mais informações sobre a implantação do PVS-Studio em sistemas Windows podem ser encontradas em *aqui*.

Após a instalação, você deve iniciar a análise. No entanto, isso é recomendado apenas depois que a compilação e os testes foram concluídos. Isso se deve ao fato de que a análise estática geralmente requer duas vezes mais tempo do que a compilação.

Como a forma de iniciar depende da plataforma e das características do projeto, eu mostrarei uma opção para C++ (Linux) como exemplo:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w

O primeiro comando executará a análise, e o segundo converteo relatório para o formato de texto, o exibirá na tela e retornará um código de saída diferente de 0 em caso de avisos. Esse mecanismo é conveniente para bloquear a compilação caso haja mensagens de erro. No entanto, você sempre pode remover a flag -w e não bloquear a compilação que contém avisos.

Observação. O formato de texto não é conveniente. Ele é apresentado apenas como exemplo. Observe um formato de relatório mais interessante — FullHtml. Ele permite a navegação pelo código.

Mais informações sobre como configurar a análise em CI podem ser encontradas no artigo "PVS-Studio e Integração Contínua" (Windows) ou "Como configurar o PVS-Studio no Travis CI" (Linux).

Bem, você configurou o funcionamento do analisador no servidor de compilação. Agora, se alguém enviar código não verificado, a etapa de verificação falhará, e você poderá identificar o problema. No entanto, isso não é exatamente conveniente, pois é mais eficaz verificar o projeto antes de ocorrer a fusão das branches, e sim antes, na etapa da pull request.

Em geral, a configuração da análise da pull request não difere muito da execução normal da análise em CI. Exceto pela necessidade de obter a lista de arquivos modificados. Normalmente, você pode obtê-los solicitando a diferença entre as branches usando git:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

Agora é necessário passar essa lista de arquivos para o analisador. Por exemplo, no PVS-Studio isso é implementado através de uma flag. -S:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Você pode saber mais sobre a análise de pull requests *aqui* Mesmo que seu CI não esteja na lista de serviços mencionados no artigo, a seção geral dedicada à teoria desse tipo de análise será útil.

Ao configurar a análise de pull requests, você poderá bloquear commits que contenham avisos, criando assim uma barreira que o código não verificado não poderá ultrapassar.

Isso é muito bom, no entanto, gostaria de ter a possibilidade de ver todos os avisos em um só lugar. Não apenas do analisador estático, mas também dos testes unitários ou do analisador dinâmico. Para isso, existem vários serviços e plugins. O PVS-Studio, por exemplo, possui um plugin para integração no SonarQube..

2. Integração nas máquinas dos desenvolvedores

Agora é hora de instalar e configurar o analisador para uso diário durante o desenvolvimento. Neste ponto, você já se familiarizou com a maior parte dos modos de operação, portanto, essa pode ser considerada a parte mais fácil.

Como a opção mais simples, os desenvolvedores podem instalar o analisador necessário por conta própria. No entanto, isso levará muito tempo e os desviará do desenvolvimento, então você pode automatizar esse processo usando um instalador e as flags necessárias. Para o PVS-Studio, existem várias flags para instalação automatizada.. No entanto, sempre existem gerenciadores de pacotes, como Chocolatey (Windows), Homebrew (macOS) ou dezenas de opções para Linux.

Em seguida, você precisará instalar os plugins necessários, como para Visual Studio., IDEA., Rider. etc.

3. Uso diário

Nesta etapa, é hora de dizer algumas palavras sobre maneiras de acelerar o trabalho do analisador durante o uso diário. A análise completa de todo o projeto leva muito tempo, mas com que frequência mudamos o código de uma só vez em todo o projeto? É raro existir uma refatoração tão grande que afete imediatamente toda a base de código. O número de arquivos modificados de uma vez raramente ultrapassa uma dúzia, portanto, vale a pena analisá-los. Para essa situação, existe o modo de análise incremental.. Apenas não se assuste, não é mais uma ferramenta. Este é um modo especial que permite analisar apenas os arquivos modificados e suas dependências, e isso acontece automaticamente após a compilação, se você estiver trabalhando em uma IDE com um plugin instalado.

Caso o analisador encontre problemas no código recentemente modificado, ele avisará por conta própria. Por exemplo, o PVS-Studio o informará através de um alerta:

Análise Estática – Da Introdução à Integração
Não basta dizer aos desenvolvedores para usar a ferramenta. É necessário explicar a eles o que é e como utilizá-la. Aqui estão artigos sobre como começar rapidamente com o PVS-Studio, mas tutoriais semelhantes podem ser encontrados para qualquer ferramenta de sua preferência:

Esses artigos fornecem todas as informações necessárias para o uso diário e não consomem muito tempo. 🙂

Mesmo na fase inicial de familiarização com a ferramenta, neutralizamos muitos avisos durante uma das primeiras execuções. Infelizmente, os analisadores estáticos não são perfeitos, por isso, de vez em quando, geram falsos positivos. Normalmente, é fácil neutralizá-los; por exemplo, no plugin PVS-Studio para Visual Studio, basta clicar em um botão:

Análise Estática – Da Introdução à Integração
No entanto, você não precisa apenas neutralizá-los. Por exemplo, você pode relatar a existência de um problema ao suporte. Se o falso positivo puder ser corrigido, nas atualizações futuras você notará que cada vez há menos e menos falsos positivos específicos para sua base de código.

Após a integração

Após passar por todas as etapas de integração da análise estática no processo de desenvolvimento. Apesar da importância da configuração dessas ferramentas no CI, o lugar mais importante de execução é, de fato, o computador do desenvolvedor. Afinal, o analisador estático não é um juiz que diz de longe que o código não serve. Pelo contrário, é um assistente que avisa se você está cansado e lembra se você esqueceu de algo.

A verdade é que, sem o uso regular, a análise estática provavelmente não simplificará significativamente o desenvolvimento. Afinal, seu principal benefício para o desenvolvedor não reside apenas na identificação de áreas complexas e controversas do código, mas sim na detecção precoce dessas questões. Concordamos que descobrir um problema quando as alterações já foram para teste é não apenas desagradável, mas também consome muito tempo. A análise estática, por sua vez, ao ser usada regularmente, revê cada alteração diretamente em seu computador e informa sobre áreas suspeitas durante o trabalho com o código.

E se você ou seus colegas ainda estão inseguros sobre a implementação de um analisador, recomendo que leiam agora o artigo "Razões para implementar um analisador de código estático PVS-Studio no processo de desenvolvimento". Nele, são discutidas as preocupações comuns dos desenvolvedores sobre o tempo que a análise estática pode consumir e outras questões semelhantes.

Análise Estática – Da Introdução à Integração

Se você deseja compartilhar este artigo com um público de língua inglesa, peço que use o link para a tradução: Maxim Zvyagintsev. Análise Estática: Do Começo à Integração.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster