Python Cobertura coverage sensor does not resolve <source> paths relative to sonar.projectBaseDir

Must-share information (formatted with Markdown):

  • which versions are you using (SonarQube Server / Community Build, Scanner, Plugin, and any relevant extension)
    Enterprise Edition v2026.1.2 (121356)

  • how is SonarQube deployed:
    Docker

  • what are you trying to achieve:
    trying to make the scanner to respect the sonar.projectBaseDir configuration when parsing the <source> section of the coverage.xml like it does with every other path.

  • what have you tried so far to achieve this:

    docker run -it --rm --env-file .env -v “./:/app” sonarsource/sonar-scanner-cli -Dsonar.projectBaseDir=/app/.tests/resources/python-app -Dsonar.python.version=3.14 -Dsonar.projectKey=my-app -Dsonar.source=my_app -Dsonar.python.coverage.reportPaths=coverage.xml

    When running this command every path is resolved relatively to the sonar.projectBaseDir path, which is the correct behaviour.

    However the relative path from the coverage.xml file:

    <sources>
    <source>my_app</source>
    </sources>

    Is not correctly resolved as a relative path but rather as an absolute path and the scanner throws a warning like the below and ignores the coverage:

    09:01:36.750 INFO Sensor Cobertura Sensor for Python coverage [python]
    09:01:36.841 INFO Python test coverage
    09:01:36.843 INFO Parsing report ‘/app/.tests/resources/python-app/coverage.xml’
    09:01:36.880 WARN Invalid directory path in ‘source’ element: my_app
    09:01:36.881 ERROR Cannot resolve the file path ‘__init__.py’ of the coverage report, the file does not exist in all ‘source’.
    09:01:36.882 ERROR Cannot resolve 2 file paths, ignoring coverage measures for those files
    09:01:36.882 INFO Sensor Cobertura Sensor for Python coverage [python] (done) | time=133ms

    As a workaround I can hack the coverage.xml file and replace the path with something like:
    <source>/app/.tests/resources/python-app/my_app</source>

    And then the report is correctly parsed:

    09:04:30.787 INFO Sensor Cobertura Sensor for Python coverage [python]
    09:04:30.873 INFO Python test coverage
    09:04:30.875 INFO Parsing report ‘/app/.tests/resources/python-app/coverage.xml’
    09:04:30.940 INFO Sensor Cobertura Sensor for Python coverage [python] (done) | time=153ms

    However this solution is pretty much a hack and is counterintuitive as every other path setting is correctly resolved against the base directory setting.

    Please let me know if this is something that you are planning to fix!

    Thank you!

Hi,

Welcome to the community!

Both of these point to the same place. So you’ve told it to look within my_app for a my_app subdirectory. Explicitly, your coverage report points to my_app/my_app. And I’m guessing that doesn’t actually exist.

 
Ann

Hi Ann,

I don’t think that’s the problem because it works if the projectBaseDir is the repository root, and also it works when the path is absolute instead of relative like I mentioned: <source>/app/.tests/resources/python-app/my_app</source>

Therefore I’m pretty confindent that the Cobertura sensor is not respecting the sonar.projectBaseDirsetting.

Which is kind of counterintuitive compared to everything else, and the official docs also instruct to use relative paths: Python test coverage | SonarQube Server | Sonar Documentation

[coverage:run]
relative_files = True

So in the light of this I’m even more confused why should I replace the relative path with the absolute path in my actual coverage.xml

Hi,

Okay. I’ve flagged this for the language experts.

 
Ann

Much appreciated Ann!