Integração do projeto VueJS+TS com SonarQube

Usamos ativamente a plataforma em nosso trabalho SonarQubeGenericName para manter a qualidade do código em um alto nível. Ao integrar um dos projetos escritos em VueJs + texto datilografado, surgiram problemas. Portanto, gostaria de contar com mais detalhes como conseguimos resolvê-los.

Integração do projeto VueJS+TS com SonarQube

Neste artigo falaremos, como escrevi acima, sobre a plataforma SonarQube. Um pouco de teoria - o que é em geral, para quem está ouvindo falar pela primeira vez:

SonarQubeGenericName (antigo Sonar) é uma plataforma de código aberto para inspeção contínua e medição de qualidade de código.
Suporta análise de código e detecção de erros de acordo com as regras dos padrões de programação MISRA C, MISRA C++, MITRE/CWE e CERT Secure Coding Standards. Ele também pode reconhecer erros das listas de erros de programação OWASP Top 10 e CWE/SANS Top 25.
Apesar de a plataforma utilizar diversas ferramentas prontas, o SonarQube reduz os resultados a um único dashboard, mantendo um histórico de execuções e permitindo assim visualizar a tendência geral de mudanças na qualidade do software durante o desenvolvimento.

Mais detalhes podem ser encontrados em o site oficial

Um grande número de linguagens de programação é suportado. A julgar pelas informações do link acima, são mais de 25 idiomas. Para oferecer suporte a um idioma específico, você deve instalar o plugin apropriado. A versão da comunidade inclui um plugin para trabalhar com Javascript (incluindo typesсript), embora o wiki diga o contrário. Atrás Javascript respostas do plugin SonarJSGenericName, para texto datilografado SonarTS respectivamente.

O cliente oficial é usado para enviar informações de cobertura scanner sonarqube, que, usando as configurações de configuração-file, envia esses dados para o servidor SonarQubeGenericName para maior consolidação e agregação.

Para Javascript tem invólucro npm. Então, vamos começar a implementação passo a passo SonarQubeGenericName в vista-projeto usando Datilografado.

Para implantar o servidor SonarQubeGenericName vamos aproveitar docker-compose.

sonar.yaml:

version: '1'
    services:
        simplesample-sonar:
            image: sonarqube:lts
            ports:
                - 9001:9000
                - 9092:9092
            network_mode: bridge

Lançar:

docker-compose -f sonar.yml up

Depois disso SonarQubeGenericName estará disponível em: http://localhost:9001 .

Integração do projeto VueJS+TS com SonarQube
Ainda não há projetos e isso é justo. Vamos corrigir esta situação. Peguei o projeto de exemplo oficial para VueJS+TS+Jest. Vamos incliná-lo para nós mesmos:

git clone https://github.com/vuejs/vue-test-utils-typescript-example.git

Primeiro precisamos instalar o cliente SonarQubeGenericNameque é chamado scanner de sonarpara npm há um invólucro:

yarn add sonarqube-scanner

E imediatamente adicione o comando a Scripts para trabalhar com isso.

pacote.json:

{
 … 
   scripts: {
      ...
      "sonar": "sonar-scanner"
      ...
   },
 …
}

A seguir, para que o scanner funcione, você precisa definir as configurações do projeto em um arquivo especial. Vamos começar com o básico.

sonar-project.properties:

sonar.host.url=http://localhost:9001

sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Test Application (VueJS+TS)

sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests*/**
sonar.sourceEncoding=UTF-8

  • sonar.host.url - endereço Sonar'A;
  • sonar.projectKey – identificador exclusivo do projeto no servidor Sonar'A;
  • sonar.projectName – seu nome, podendo ser alterado a qualquer momento, desde que o projeto seja identificado por chave do projeto;
  • sonar.fontes – pasta com fontes, geralmente esta src, mas pode ser qualquer coisa. Esta pasta é definida em relação à pasta raiz, que é a pasta a partir da qual o scanner é iniciado;
  • sonar.testes – um parâmetro que acompanha o anterior. Esta é a pasta onde os testes estão localizados. Neste projeto não existe tal pasta, e o teste está localizado próximo ao componente que está sendo testado na pasta 'teste', então vamos ignorá-lo por enquanto e usar o próximo parâmetro;
  • sonar.teste.inclusões – caminho para testes utilizando máscara, podendo haver vários elementos listados separados por vírgula;
  • sonar.sourceEncoding – codificação para arquivos de origem.

Para a primeira inicialização do scanner está tudo pronto, exceto a principal ação anterior: iniciar o próprio mecanismo de teste, para que ele possa gerar informações sobre a cobertura, que o scanner utilizará posteriormente.

Mas para fazer isso, é necessário configurar o mecanismo de teste para gerar essas informações. Neste projeto, o mecanismo de teste é Brincadeira. E suas configurações estão na seção correspondente do arquivo package.json.

Vamos adicionar estas configurações:

"collectCoverage": true,
"collectCoverageFrom": [
      "src/**/*",
      "!src/main.ts",
      "!src/App.vue",
      "!src/**/*.d.*",
      "!src/**/*__tests__*"
],

Ou seja, definimos o próprio sinalizador para a necessidade de calcular a cobertura e a fonte (juntamente com as exceções) com base na qual ela será formada.

Agora vamos fazer o teste:

yarn test

Veremos o seguinte:

Integração do projeto VueJS+TS com SonarQube

A razão é que não há código no próprio componente. Vamos consertar isso.

HelloWorld.vue:

...
methods: {
    calc(n) {
      return n + 1;
    }
  },
mounted() {
  this.msg1 = this.msg + this.calc(1);
},
...

Isso será suficiente para calcular a cobertura.

Depois de reiniciar o teste, teremos certeza disso:

Integração do projeto VueJS+TS com SonarQube

Na tela devemos ver informações sobre a cobertura, e uma pasta será criada na pasta do projeto cobertura com informações de cobertura de teste em formato universal LCOV (extensão LTP GCOV).

Gcov é um utilitário distribuído gratuitamente para examinar a cobertura de código. Gcov gera o número exato de execuções para cada instrução em um programa e permite adicionar anotações ao código-fonte. Gcov vem como um utilitário padrão como parte do pacote GCC.
Lcov - interface gráfica para gcov. Ele monta arquivos gcov para vários arquivos de origem e produz um conjunto de páginas HTML com código e informações de cobertura. As páginas também são geradas para facilitar a navegação. Lcov oferece suporte à cobertura de strings, funções e ramificações.

Após a conclusão dos testes, as informações de cobertura estarão localizadas em cobertura/lcov.info.
Precisamos dizer Sonar'Onde posso conseguir isso? Portanto, vamos adicionar as seguintes linhas ao seu arquivo de configuração. Mas tem uma coisa: os projetos podem ser multilíngues, ou seja, na pasta src existem códigos-fonte para diversas linguagens de programação e afiliação a uma ou outra, e por sua vez, o uso de um ou outro plugin é determinado por sua extensão. E as informações de cobertura podem ser armazenadas em locais diferentes para diferentes linguagens de programação, portanto, cada linguagem tem sua própria seção para configurar isso. Nosso projeto utiliza Datilografado, então precisamos de uma seção de configurações só para isso:

sonar-project.properties:

sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info

Tudo está pronto para o primeiro lançamento do scanner. Gostaria de salientar que o projeto é Sonar'e é criado automaticamente na primeira vez que você executa o scanner para um determinado projeto. Nos momentos subsequentes, as informações serão acumuladas para ver a dinâmica das mudanças nos parâmetros do projeto ao longo do tempo.

Então, vamos usar o comando criado anteriormente em package.json:

yarn run sonar 

Nota: você também pode usar o parâmetro -X para registro mais detalhado.

Se o scanner foi iniciado pela primeira vez, o binário do próprio scanner será baixado primeiro. Depois disso ele inicia e começa a escanear o servidor Sonar'a para plugins instalados, calculando assim o idioma suportado. Vários outros parâmetros para seu funcionamento também são carregados: perfis de qualidade, regras ativas, repositório de métricas, regras de servidor.

Integração do projeto VueJS+TS com SonarQube

Integração do projeto VueJS+TS com SonarQube

Nota: Não nos deteremos neles em detalhes no âmbito deste artigo, mas você sempre pode entrar em contato com fontes oficiais.

A seguir, começa a análise da pasta src pela disponibilidade de arquivos de origem para todos os idiomas suportados (se um específico não for especificado explicitamente), com sua posterior indexação.

Integração do projeto VueJS+TS com SonarQube

Em seguida vêm várias outras análises, nas quais não nos concentramos neste artigo (por exemplo, como linting, detecção de duplicação de código, etc.).

Ao final do trabalho do scanner, todas as informações coletadas são agregadas, arquivadas e enviadas ao servidor.

Depois disso, já podemos ver o que aconteceu na interface web:

Integração do projeto VueJS+TS com SonarQube

Como podemos ver, algo funcionou, e até mostra algum tipo de cobertura, mas não corresponde à nossa Brincadeira-relatório.

Vamos descobrir. Vejamos o projeto com mais detalhes, clique no valor da cobertura e “caia” em um relatório de arquivo detalhado:

Integração do projeto VueJS+TS com SonarQube

Aqui vemos, além do arquivo principal, examinado HelloWorld.vue, também há um arquivo principal.ts, o que estraga todo o quadro da cobertura. Mas como é que excluímos isso do cálculo da cobertura? Sim, está tudo correto, mas foi nivelado Brincadeira, mas o scanner o indexou, então acabou em seus cálculos.

Vamos consertar isso:

sonar-project.properties:

...
sonar.exclusions=src/main.ts
...

Gostaria de fazer um esclarecimento: além das pastas que estão especificadas neste parâmetro, também são adicionadas todas as pastas listadas no parâmetro sonar.teste.inclusões.

Após iniciar o scanner, vemos as informações corretas:

Integração do projeto VueJS+TS com SonarQube

Integração do projeto VueJS+TS com SonarQube

Vejamos o próximo ponto - Perfis de qualidade. Falei acima sobre suporte Sonarem vários idiomas ao mesmo tempo. Isso é exatamente o que estamos vendo. Mas sabemos que nosso projeto está escrito em TS, então por que sobrecarregar o scanner com manipulações e verificações desnecessárias. Definiremos o idioma para análise adicionando mais um parâmetro ao arquivo de configuração Sonar'A:

sonar-project.properties:

...
sonar.language=ts
...

Vamos executar o scanner novamente e ver o resultado:

Integração do projeto VueJS+TS com SonarQube

A cobertura desapareceu completamente.

Se olharmos o log do scanner, podemos ver a seguinte linha:

Integração do projeto VueJS+TS com SonarQube

Ou seja, nossos arquivos de projeto simplesmente não foram indexados.

A situação é a seguinte: oficialmente apoiada VueJs está no plug-in SonarJSGenericNamequem é responsável por Javascript.

Integração do projeto VueJS+TS com SonarQube

Mas esse suporte não está no plugin SonarTS para TS, sobre o qual um ticket oficial foi aberto no bug tracker Sonar'A:

  1. https://jira.sonarsource.com/browse/MMF-1441
  2. https://github.com/SonarSource/SonarJS/issues/1281

Aqui estão algumas respostas de um dos representantes dos desenvolvedores do SonarQube, confirmando este fato.

Integração do projeto VueJS+TS com SonarQube

Integração do projeto VueJS+TS com SonarQube

Mas tudo funcionou para nós, você contesta. Sim, é, vamos tentar um pouco “hackear”.
Se houver apoio .vue-arquivos Sonar'ah, então vamos tentar dizer a ele para considerá-los como Datilografado.

Vamos adicionar um parâmetro:

sonar-project.properties:

...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...

Vamos iniciar o scanner:

Integração do projeto VueJS+TS com SonarQube

E pronto, tudo voltou ao normal, e com um perfil só para Datilografado. Ou seja, conseguimos resolver o problema no suporte VueJs+TS para SonarQubeGenericName.

Vamos tentar ir mais longe e melhorar um pouco as informações de cobertura.

O que fizemos até agora:

  • adicionado ao projeto Sonar-scanner;
  • configurar Brincadeira gerar informações de cobertura;
  • configurado Sonar-scanner;
  • resolveu o problema de suporte .vue-arquivos + Datilografado.

Além da cobertura dos testes, existem outros critérios úteis e interessantes para a qualidade do código, por exemplo, a duplicação do código e o número de linhas (envolvidas no cálculo dos coeficientes relacionados à complexidade do código) do projeto.

Na implementação atual do plugin para trabalhar com TS (SonarTS) não funciona CPD (detector de copiar e colar) e contando linhas de código .vue-arquivos.

Para criar uma situação sintética de duplicação de código, basta duplicar o arquivo do componente com um nome diferente e adicioná-lo também ao código principal.ts uma função fictícia e duplicá-la com um nome diferente. Para verificar se há duplicação como em .vuee em .ts -arquivos.

principal.ts:

...
function name(params:string): void {
  console.log(params);
}
...

Para fazer isso, você precisa comentar temporariamente a linha de configuração:

sonar-project.properties:

...
sonar.exclusions=src/main.ts
...

Vamos reiniciar o scanner junto com os testes:

yarn test && yarn run sonar

É claro que nossa cobertura vai cair, mas agora não estamos interessados ​​nisso.

Em termos de duplicação de linhas de código, veremos:

Integração do projeto VueJS+TS com SonarQube

Para verificar usaremos CPD-Utilitário - jscpd:

npx jscpd src

Integração do projeto VueJS+TS com SonarQube

Para linhas de código:

Integração do projeto VueJS+TS com SonarQube

Talvez isso seja resolvido em futuras versões do plugin SonarJS(TS). Gostaria de observar que eles estão gradualmente começando a fundir esses dois plugins em um SonarJSGenericName, o que considero correto.

Agora eu queria considerar a opção de melhorar as informações de cobertura.

Até agora podemos ver a cobertura dos testes em termos percentuais para todo o projeto e para arquivos em particular. Mas é possível ampliar esse indicador com informações sobre a quantidade unidade-testes para o projeto, bem como no contexto de arquivos.

Existe uma biblioteca que pode Brincadeira-converter o relatório em formato para Sonar'A:
dados de teste genéricos - https://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

Vamos instalar esta biblioteca em nosso projeto:

yarn add jest-sonar-reporter

E adicione-o à configuração Brincadeira:

pacote.json:

…
"testResultsProcessor": "jest-sonar-reporter"
…

Agora vamos fazer o teste:

yarn test

Após o qual um arquivo será criado na raiz do projeto relatório de teste.xml.

Vamos usá-lo na configuração Sonar'A:

sonar-project.properties:

…
sonar.testExecutionReportPaths=test-report.xml
…

E reinicie o scanner:

yarn run sonar

Vamos ver o que mudou na interface Sonar'A:

Integração do projeto VueJS+TS com SonarQube

E nada mudou. O fato é que o Sonar não considera os arquivos descritos no relatório Jest como arquivos unidade-testes. Para corrigir esta situação, utilizamos o parâmetro de configuração Sonar sonar.testes, onde indicaremos explicitamente as pastas com testes (só temos uma por enquanto):

sonar-project.properties:

…
sonar.tests=src/components/__tests__
…

Vamos reiniciar o scanner:

yarn run sonar

Vamos ver o que mudou na interface:

Integração do projeto VueJS+TS com SonarQube

Agora vimos o número do nosso unidade-testes e, tendo falhado clicando dentro, podemos ver a distribuição deste número entre os arquivos do projeto:

Integração do projeto VueJS+TS com SonarQube

Conclusão

Então, olhamos para uma ferramenta de análise contínua SonarQubeGenericName. Integramos com sucesso nele um projeto escrito em VueJs+TS. Corrigidos alguns problemas de compatibilidade. Aumentamos o conteúdo informativo do indicador de cobertura de testes. Neste artigo examinamos apenas um dos critérios de qualidade de código (talvez um dos principais), mas SonarQubeGenericName apoia outros critérios de qualidade, incluindo testes de segurança. Mas nem todos esses recursos estão totalmente disponíveis em comunidade-versões. Um dos recursos interessantes e úteis é a integração SonarQubeGenericName com vários sistemas de gerenciamento de repositório de código, como GitLab e BitBucket. Prevenir solicitação de pull de mesclagem (mesclagem)'a para o branch principal do repositório quando a cobertura estiver degradada. Mas esta é uma história para um artigo completamente diferente.

PS: Tudo descrito no artigo em forma de código está disponível em meu garfo.

Apenas usuários registrados podem participar da pesquisa. Entrarpor favor

Você usa a plataforma SonarQube:

  • 26,3%sim5

  • 15,8%No3

  • 15,8%Ouvi falar desta plataforma e quero usar3

  • 10,5%Já ouvi falar desta plataforma e não quero usar2

  • 0,0%Estou usando uma plataforma diferente0

  • 31,6%Primeira vez que ouvi falar dela6

19 usuários votaram. 3 usuários se abstiveram.

Fonte: habr.com

Adicionar um comentário