Jump to content

Como gerar cobertura de código no Cypress para o SonarQube


 Compartilhar

Postagens Recomendadas

Instalação e uso do Cypress

Primeiramente, é necessária a instalação do Cypress no seu projeto Node.js como uma devDependency:

npm install -D Cypress 

Para executar o Cypress diretamente da raiz do seu projeto, adicione os dois scripts no package.json. O primeiro abrirá a GUI do Cypress, enquanto que o segundo rodará todos os testes do projeto em modo silencioso.

{
  "scripts": {
    "cypress:open": "cypress open",
    "cypress:run": "cypress run"
  }
}

Após a adição, execute o comando abaixo definido para abrir o Cypress.  Caso seja a primeira vez que esteja usando o Cypress, o Launchpad do programa será exibido para guiar as decisões de projeto e configurações de tarefas que devem ser definidas antes do primeiro código ser escrito.

npm run cypress:open

Instrumentalização do código

Para calcular a taxa de cobertura em testes E2E no Cypress, é preciso primeiramente instrumentalizar o código do projeto.  A instrumentalização do código é definida como a inserção de contadores adicionais no código-fonte de um projeto antes do tempo de execução. E é por meio desses contadores que o Cypress realiza a computação das linhas do código-fonte que foram executadas durante a realização dos testes e gera o total de cobertura da aplicação.

O Cypress em si não faz a instrumentalização do código. Ela deve ser feita usando o módulo nyc ou o plugin babel-plugin-istanbul durante a transpilação do código de um projeto que use Babel. Nesse tutorial, será descrito como gerar código instrumentado com o babel-plugin-istanbul. Maiores informações sobre a instrumentalização e a cobertura de código do Cypress estão disponíveis na sua documentação.

Adicione em seu projeto as seguintes dependências:

npm install -D @babel/core @babel/preset-react babel-plugin-istanbul babel-plugin-transform-class-properties

Em seguida, crie um arquivo babel.config.js com as configurações abaixo. O if é usado para garantir que o preset e os plugins necessários sejam inseridos apenas durante a fase de testes, já que não há a necessidade de instrumentalizar código em outros ambientes.

module.exports = function (api) {
    api.cache(true);

    let presets = []
    let plugins = []

    if (process.env.test) {
        presets = [
            "@babel/preset-react"
        ]

        plugins = [
            "transform-class-properties",
            "istanbul"
        ]
    }

    return {
        presets,
        plugins
    };
}

Para confirmar se o código foi instrumentalizado, suba a aplicação. Lembre-se que, para o exemplo acima é preciso definir process.env como teste.

Abra o console do navegador, digite window.__coverage__ e aperte Enter. Caso apareçam dados como na imagem abaixo, o código do seu projeto foi instrumentalizado com sucesso 🎉

 

image.png

 

Cobertura de Código E2E

Para gerar cobertura de código durante a execução dos testes, o Cypress utiliza o plugin cypress/code-coverage. Ele faz o merge da cobertura individual obtida em cada teste, salva esse resultado combinado e utiliza o nyc para gerar relatórios em HTML com esses dados de cobertura.

Primeiramente, instale o plugin com o comando:

npm install -D @cypress/code-coverage

Adicione os códigos a seguir nos respectivos arquivos da pasta do Cypress:

// cypress/support/e2e.js

import '@cypress/code-coverage/support'
 
// cypress/plugins/index.js

module.exports = (on, config) => {
  require('@cypress/code-coverage/task')(on, config)
  
  return config
}

Abra a GUI do Cypress e execute um dos testes do seu projeto. Se os comandos dos retângulos verdes na imagem abaixo estiverem presentes durante a execução do teste, então o plugin foi integrado corretamente e a cobertura está sendo gerada.

image.png

Quando o teste terminar de rodar, o arquivo JSON com o merge das coberturas será salvo na pasta nyc_output.  É desse arquivo JSON que podem ser gerados relatórios em diversos formatos, como texto, HTML e LCOV. O plugin também salva um relatório em HTML e um arquivo LCOV com todas as informações de cobertura na pasta coverage.

Geração de Relatórios para o SonarQube

O arquivo lcov.info gerado após o termino da execução dos testes contém informações como a porcentagem de cobertura de código em todo o projeto e ele deve ser enviado via sonarscanner para o SonarQube. Porém, para o Sonar contabilizar o total de testes existentes no projeto é preciso também do TestExecutionReport, que no caso do Cypress pode ser gerado por meio da lib cypress-sonarqube-reporter.

Primeiro, instale as dependências:

npm install -D cypress-sonarqube-reporter sonarqube-scanner

Em seguida, no arquivo cypress.json defina o sonarqube-reporter como reporter e configure as reporterOptions desejadas. Nesse exemplo, os relatórios .xml de cada teste serão salvos em coverage/xml-reports/.

// cypress.json

{
  "reporter": "cypress-sonarqube-reporter",
  "reporterOptions": {
    "overwrite": true,
    "preserveSpecsDir": false,
    "outputDir": "coverage/xml-reports/"
  }
}

Para que todos os .xml de cada teste sejam gerados corretamente, é preciso aplicar a função SpecTitle da lib nos títulos dos describes de todos os arquivos de testes existentes no seu projeto, como no exemplo abaixo:

Observação: se por alguma razão um mesmo arquivo de teste tiver dois ou mais describes que não estejam aninhados, é preciso aplicar o SpecTitle em cada um deles para funcionar corretamente.

// File: cypress/integration/Sample.spec.js
const specTitle = require("cypress-sonarqube-reporter/specTitle");
describe(specTitle("The root suite"), () => {
    it("Test case #1 (must pass)", () => {
        expect(true).to.be.true;
    });
    describe("A sub suite", () => {
        it("Test case #2 (must pass)", () => {
            expect(true).to.be.true;
        });
        it("Test case #3 (must fail)", () => {
            expect(true).to.be.false;
        });
    });
    describe("Another sub suite", () => {
        xit("Test case #4 (must be skipped)", () => {
            expect(true).to.be.false;
        });
        it("Test case #5 (must raise an error)", () => {
            undefined.toString();
        });
    });
});

describe(specTitle("Another root suite"), () => {
    it("Test case #4 (must pass)", () => {
        expect(true).to.be.true;
    });
});

Em seguida é preciso fazer o merge de todos os .xml de cada teste em um arquivo .xml único,  de nome sonar.xml nesse exemplo.

// cypress/plugins/index.js

module.exports = (on, config) => {
  require('@cypress/code-coverage/task')(on, config)
  
  on('after:run', (results) => {
    return require('cypress-sonarqube-reporter/mergeReports')(results, {
      mergeFileName: "sonar.xml"
    })
  })

  return config
}

Posteriormente, basta rodar todos os testes com o comando abaixo e se tudo foi configurado corretamente, o arquivo coverage/xml-reports/sonar.xml será gerado com sucesso. Por fim, crie o arquivo sonar.js com as seguintes informações do seu repositório para o escaneamento e envio dos dados para o SonarQube:

const scanner = require('sonarqube-scanner')

scanner(
  {
    serverUrl : 'http://sonarqube.tecnospeed.local',
    token : '<token gerado no SonarQube para o seu projeto>',
    options: {
      'sonar.projectKey': '<project key do seu projeto>',
      'sonar.projectName': 'nome do seu projeto',
      'sonar.javascript.lcov.reportPaths': 'coverage/lcov.info',
      'sonar.testExecutionReportPaths': 'coverage/xml-reports/sonar.xml',
      'sonar.sources': 'src',
      'sonar.tests': 'cypress/integration'
    }
  },
  () => process.exit()
)

 

Stage de testes no Pipeline do Gitlab

Adicione no .gitignore as pastas criadas pelo sonarscanner e pelas dependências do gerador de cobertura do cypress:

coverage
.scannerwork
.nyc_output

Agora basta adicionar o script de execução dos testes do cypress e do sonar em um pipeline de testes no gitlab:

// .gitlab-ci.yml

stages:
  - test
  
test:
  image: cypress/browsers:node16.5.0-chrome94-ff93
  stage: test
  script:
    - npm set registry http://devdocker.tecnospeed.local:4873/
    - npm install
    - npm run cypress:run
  after_script:
    - node sonar.js

Se tudo correr bem após a execução do pipeline, a página de seu projeto no SonarQube será criada/atualizada com as informações relacionadas a cobertura e total de testes, duplicidades, bugs e etc. como no exemplo da imagem abaixo:

image.png

 

Referências:

https://docs.cypress.io/guides/tooling/code-coverage#Using-NYC

https://github.com/BBE78/cypress-sonarqube-reporter

  • Curtir 4
  • Amei 3
Link to comment
Compartilhe em outros sites

Crie uma conta ou entre para comentar 😀

Você precisa ser um membro para deixar um comentário.

Crie a sua conta

Participe da nossa comunidade, crie sua conta.
É bem rápido!

Criar minha conta agora

Entrar

Você já tem uma conta?
Faça o login agora.

Entrar agora
 Compartilhar



Sobre o Fórum

Este é um fórum para todos que fazem parte
do ecossistema de uma Software House!

Bem-vindo(a) ao fórum da Casa do Desenvolvedor, uma comunidade completa, onde desenvolvedores, software houses, profissionais de marketing, experiência e vendas, fornecedores de soluções, aficionados por inovação e tecnologia podem tirar dúvidas, compartilhar novidades e conhecimento, trocar experiências e até postar uns memes que só nós da tecnologia entendemos 😅

Crie agora sua conta e vamos juntos fortalecer
o desenvolvimento de software no Brasil! 🇧🇷

×
×
  • Create New...