简体   繁体   English

SonarQube 分析未显示代码覆盖率

[英]SonarQube Analysis not showing code coverage

I have a Jenkins project to do SonarQube analysis of my NodeJS project.我有一个 Jenkins 项目来对我的 NodeJS 项目进行 SonarQube 分析。 I added istanbul as a dependency to my project's package.json .我添加了istanbul作为我项目package.json的依赖项。 In the Jenkins build configuration, first I run a shell script:在 Jenkins 构建配置中,我首先运行一个 shell 脚本:

cd ./project-name
npm install
node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha path-to-unit-tests
node_modules/.bin/istanbul report cobertura
cd ..

This installs the dependencies, runs the tests and generates a code coverage report and generates a cobertura-coverage.xml file.这将安装依赖项、运行测试并生成代码覆盖率报告并生成 cobertura-coverage.xml 文件。

After the shell script, I run a Invoke Standalone SonarQube Analysis with the following properties for code coverage:在 shell 脚本之后,我运行具有以下代码覆盖属性的Invoke Standalone SonarQube Analysis

sonar.java.coveragePlugin=cobertura
sonar.dynamicAnalysis=reuseReports
sonar.cobertura.reportPath=./project-name/coverage/cobertura-coverage.xml

The Jenkins job runs successfully with a SonarQube dashboard describing various things such as the lines of code, technical debt, issues and so on for the project. Jenkins 作业通过 SonarQube 仪表板成功运行,该仪表板描述了项目的各种内容,例如代码行、技术债务、问题等。 But the code coverage for the unit tests doesn't show up on the SonarQube dashboard.但是单元测试的代码覆盖率没有显示在 SonarQube 仪表板上。 I made sure that the dashboard has the Unit Tests widget.我确保仪表板具有单元测试小部件。

Version of SonarQube server: 5.2
Version of JavaScript plguin used on SonarQube: 2.9
Version of Cobertura plugin used on SonarQube: 1.6.3
Version of Cobertura plugin used on Jenkins: 1.9.7
Version of NodeJS plugin used on Jenkins: 0.2.1

I verified that the workspace does have the cobertura-coverage.xml file.我验证了工作区确实有cobertura-coverage.xml文件。 Also checked the build console logs and found no bugs.还检查了构建控制台日志,没有发现错误。 I have also tried pushing the code coverage using LCOV format before:我之前也尝试过使用 LCOV 格式推送代码覆盖率:

sonar.dynamicAnalysis=reuseReports
sonar.javascript.lcov.reportPath=./project-name/coverage/lcov.info

The report doesn't get published to SonarQube even though the coverage report does get generated in Jenkins workspace.即使覆盖率报告确实在 Jenkins 工作区中生成,该报告也不会发布到 SonarQube。 I looked at the workspace contents and verified.我查看了工作区内容并进行了验证。 The console logs show the coverage report getting generated.控制台日志显示生成的覆盖率报告。 Also tried也试过

sonar.dynamicAnalysis=reuseReports
sonar.javascript.lcov.reportPath=project-name/coverage/lcov.info

and

sonar.dynamicAnalysis=reuseReports
sonar.cobertura.reportPath=project-name/coverage/cobertura-coverage.xml

to no avail.无济于事。 I also restarted the Jenkins and SonarQube servers 2 times each.我还分别重新启动了 Jenkins 和 SonarQube 服务器 2 次。 Looked at many similar questions on StackOverflow and elsewhere but didn't find anything that works.在 StackOverflow 和其他地方查看了许多类似的问题,但没有找到任何有效的方法。

If I add a post-build action Publish Cobetura Coverage Report and specify the path to the cobetura-coverage.xml file in the Cobertura xml report pattern field, the code coverage report does get published in Jenkins.如果我添加构建后操作Publish Cobetura Coverage Report并在Cobertura xml report pattern字段中指定 cobetura-coverage.xml 文件的路径,则代码覆盖率报告确实会在 Jenkins 中发布。

Looked at the background task logs in SonarQube and saw an exception.查看SonarQube中的后台任务日志,发现异常。

java.lang.IllegalStateException: Cannot persist sources of project-key:project-name/node_modules/jscs/jscs-browser.js
at     org.sonar.server.computation.step.PersistFileSourcesStep$FileSourceVisitor.visitFile(PersistFileSourcesStep.java:132) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visitNode(DepthTraversalTypeAwareCrawler.java:72) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visit(DepthTraversalTypeAwareCrawler.java:44) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visitChildren(DepthTraversalTypeAwareCrawler.java:91) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visit(DepthTraversalTypeAwareCrawler.java:47) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visitChildren(DepthTraversalTypeAwareCrawler.java:91) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler.visit(DepthTraversalTypeAwareCrawler.java:47) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.step.PersistFileSourcesStep.execute(PersistFileSourcesStep.java:89) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:39) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.taskprocessor.report.ReportTaskProcessor.process(ReportTaskProcessor.java:53) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.taskprocessor.CeWorkerRunnableImpl.executeTask(CeWorkerRunnableImpl.java:78) [sonar-server-5.2.jar:na]
at org.sonar.server.computation.taskprocessor.CeWorkerRunnableImpl.run(CeWorkerRunnableImpl.java:55) [sonar-server-5.2.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_45-internal]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_45-internal]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_45-internal]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_45-internal]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45-internal]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45-internal]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45-internal]
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: com.mysql.jdbc.PacketTooBigException:     Packet for query is too large (7989143 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.
### The error may involve org.sonar.db.source.FileSourceMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO file_sources (project_uuid, file_uuid, created_at, updated_at, binary_data, line_hashes, data_hash,     src_hash, data_type, revision)     VALUES (?, ?, ?,     ?, ?, ?,     ?, ?,?,     ?)
### Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (7989143 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:154) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:141) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) ~[mybatis-3.2.7.jar:3.2.7]
at com.sun.proxy.$Proxy84.insert(Unknown Source) ~[na:na]
at org.sonar.db.source.FileSourceDao.insert(FileSourceDao.java:117) ~[sonar-db-5.2.jar:na]
at org.sonar.server.computation.step.PersistFileSourcesStep$FileSourceVisitor.persistSource(PersistFileSourcesStep.java:160) ~[sonar-server-5.2.jar:na]
at org.sonar.server.computation.step.PersistFileSourcesStep$FileSourceVisitor.visitFile(PersistFileSourcesStep.java:130) ~[sonar-server-5.2.jar:na]
... 18 common frames omitted
Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (7989143 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3540) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2417) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2535) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1911) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1203) ~[mysql-connector-java-5.1.35.jar:5.1.35]
at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) ~[commons-dbcp-1.4.jar:1.4]
at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) ~[commons-dbcp-1.4.jar:1.4]
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.executor.ReuseExecutor.doUpdate(ReuseExecutor.java:50) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71) ~[mybatis-3.2.7.jar:3.2.7]
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152) ~[mybatis-3.2.7.jar:3.2.7]
... 25 common frames omitted

So now I've updated the shell script code coverage generation line to所以现在我已经将 shell 脚本代码覆盖率生成行更新为

node_modules/.bin/istanbul cover -x node_modules ./node_modules/.bin/_mocha path-to-unit-tests

Still getting the exception.仍然得到例外。 Based on max_allowed_packet, I don't have MySQL , I need to bump up the value of MAX_ALLOWED_PACKET in the database settings.基于max_allowed_pa​​cket,我没有 MySQL ,我需要在数据库设置中提高MAX_ALLOWED_PACKET的值。 Just done that and retriggered the Jenkins job for SonarQube analysis.刚刚完成并重新触发 Jenkins 工作以进行 SonarQube 分析。 The exception disappeared.异常消失了。 The background task in SonarQube was successful. SonarQube 中的后台任务成功。 But I still don't see Unit test code coverage in the dashboard.但是我仍然没有在仪表板中看到单元测试代码覆盖率。 There are no other exceptions.没有其他例外。 When I click on 'Configure Widgets' button, the Unit test widget has 'No data' label on it.当我点击“配置小部件”按钮时,单元测试小部件上有“无数据”标签。 When I go back to the dashboard, the Unit test widget disappears.当我返回仪表板时,单元测试小部件消失了。

Any idea what I am missing?知道我缺少什么吗?

The first time (~a year back) when I started exploring "Sonarqube" and while doing set up everything worked fine.第一次(大约一年前)当我开始探索“Sonarqube”并且在设置时一切正常。 I was able to see all the metrics along with " code coverage ".我能够看到所有指标以及“代码覆盖率”。

For that used version was : sonarqube-6.7.5, sonar-scanner: sonar-scanner-3.2.0.1227-macosx对于那个使用的版本是:sonarqube-6.7.5,sonar-scanner:sonar-scanner-3.2.0.1227-macosx

After that, when I tried today for some other project but I struggled almost ~3 hours to identify why code coverage is not being displayed in the sonarqube report though everything is configured properly.在那之后,当我今天尝试其他一些项目时,虽然一切都配置正确,但我花了将近 3 个小时才确定为什么代码覆盖率没有显示在 sonarqube 报告中。

After spending some time I have found below two blog topics which helps me to understand why I was not getting the coverage report.花了一些时间后,我发现了以下两个博客主题,这有助于我理解为什么我没有得到覆盖率报告。

If I read it correctly then it seems that there was a bug where after " lcov " report path was not recognized though it was configured accurately.如果我正确阅读了它,那么似乎存在一个错误,即“ lcov ”报告路径虽然配置准确,但无法识别。

Reference links:参考链接:

unable-to-get-code-coverage-for-javascript javascript 无法获取代码覆盖率

Fix: js-coverage-doesnt-work-anymore 修复:js-coverage-doesnt-work-anymore

Used version: Docker image of sonarqube:8.3.0 & newtmitch/sonar-scanner as a sonar-scanner.使用版本: Sonarqube 的 Docker 镜像:8.3.0 & newtmitch/sonar-scanner 作为声纳扫描仪。

For reference, Dockerfile from my local setup which is used to run the sonar-scanner:作为参考,来自我本地设置的 Dockerfile 用于运行声纳扫描仪:

FROM newtmitch/sonar-scanner AS sonarqube_scan
COPY . /usr/src
RUN ls -list
RUN sonar-scanner \
    -Dsonar.host.url="http://localhost:9000" \
    -Dsonar.projectKey="test-node-app" \
    -Dsonar.projectVersion="1.0" \
    -Dsonar.sources="/usr/src" \
    -Dsonar.language="javascript" \
    -Dsonar.sourceEncoding="UTF-8" \
    -Dsonar.dynamicAnalysis="reuseReports" \
    -Dsonar.javascript.lcov.reportPaths="/usr/src/app/coverage/lcov.info"

I hope someone this helpful!我希望有人有帮助!

Happy learning!快乐学习!

The lcov report publishing worked after I had fixed the exception mentioned in the question.在我修复了问题中提到的异常后,lcov 报告发布工作。 But sometimes, I randomly see another exception.但有时,我会随机看到另一个例外。 Moreover, the Unit test widget on the SonarQube dashboard shows only the Conditionals coverage.此外,SonarQube 仪表板上的单元测试小部件仅显示条件覆盖。 Need to fine tune the solution more.需要进一步微调解决方案。

sonar.dynamicAnalysis=reuseReports
sonar.javascript.lcov.reportPath=project-name/coverage/lcov.info

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM