Hello Antichesse, tu m'as dit que tu allais peut-être t'intéresser à la remontée du coverage côté Front vers Sonar, donc je te met des infos sur ce que j'ai fait, pour t'aider.
Infos préalables (mais je sais que ça marche avec Angular et depuis Karma 4.1.0) :
Package.json
"devDependencies": {
"@angular-devkit/build-angular": "0.901.0",
"@angular/cli": "9.1.0",
"@angular/compiler-cli": "9.1.0",
"@angular/language-service": "9.1.0",
"@types/jasmine": "3.5.10",
"@types/jasminewd2": "2.0.8",
"@types/node": "12.12.34",
"codelyzer": "5.2.2",
"jasmine-core": "3.5.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.4.1",
"karma-coverage-istanbul-reporter": "2.1.1",
"karma-firefox-launcher": "1.3.0",
"karma-jasmine": "3.0.3",
"karma-jasmine-html-reporter": "1.5.3",
"protractor": "5.4.3",
"ts-node": "8.3.0",
"tslint": "6.1.1",
"typescript": "3.8.3"
},
Alors déjà, je lance mes tests en Firefox Headless.
Extrait de mon fichier Karma.conf.js :
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-firefox-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
...
browsers: ['FirefoxHeadless'],
captureTimeout: 600000,
browserDisconnectTolerance: 3,
browserDisconnectTimeout: 600000,
browserNoActivityTimeout: 600000,
customLaunchers: {
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless', '--no-sandbox']
}
}
...
});
};
Mais surtout, dans le fichier Karma, il y a un élément super important, l'emplacement de stockage de ton coverage :
Karma.conf.js
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/project-name'), **<---- ICI**
reports: ['html', 'lcovonly', 'text-summary'], <--- Lcov doit être inclu aussi !
fixWebpackSourcePaths: true
},
Le dir indique ou le coverage sera stocké. Tu en auras besoin dans ton fichier JenkinsFile. Pour moi, à la racine de mon WORKSPACE, j'aurais un dossier "coverage", qui contient un autre dossier "project-name" contenant le résultat de l'analyse Istanbul-reporter, incluant le coverage.
Voici quelques extraits de mon fichier JenkinsFile, pour montrer les modifs que j'ai du faire :
pipeline {
agent { label 'trololo-pouetpouet' }
stages {
stage('Clone source code') {
steps {
git branch:'${BRANCH_NAME}', credentialsId: gitCredentialsId, url: gitSshUrl
}
}
stage('Test') {
steps {
println " ========== START PLAYING TESTS ========== "
configFileProvider([configFile(fileId: 'npm-npmrc', targetLocation: '/root/.npmrc')]) {
sh "export SASS_BINARY_PATH=${sassBinaryLocation}/${bindingNodeFileName} ; npm run test-prod"
}
stash includes: 'coverage/**/*', name: 'COVERAGE' **<---- Ici, c'est parce que je change d'agent, donc je garde l'output de mon coverage **
}
}
stage('Build') {
steps {
println " ========== START BUILDING DELIVERABLE ========== "
...
}
}
stage('Sonarqube analysis') {
agent {
label 'sonar-scanner-agent-de-ouf'
}
steps {
git branch:'${BRANCH_NAME}', credentialsId: gitCredentialsId, url: gitSshUrl
script {
configFileProvider([configFile(fileId: 'npm-npmrc', targetLocation: '/root/.npmrc')]) {
...
unstash 'COVERAGE' ** <----- je récupère mon output d'analyse incluant mon coverage **
withSonarQubeEnv(sonarEnvName) {
sh "sonar-scanner "+
"-Dsonar.verbose=true "+
"-Dsonar.projectBaseDir=${WORKSPACE} "+
"-Dsonar.projectVersion=${taggedVersion} "+
"-Dsonar.sources=. "+
"-Dsonar.exclusions='**/*.spec.ts, **/*.js, src/test/*'"+ **<---- Ici, j'exclue les tests et le js du coverage et de l'analyse **
"-Dsonar.projectName='${binaryName}' "+
"-Dsonar.projectKey=${binaryName} "+
"-Dsonar.typescript.lcov.reportPaths=${env.WORKSPACE}/coverage/project-name/lcov.info "+ <---- Ici, il faut indiquer le path récupéré depuis le fichier Karma.conf.js, et pointer vers le fichier lcov.info
(env.BRANCH_NAME != 'master' ? "-Dsonar.branch.name=${env.BRANCH_NAME} -X " : "")
}
}
}
}
}
...
}
...
}
Et last, but not least, une petite indication supplémentaire à préciser quand on fait de l'angular :
package.json
"scripts": {
"ng": "ng",
...
"test": "ng test --watch --code-coverage", ** <---- Indiquer que l'on veut l'emission du coverage !**
"test-prod": "npm install && ng test --code-coverage",
"lint": "ng lint",
"e2e": "ng e2e"
},
Note : l'option de script "--code-coverage" peut également être remplacée par l'option de build:
"test": { ** <---- En phase test **
"builder": ...
"options": {
....
"codeCoverage": true, ** <---- Indiquer codeCoverage true **
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss",
....
}
},
Et voilà, ton coverage est dispo sur SONAR !
Si quelque n'est pas clair, n'hésite pas à me le dire !