Search code examples
pythoncode-coveragesonarcloudsonarscanner

CodeCoverage not showing in SonarCloud in a Python project


I'm trying to include the codecoverage from my Python project.

First I executed the command py.test --cov=tests/ --cov-report xml:cov/coverage.xml to run the tests and report to cov/coverage.xml

My sonar-project.properties file:

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

After executing the sonar-scanner command sonar-scanner -Dsonar.organization=****** -Dsonar.projectKey=****** -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=********* the code coverage is not included.

In the logs I see it's looking for sonar.coverage.jacoco.xmlReportPaths. Anybody an idea what I'm doing wrong here?

EDIT:

These lines of logs are maybe useful:

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

After adding the line sonar.python.xunit.reportPath=cov/coverage.xml in the sonar-project.properties file, the logs returned this:

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

After adding the line sonar.coverage.jacoco.xmlReportPaths=cov/coverage.xml in the sonar-project.properties file, the logs returned this with an error:

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)

Solution

  • The contents of the coverage.xml file turned out not to be good I think. By running the command coverage run -m pytest -rap --junitxml coverage.xml and afterwards the command coverage xml -i fixed the issue for me. The coverage.xml file is way bigger than the file before.

    My sonar-project.properties file looks like this now:

    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
    

    And this is the sonar-scanner command I'm running:

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