CodeCoverage 未显示在 Python 项目的 SonarCloud 中

Posted

技术标签:

【中文标题】CodeCoverage 未显示在 Python 项目的 SonarCloud 中【英文标题】:CodeCoverage not showing in SonarCloud in a Python project 【发布时间】:2021-12-27 21:02:08 【问题描述】:

我正在尝试从我的 Python 项目中包含代码覆盖。

首先我执行命令py.test --cov=tests/ --cov-report xml:cov/coverage.xml 运行测试并报告给cov/coverage.xml

我的 sonar-project.properties 文件:

sonar.exclusions=tests/**
sonar.python.coverage.reportPaths=cov/coverage.xml
sonar.python.xunit.reportPath=cov/coverage.xml # added this later, see below for the logs
sonar.verbose=true
sonar.python.version=3.8.2

执行 sonar-scanner 命令sonar-scanner -Dsonar.organization=****** -Dsonar.projectKey=****** -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=********* 后,代码覆盖率不包括在内。

在日志中我看到它正在寻找sonar.coverage.jacoco.xmlReportPaths。有人知道我在这里做错了什么吗?

编辑:

这些日志行可能有用:

11:56:11.571 DEBUG: Using pattern 'cov/coverage.xml' to find reports
11:56:11.687 INFO: Python test coverage
11:56:11.689 INFO: Parsing report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
11:56:11.750 INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=180ms
11:56:11.750 INFO: Sensor PythonXUnitSensor [python]
11:56:11.751 DEBUG: Using pattern 'xunit-reports/xunit-result-*.xml' to find reports
11:56:11.859 DEBUG: No report was found for sonar.python.xunit.reportPath using default pattern xunit-reports/xunit-result-*.xml
11:56:11.859 INFO: Sensor PythonXUnitSensor [python] (done) | time=109ms
11:56:11.859 INFO: Sensor JaCoCo XML Report Importer [jacoco]
11:56:11.861 INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
11:56:11.862 INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer

sonar-project.properties 文件中添加sonar.python.xunit.reportPath=cov/coverage.xml 行后,日志返回如下:

12:05:15.803 DEBUG: Using pattern 'cov/coverage.xml' to find reports
12:05:15.903 INFO: Python test coverage
12:05:15.905 INFO: Parsing report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
12:05:15.961 INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=159ms
12:05:15.962 INFO: Sensor PythonXUnitSensor [python]
12:05:15.962 DEBUG: Using pattern 'cov/coverage.xml' to find reports
12:05:16.044 INFO: Processing report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
12:05:16.044 INFO: Sensor PythonXUnitSensor [python] (done) | time=82ms
12:05:16.045 INFO: Sensor JaCoCo XML Report Importer [jacoco]
12:05:16.047 INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
12:05:16.047 INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer
12:05:16.048 INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms

sonar-project.properties 文件中添加行sonar.coverage.jacoco.xmlReportPaths=cov/coverage.xml 后,日志返回此错误:

19:05:32.505 INFO: Sensor Python Sensor [python] (done) | time=4495ms
19:05:32.506 INFO: Sensor Cobertura Sensor for Python coverage [python]
19:05:32.506 DEBUG: Using pattern 'cov/coverage.xml' to find reports
19:05:32.814 INFO: Python test coverage
19:05:32.817 INFO: Parsing report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
19:05:32.899 DEBUG: Saving coverage measures for file 'tests/unit_tests/add_test.py'
19:05:32.904 DEBUG: Saving coverage measures for file 'tests/unit_tests/__init__.py'
19:05:32.905 DEBUG: Saving coverage measures for file 'tests/unit_tests/base_test.py'
19:05:32.905 DEBUG: Saving coverage measures for file 'tests/unit_tests/bot_test.py'
19:05:32.906 DEBUG: Saving coverage measures for file 'tests/__init__.py'
19:05:32.906 INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=400ms
19:05:32.906 INFO: Sensor PythonXUnitSensor [python]
19:05:32.906 DEBUG: Using pattern 'cov/coverage.xml' to find reports
19:05:32.998 INFO: Processing report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
19:05:32.998 INFO: Sensor PythonXUnitSensor [python] (done) | time=92ms
19:05:32.999 INFO: Sensor JaCoCo XML Report Importer [jacoco]
19:05:33.001 INFO: Importing 1 report(s). Turn your logs in debug mode in order to see the exhaustive list.
19:05:33.001 DEBUG: Reading report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml'
19:05:33.012 ERROR: Coverage report '/Users/lucasscheepers/Desktop/Lucas/School/Semester 8 - Stage IND/3. Implementation/ChatOps bot/cov/coverage.xml' could not be read/imported. Error: 
java.lang.IllegalStateException: Invalid report: expected to find 'line' within a 'sourcefile' at line 26 column 7
    at org.sonar.plugins.jacoco.XmlReportParser.parse(XmlReportParser.java:89)
    at org.sonar.plugins.jacoco.JacocoSensor.importReport(JacocoSensor.java:70)
    at org.sonar.plugins.jacoco.JacocoSensor.importReports(JacocoSensor.java:62)
    at org.sonar.plugins.jacoco.JacocoSensor.execute(JacocoSensor.java:47)
    at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:62)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:75)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:48)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:66)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:48)
    at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:64)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
    at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:440)
    at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:436)
    at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:394)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
    at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:128)
    at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
    at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
    at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:58)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:52)
    at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
    at com.sun.proxy.$Proxy0.execute(Unknown Source)
    at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
    at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
    at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
    at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
    at org.sonarsource.scanner.cli.Main.main(Main.java:61)

【问题讨论】:

【参考方案1】:

截至今天,coverage.py 不支持 Sonarqube:https://github.com/nedbat/coveragepy/issues/1033

你能尝试在那个问题上提到的实验,并在那里报告发生了什么吗?也许在这里可以轻松进行调整。

【讨论】:

嗯我不明白coveragepy存储库与此有什么关系,因为我没有使用它。我不确定我明白了。另外我使用的是 SonarCloud 而不是 SonarQube,也许那里有区别?阅读他们的文档,我会说他们支持这一点:sonarcloud.io/documentation/enriching/coverage 你指的是他的包裹:coverage.readthedocs.io/en/6.1.2。但我正在使用这个包:pytest-cov.readthedocs.io/en/latest/reporting.html 我添加了一些可能对这个案例有用的日志 pytest-cov插件使用coverage.py进行实测。 您链接到的文档说您可以将sonar.python.coverage.reportPaths 设置为指向您拥有的 XML 报告。【参考方案2】:

我认为coverage.xml 文件的内容并不好。通过运行命令coverage run -m pytest -rap --junitxml coverage.xml 然后运行命令coverage xml -i 为我解决了这个问题。 coverage.xml 文件比之前的文件大很多。

我的sonar-project.properties 文件现在看起来像这样:

sonar.exclusions=sonar-scanner-3.3.0.1492-linux/jre/**, tests/**, bot.py
sonar.python.coverage.reportPaths=./coverage.xml
sonar.python.version=3.8.2

这是我正在运行的 sonar-scanner 命令:

sonar-scanner \                                     
  -Dsonar.organization=****** \
  -Dsonar.projectKey=****** \
  -Dsonar.sources=. \
  -Dsonar.host.url=https://sonarcloud.io \
  -Dsonar.login=******

【讨论】:

以上是关于CodeCoverage 未显示在 Python 项目的 SonarCloud 中的主要内容,如果未能解决你的问题,请参考以下文章

dyninst codecoverage

Visual PHPUnit 内部错误,打开失败需要“PHP/CodeCoverage/Filter.php”

为啥 codecoverage 要我覆盖定义变量?

如何让 Sonar 忽略 codeCoverage 指标的某些类?

使用具有多个目标的 CodeCoverage.cmake 进行代码覆盖率分析

Python 线程名称未显示在 ps 或 htop 上