解决没有覆盖率的问题
在sonar-scanner 中的覆盖率可以通过属性来指定 typescript 覆盖率的文件目录
sonar.typescript.lcov.reportPaths
在Angular项目中,可以通过:
ng test --code-coverage --watch=false
来生成 lcov.info 文件,sonar 通过读取这个文件来获取当前项目的覆盖率
在之前由于本人的愚蠢,在本地环境中,获取了 Angular 项目的覆盖率,然后将项目挂载到Jenkins的工作目录中,但是由于 lcov.info 中的文件目录不正确,导致sonar一直获取不到覆盖率。
这里的路径在Jenkins中找不到,所以一直拿不到覆盖率。
解决办法
方法一:在知道Jenkins 目录的情况下,将这里的路径更改为Jenkins的工作目录
当前 Jenkins 的目录为:/data/jenkins/workspace/demo,遂修改如下:
此时在重新构建的就有覆盖率了。
但是这个方法仅限于零时解决一下,不能用于持续化构建获取sonar 扫描结果
方法二:在Jenkins 工作空间中触发测试从而生成正确目录的覆盖率文件
- 修改 Jenkins 的 pipeline script
import groovy.json.JsonSlurperClassic
node {
def appName="demo"; def appVersionCode="13";
sh "sleep 1"
def appCodeSonarDirs = "/data/jenkins/workspace/demo";
def coverSrc = "/data/jenkins/workspace/demo/coverage/lcov.info";
def loginUser="admin";
def loginpPassword="admin";
def projectBaseDir="/data/jenkins/workspace/demo"
stage('Review') {
echo "-----New Stage Start-----TemplateStageId[2]------"
echo "Stage[Review] Start!"
def result = 0;
try {
echo "Stage[Review] start!"
def inventoryUrl = "http://60.205.214.32:9000"
def sonarqubeScannerHome = tool name: 'Bundled', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
withCredentials([usernamePassword(credentialsId: 'Sonar_DevOps_Default', usernameVariable: 'username', passwordVariable: 'password')]) {
sh "npm run test:codeCoverage && ${sonarqubeScannerHome}/bin/sonar-scanner -X -Dsonar.projectBaseDir=${projectBaseDir} -Dsonar.host.url=${inventoryUrl} -Dsonar.login=${loginUser} -Dsonar.password=${loginpPassword} -Dsonar.projectName=${appName} -Dsonar.projectVersion=${appVersionCode} -Dsonar.projectKey=${appName} -Dsonar.sources=${appCodeSonarDirs} -Dsonar.typescript.lcov.reportPaths=${coverSrc}"
}
result = 2
} catch (e) {
result = -1
echo "-----Stage End-----TemplateStageId[-9]-DurationTime[0]-Result[-1]------"
throw e
} finally {
echo "Stage[Review] End!"
}
}
}
此时会先执行npm run test:codeCoverage
生成覆盖率文件目录
这里在package.json 的 script 中配置了test:codeCoverage命令,因为angular/cli 没有全局安装,所以在这里直接执行 ng 命令时会报错,通过执行 npm run test:codeCoverage 来调用的是当前node_modules 安装的angular/cli 。
但是此时又会出现一个问题,就是在jenkins中没有安装chrome , 在拉起chrome会报错。
- 使用 ChromeHeadless
安装插件 puppeteer & karma-chrome-launcher
执行命令:
npm i -D puppeteer karma-chrome-launcher
- 修改 karma 的配置文件
修改项目目录下的 karma.conf.js
process.env.CHROME_BIN = require('puppeteer').executablePath();
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: ['html', 'lcovonly'],
fixWebpackSourcePaths: true,
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadlessCI'],
singleRun: false,
customLaunchers: {
ChromeHeadlessCI: {
base: 'ChromeHeadless',
flags: ['--no-sandbox']
}
},
});
};
然后在 Jenkins 中重新执行就可以了。