No pytest coverage displayed in measures

SonarQube Version: 10.4.1, Community Edition
Deployment: Docker

Hi,
I am trying to measure the coverage of my Python project. For this I am using gitlab ci, where first the coverage report is created, and then the sonar scanner analyses the branch.

Extract of gitlab-ci.yml

coverage-backend:
  image:
    name: python:3.10
    entrypoint:
      - "/usr/bin/env"
  stage: test
  only:
    - dev
  services:
    - name: git.tensor-olympus.com:5050/tensor-solutions/hephaestus:database
      alias: db
  script:
    - cp backend/.env-template backend/.env
    - pip3 install -r backend/requirements.txt
    - coverage run -m pytest -v backend/tests/
    - coverage xml -o "reports/coverage.xml"
  artifacts:
    paths:
      - reports/coverage.xml
  allow_failure: false

sonarqube-dev:
  stage: analyze
  only:
    - dev
  image:
    name: sonarsource/sonar-scanner-cli:5.0
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner -Dsonar.projectVersion=$CI_COMMIT_SHA -Dsonar.branch.name=dev
  allow_failure: true

I doublechecked the gitlab artefacts and I can say that the coverage report is there and there are defenity some lines covered.

coverage.xml

<?xml version="1.0" ?>
<coverage version="7.3.2" timestamp="1718369581211" lines-valid="626" lines-covered="427" line-rate="0.6821" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
	<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.3.2 -->
	<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
	<sources>
		<source>/builds/iVeDjymz/0/censored/censored</source>
	</sources>
	<packages>
		<package name="backend" line-rate="0.7681" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/__init__.py" complexity="0" line-rate="0.9231" branch-rate="0">
					<methods/>
					<lines>
						<line number="7" hits="1"/>
						<line number="9" hits="1"/>
						<line number="10" hits="1"/>
						<line number="12" hits="1"/>
						<line number="14" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="19" hits="1"/>
						<line number="25" hits="1"/>
						<line number="27" hits="1"/>
						<line number="28" hits="0"/>
						<line number="30" hits="1"/>
					</lines>
				</class>
				<class name="config.py" filename="backend/config.py" complexity="0" line-rate="0.6875" branch-rate="0">
					<methods/>
					<lines>
						<line number="3" hits="1"/>
						<line number="4" hits="1"/>
						<line number="7" hits="1"/>
						<line number="42" hits="1"/>
						<line number="52" hits="1"/>
						<line number="53" hits="0"/>
						<line number="54" hits="1"/>
						<line number="55" hits="0"/>
						<line number="56" hits="1"/>
						<line number="57" hits="0"/>
						<line number="58" hits="1"/>
						<line number="59" hits="0"/>
						<line number="60" hits="1"/>
						<line number="61" hits="0"/>
						<line number="62" hits="1"/>
						<line number="63" hits="0"/>
						<line number="64" hits="1"/>
						<line number="65" hits="0"/>
						<line number="67" hits="1"/>
						<line number="68" hits="0"/>
						<line number="69" hits="1"/>
						<line number="70" hits="0"/>
						<line number="71" hits="1"/>
						<line number="72" hits="0"/>
						<line number="73" hits="1"/>
						<line number="74" hits="0"/>
						<line number="75" hits="1"/>
						<line number="76" hits="0"/>
						<line number="78" hits="1"/>
						<line number="79" hits="0"/>
						<line number="81" hits="1"/>
						<line number="82" hits="0"/>
						<line number="83" hits="1"/>
						<line number="84" hits="0"/>
						<line number="86" hits="1"/>
						<line number="89" hits="1"/>
						<line number="90" hits="1"/>
						<line number="91" hits="1"/>
						<line number="92" hits="1"/>
						<line number="93" hits="1"/>
						<line number="96" hits="1"/>
						<line number="97" hits="1"/>
						<line number="98" hits="1"/>
						<line number="99" hits="1"/>
						<line number="100" hits="1"/>
						<line number="101" hits="1"/>
						<line number="102" hits="1"/>
						<line number="104" hits="1"/>
					</lines>
				</class>
				<class name="extensions.py" filename="backend/extensions.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines>
						<line number="3" hits="1"/>
						<line number="4" hits="1"/>
						<line number="5" hits="1"/>
						<line number="6" hits="1"/>
						<line number="8" hits="1"/>
						<line number="9" hits="1"/>
						<line number="10" hits="1"/>
						<line number="11" hits="1"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.models" line-rate="0.7828" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/models/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="helper.py" filename="backend/models/helper.py" complexity="0" line-rate="0.5476" branch-rate="0">
					<methods/>
					<lines>
						<line number="3" hits="1"/>
						<line number="4" hits="1"/>
						<line number="5" hits="1"/>
						<line number="8" hits="1"/>
						<line number="16" hits="1"/>
						<line number="18" hits="1"/>
						<line number="21" hits="1"/>
						<line number="24" hits="1"/>
						<line number="25" hits="1"/>
						<line number="26" hits="1"/>
						<line number="27" hits="1"/>
						<line number="28" hits="1"/>
						<line number="31" hits="1"/>
						<line number="32" hits="1"/>
						<line number="35" hits="1"/>
						<line number="38" hits="1"/>
						<line number="39" hits="1"/>
						<line number="40" hits="1"/>
						<line number="43" hits="1"/>
						<line number="55" hits="1"/>
						<line number="64" hits="0"/>
						<line number="65" hits="0"/>
						<line number="67" hits="1"/>
						<line number="81" hits="0"/>
						<line number="82" hits="0"/>
						<line number="83" hits="0"/>
						<line number="84" hits="0"/>
						<line number="88" hits="1"/>
						<line number="102" hits="0"/>
						<line number="103" hits="0"/>
						<line number="104" hits="0"/>
						<line number="105" hits="0"/>
						<line number="106" hits="0"/>
						<line number="107" hits="0"/>
						<line number="108" hits="0"/>
						<line number="109" hits="0"/>
						<line number="112" hits="1"/>
						<line number="126" hits="0"/>
						<line number="127" hits="0"/>
						<line number="128" hits="0"/>
						<line number="131" hits="0"/>
						<line number="132" hits="0"/>
					</lines>
				</class>
				<class name="tool_jobs.py" filename="backend/models/tool_jobs.py" complexity="0" line-rate="0.8485" branch-rate="0">
					<methods/>
					<lines>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="19" hits="1"/>
						<line number="20" hits="1"/>
						<line number="22" hits="1"/>
						<line number="23" hits="1"/>
						<line number="24" hits="1"/>
						<line number="27" hits="1"/>
						<line number="62" hits="1"/>
						<line number="63" hits="1"/>
						<line number="66" hits="1"/>
						<line number="67" hits="1"/>
						<line number="71" hits="1"/>
						<line number="77" hits="1"/>
						<line number="78" hits="1"/>
						<line number="79" hits="1"/>
						<line number="81" hits="1"/>
						<line number="85" hits="1"/>
						<line number="86" hits="1"/>
						<line number="87" hits="1"/>
						<line number="88" hits="1"/>
						<line number="89" hits="1"/>
						<line number="91" hits="1"/>
						<line number="100" hits="1"/>
						<line number="102" hits="1"/>
						<line number="115" hits="1"/>
						<line number="116" hits="0"/>
						<line number="117" hits="0"/>
						<line number="120" hits="1"/>
						<line number="130" hits="1"/>
						<line number="133" hits="1"/>
						<line number="135" hits="1"/>
						<line number="137" hits="1"/>
						<line number="139" hits="0"/>
						<line number="142" hits="1"/>
						<line number="143" hits="1"/>
						<line number="144" hits="1"/>
						<line number="146" hits="1"/>
						<line number="148" hits="1"/>
						<line number="149" hits="0"/>
						<line number="152" hits="1"/>
						<line number="153" hits="1"/>
						<line number="154" hits="1"/>
						<line number="156" hits="1"/>
						<line number="158" hits="1"/>
						<line number="159" hits="0"/>
						<line number="162" hits="1"/>
						<line number="163" hits="1"/>
						<line number="164" hits="1"/>
						<line number="170" hits="1"/>
						<line number="173" hits="1"/>
						<line number="174" hits="1"/>
						<line number="180" hits="1"/>
						<line number="183" hits="1"/>
						<line number="185" hits="1"/>
						<line number="194" hits="0"/>
						<line number="196" hits="1"/>
						<line number="209" hits="0"/>
						<line number="210" hits="0"/>
						<line number="211" hits="0"/>
						<line number="214" hits="1"/>
						<line number="215" hits="1"/>
						<line number="216" hits="1"/>
						<line number="218" hits="1"/>
						<line number="219" hits="0"/>
					</lines>
				</class>
				<class name="tools.py" filename="backend/models/tools.py" complexity="0" line-rate="0.8676" branch-rate="0">
					<methods/>
					<lines>
						<line number="15" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="19" hits="1"/>
						<line number="20" hits="1"/>
						<line number="21" hits="1"/>
						<line number="24" hits="1"/>
						<line number="25" hits="1"/>
						<line number="26" hits="1"/>
						<line number="27" hits="1"/>
						<line number="28" hits="1"/>
						<line number="29" hits="1"/>
						<line number="30" hits="1"/>
						<line number="31" hits="1"/>
						<line number="32" hits="1"/>
						<line number="33" hits="1"/>
						<line number="35" hits="1"/>
						<line number="36" hits="1"/>
						<line number="41" hits="1"/>
						<line number="42" hits="1"/>
						<line number="44" hits="1"/>
						<line number="53" hits="1"/>
						<line number="55" hits="1"/>
						<line number="68" hits="1"/>
						<line number="69" hits="0"/>
						<line number="70" hits="0"/>
						<line number="73" hits="1"/>
						<line number="74" hits="1"/>
						<line number="75" hits="1"/>
						<line number="76" hits="1"/>
						<line number="78" hits="1"/>
						<line number="79" hits="1"/>
						<line number="80" hits="1"/>
						<line number="82" hits="1"/>
						<line number="83" hits="0"/>
						<line number="86" hits="1"/>
						<line number="87" hits="1"/>
						<line number="88" hits="1"/>
						<line number="89" hits="1"/>
						<line number="102" hits="1"/>
						<line number="103" hits="1"/>
						<line number="104" hits="1"/>
						<line number="106" hits="1"/>
						<line number="107" hits="0"/>
						<line number="110" hits="1"/>
						<line number="111" hits="1"/>
						<line number="112" hits="1"/>
						<line number="115" hits="1"/>
						<line number="116" hits="1"/>
						<line number="117" hits="1"/>
						<line number="118" hits="1"/>
						<line number="119" hits="1"/>
						<line number="120" hits="1"/>
						<line number="125" hits="1"/>
						<line number="127" hits="1"/>
						<line number="136" hits="0"/>
						<line number="138" hits="1"/>
						<line number="151" hits="0"/>
						<line number="152" hits="0"/>
						<line number="153" hits="0"/>
						<line number="156" hits="1"/>
						<line number="157" hits="1"/>
						<line number="158" hits="1"/>
						<line number="160" hits="1"/>
						<line number="161" hits="1"/>
						<line number="163" hits="1"/>
						<line number="164" hits="0"/>
					</lines>
				</class>
				<class name="user.py" filename="backend/models/user.py" complexity="0" line-rate="0.7727" branch-rate="0">
					<methods/>
					<lines>
						<line number="15" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="21" hits="1"/>
						<line number="22" hits="1"/>
						<line number="23" hits="1"/>
						<line number="24" hits="1"/>
						<line number="25" hits="1"/>
						<line number="26" hits="1"/>
						<line number="28" hits="1"/>
						<line number="29" hits="1"/>
						<line number="35" hits="1"/>
						<line number="44" hits="0"/>
						<line number="46" hits="1"/>
						<line number="59" hits="0"/>
						<line number="60" hits="0"/>
						<line number="61" hits="0"/>
						<line number="64" hits="1"/>
						<line number="65" hits="1"/>
						<line number="66" hits="1"/>
						<line number="68" hits="1"/>
						<line number="69" hits="0"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.services" line-rate="1" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/services/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
			</classes>
		</package>
		<package name="backend.services.scheduler" line-rate="1" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/services/scheduler/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="scheduler.py" filename="backend/services/scheduler/scheduler.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines>
						<line number="6" hits="1"/>
						<line number="10" hits="1"/>
						<line number="11" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="15" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="20" hits="1"/>
						<line number="30" hits="1"/>
						<line number="31" hits="1"/>
						<line number="33" hits="1"/>
						<line number="45" hits="1"/>
						<line number="46" hits="1"/>
						<line number="51" hits="1"/>
						<line number="52" hits="1"/>
						<line number="55" hits="1"/>
						<line number="56" hits="1"/>
						<line number="57" hits="1"/>
						<line number="60" hits="1"/>
						<line number="62" hits="1"/>
						<line number="76" hits="1"/>
						<line number="83" hits="1"/>
						<line number="84" hits="1"/>
						<line number="85" hits="1"/>
						<line number="86" hits="1"/>
						<line number="88" hits="1"/>
						<line number="97" hits="1"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.services.scheduler.slurm" line-rate="0.4696" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/services/scheduler/slurm/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="slurm_control.py" filename="backend/services/scheduler/slurm/slurm_control.py" complexity="0" line-rate="0.3297" branch-rate="0">
					<methods/>
					<lines>
						<line number="5" hits="1"/>
						<line number="12" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="20" hits="1"/>
						<line number="23" hits="1"/>
						<line number="37" hits="1"/>
						<line number="38" hits="1"/>
						<line number="39" hits="1"/>
						<line number="40" hits="1"/>
						<line number="41" hits="1"/>
						<line number="42" hits="1"/>
						<line number="43" hits="1"/>
						<line number="44" hits="1"/>
						<line number="46" hits="1"/>
						<line number="55" hits="0"/>
						<line number="56" hits="0"/>
						<line number="57" hits="0"/>
						<line number="61" hits="0"/>
						<line number="62" hits="0"/>
						<line number="67" hits="0"/>
						<line number="71" hits="0"/>
						<line number="72" hits="0"/>
						<line number="74" hits="1"/>
						<line number="90" hits="0"/>
						<line number="92" hits="0"/>
						<line number="93" hits="0"/>
						<line number="94" hits="0"/>
						<line number="98" hits="0"/>
						<line number="99" hits="0"/>
						<line number="101" hits="0"/>
						<line number="105" hits="0"/>
						<line number="107" hits="0"/>
						<line number="109" hits="1"/>
						<line number="125" hits="0"/>
						<line number="126" hits="0"/>
						<line number="127" hits="0"/>
						<line number="128" hits="0"/>
						<line number="129" hits="0"/>
						<line number="131" hits="0"/>
						<line number="135" hits="0"/>
						<line number="136" hits="0"/>
						<line number="138" hits="1"/>
						<line number="152" hits="0"/>
						<line number="157" hits="1"/>
						<line number="172" hits="0"/>
						<line number="178" hits="1"/>
						<line number="192" hits="0"/>
						<line number="197" hits="1"/>
						<line number="211" hits="0"/>
						<line number="216" hits="1"/>
						<line number="231" hits="0"/>
						<line number="232" hits="0"/>
						<line number="234" hits="0"/>
						<line number="235" hits="0"/>
						<line number="238" hits="0"/>
						<line number="239" hits="0"/>
						<line number="241" hits="1"/>
						<line number="255" hits="0"/>
						<line number="256" hits="0"/>
						<line number="257" hits="0"/>
						<line number="258" hits="0"/>
						<line number="259" hits="0"/>
						<line number="261" hits="1"/>
						<line number="275" hits="0"/>
						<line number="276" hits="0"/>
						<line number="277" hits="0"/>
						<line number="278" hits="0"/>
						<line number="279" hits="0"/>
						<line number="281" hits="1"/>
						<line number="290" hits="0"/>
						<line number="292" hits="0"/>
						<line number="296" hits="1"/>
						<line number="307" hits="0"/>
						<line number="308" hits="0"/>
						<line number="310" hits="1"/>
						<line number="323" hits="0"/>
						<line number="324" hits="0"/>
						<line number="326" hits="0"/>
						<line number="327" hits="0"/>
						<line number="328" hits="0"/>
						<line number="329" hits="0"/>
						<line number="330" hits="0"/>
						<line number="331" hits="0"/>
						<line number="333" hits="1"/>
						<line number="346" hits="0"/>
						<line number="347" hits="0"/>
						<line number="348" hits="0"/>
						<line number="349" hits="0"/>
					</lines>
				</class>
				<class name="slurm_script_generator.py" filename="backend/services/scheduler/slurm/slurm_script_generator.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines>
						<line number="5" hits="1"/>
						<line number="12" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="17" hits="1"/>
						<line number="51" hits="1"/>
						<line number="58" hits="1"/>
						<line number="61" hits="1"/>
						<line number="62" hits="1"/>
						<line number="63" hits="1"/>
						<line number="64" hits="1"/>
						<line number="65" hits="1"/>
						<line number="66" hits="1"/>
						<line number="69" hits="1"/>
						<line number="70" hits="1"/>
						<line number="71" hits="1"/>
						<line number="72" hits="1"/>
						<line number="73" hits="1"/>
						<line number="76" hits="1"/>
						<line number="78" hits="1"/>
						<line number="87" hits="1"/>
						<line number="88" hits="1"/>
						<line number="110" hits="1"/>
						<line number="111" hits="1"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.tests" line-rate="1" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/tests/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
			</classes>
		</package>
		<package name="backend.tests.services" line-rate="1" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/tests/services/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
			</classes>
		</package>
		<package name="backend.tests.services.scheduler" line-rate="0.9351" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/tests/services/scheduler/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="test_scheduler.py" filename="backend/tests/services/scheduler/test_scheduler.py" complexity="0" line-rate="0.9351" branch-rate="0">
					<methods/>
					<lines>
						<line number="1" hits="1"/>
						<line number="2" hits="1"/>
						<line number="4" hits="1"/>
						<line number="5" hits="1"/>
						<line number="6" hits="1"/>
						<line number="7" hits="1"/>
						<line number="8" hits="1"/>
						<line number="11" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="15" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="19" hits="1"/>
						<line number="21" hits="1"/>
						<line number="22" hits="1"/>
						<line number="25" hits="1"/>
						<line number="28" hits="1"/>
						<line number="35" hits="1"/>
						<line number="37" hits="1"/>
						<line number="38" hits="1"/>
						<line number="39" hits="1"/>
						<line number="41" hits="1"/>
						<line number="42" hits="1"/>
						<line number="45" hits="1"/>
						<line number="48" hits="1"/>
						<line number="49" hits="1"/>
						<line number="52" hits="1"/>
						<line number="54" hits="1"/>
						<line number="55" hits="1"/>
						<line number="56" hits="1"/>
						<line number="58" hits="1"/>
						<line number="59" hits="1"/>
						<line number="62" hits="1"/>
						<line number="65" hits="1"/>
						<line number="66" hits="1"/>
						<line number="69" hits="1"/>
						<line number="71" hits="1"/>
						<line number="72" hits="1"/>
						<line number="73" hits="1"/>
						<line number="74" hits="1"/>
						<line number="75" hits="1"/>
						<line number="76" hits="1"/>
						<line number="77" hits="1"/>
						<line number="79" hits="1"/>
						<line number="80" hits="1"/>
						<line number="81" hits="1"/>
						<line number="84" hits="1"/>
						<line number="87" hits="1"/>
						<line number="88" hits="1"/>
						<line number="92" hits="1"/>
						<line number="93" hits="1"/>
						<line number="96" hits="1"/>
						<line number="101" hits="1"/>
						<line number="103" hits="1"/>
						<line number="104" hits="1"/>
						<line number="105" hits="1"/>
						<line number="106" hits="1"/>
						<line number="107" hits="1"/>
						<line number="108" hits="1"/>
						<line number="109" hits="1"/>
						<line number="111" hits="1"/>
						<line number="112" hits="1"/>
						<line number="113" hits="1"/>
						<line number="116" hits="1"/>
						<line number="119" hits="1"/>
						<line number="120" hits="1"/>
						<line number="122" hits="1"/>
						<line number="123" hits="1"/>
						<line number="126" hits="1"/>
						<line number="131" hits="1"/>
						<line number="132" hits="0"/>
						<line number="133" hits="0"/>
						<line number="134" hits="0"/>
						<line number="135" hits="0"/>
						<line number="136" hits="0"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.tests.services.scheduler.slurm" line-rate="0.4599" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="backend/tests/services/scheduler/slurm/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="test_slurm_control.py" filename="backend/tests/services/scheduler/slurm/test_slurm_control.py" complexity="0" line-rate="0.3039" branch-rate="0">
					<methods/>
					<lines>
						<line number="6" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="15" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="20" hits="1"/>
						<line number="23" hits="1"/>
						<line number="24" hits="1"/>
						<line number="51" hits="1"/>
						<line number="52" hits="1"/>
						<line number="53" hits="1"/>
						<line number="55" hits="0"/>
						<line number="56" hits="0"/>
						<line number="59" hits="0"/>
						<line number="62" hits="0"/>
						<line number="63" hits="0"/>
						<line number="66" hits="0"/>
						<line number="67" hits="0"/>
						<line number="69" hits="0"/>
						<line number="74" hits="1"/>
						<line number="75" hits="1"/>
						<line number="76" hits="1"/>
						<line number="78" hits="0"/>
						<line number="81" hits="0"/>
						<line number="82" hits="0"/>
						<line number="85" hits="0"/>
						<line number="86" hits="0"/>
						<line number="87" hits="0"/>
						<line number="88" hits="0"/>
						<line number="91" hits="1"/>
						<line number="92" hits="1"/>
						<line number="93" hits="1"/>
						<line number="95" hits="0"/>
						<line number="98" hits="0"/>
						<line number="99" hits="0"/>
						<line number="102" hits="0"/>
						<line number="103" hits="0"/>
						<line number="104" hits="0"/>
						<line number="105" hits="0"/>
						<line number="108" hits="1"/>
						<line number="109" hits="1"/>
						<line number="110" hits="1"/>
						<line number="112" hits="0"/>
						<line number="115" hits="0"/>
						<line number="118" hits="0"/>
						<line number="119" hits="0"/>
						<line number="122" hits="0"/>
						<line number="127" hits="1"/>
						<line number="128" hits="1"/>
						<line number="129" hits="1"/>
						<line number="131" hits="0"/>
						<line number="134" hits="0"/>
						<line number="137" hits="0"/>
						<line number="138" hits="0"/>
						<line number="139" hits="0"/>
						<line number="140" hits="0"/>
						<line number="143" hits="0"/>
						<line number="148" hits="1"/>
						<line number="149" hits="1"/>
						<line number="150" hits="1"/>
						<line number="152" hits="0"/>
						<line number="153" hits="0"/>
						<line number="154" hits="0"/>
						<line number="155" hits="0"/>
						<line number="156" hits="0"/>
						<line number="159" hits="0"/>
						<line number="162" hits="0"/>
						<line number="163" hits="0"/>
						<line number="164" hits="0"/>
						<line number="165" hits="0"/>
						<line number="166" hits="0"/>
						<line number="167" hits="0"/>
						<line number="168" hits="0"/>
						<line number="169" hits="0"/>
						<line number="172" hits="0"/>
						<line number="173" hits="0"/>
						<line number="178" hits="1"/>
						<line number="179" hits="1"/>
						<line number="180" hits="1"/>
						<line number="182" hits="0"/>
						<line number="183" hits="0"/>
						<line number="186" hits="0"/>
						<line number="187" hits="0"/>
						<line number="190" hits="0"/>
						<line number="191" hits="0"/>
						<line number="194" hits="0"/>
						<line number="198" hits="0"/>
						<line number="199" hits="0"/>
						<line number="200" hits="0"/>
						<line number="205" hits="1"/>
						<line number="206" hits="0"/>
						<line number="207" hits="0"/>
						<line number="208" hits="0"/>
						<line number="209" hits="0"/>
						<line number="210" hits="0"/>
						<line number="211" hits="0"/>
						<line number="212" hits="0"/>
						<line number="213" hits="0"/>
						<line number="214" hits="0"/>
						<line number="215" hits="0"/>
						<line number="216" hits="0"/>
					</lines>
				</class>
				<class name="test_slurm_script_generator.py" filename="backend/tests/services/scheduler/slurm/test_slurm_script_generator.py" complexity="0" line-rate="0.9143" branch-rate="0">
					<methods/>
					<lines>
						<line number="6" hits="1"/>
						<line number="12" hits="1"/>
						<line number="13" hits="1"/>
						<line number="15" hits="1"/>
						<line number="16" hits="1"/>
						<line number="17" hits="1"/>
						<line number="18" hits="1"/>
						<line number="19" hits="1"/>
						<line number="22" hits="1"/>
						<line number="24" hits="1"/>
						<line number="25" hits="1"/>
						<line number="27" hits="1"/>
						<line number="50" hits="1"/>
						<line number="51" hits="1"/>
						<line number="52" hits="1"/>
						<line number="53" hits="1"/>
						<line number="56" hits="1"/>
						<line number="58" hits="1"/>
						<line number="59" hits="1"/>
						<line number="60" hits="1"/>
						<line number="61" hits="1"/>
						<line number="63" hits="1"/>
						<line number="64" hits="1"/>
						<line number="66" hits="1"/>
						<line number="67" hits="1"/>
						<line number="68" hits="1"/>
						<line number="69" hits="1"/>
						<line number="72" hits="1"/>
						<line number="75" hits="1"/>
						<line number="78" hits="1"/>
						<line number="79" hits="1"/>
						<line number="82" hits="1"/>
						<line number="83" hits="0"/>
						<line number="84" hits="0"/>
						<line number="85" hits="0"/>
					</lines>
				</class>
			</classes>
		</package>
		<package name="backend.tools" line-rate="1" branch-rate="0" complexity="0">
			<classes>
				<class name="config.py" filename="backend/tools/config.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines>
						<line number="1" hits="1"/>
						<line number="3" hits="1"/>
					</lines>
				</class>
			</classes>
		</package>
	</packages>
</coverage>

I have also added the reports path to the sonar-project.properties file.

sonar-project.properties

sonar.projectKey=censored
sonar.qualitygate.wait=true
sonar.verbose=true

sonar.python.coverage.reportPaths=reports/coverage.xml
sonar.python.ruff.reportPaths=reports/ruff-report.json
sonar.eslint.reportPaths=reports/eslint-report.json
sonar.typescript.lcov.reportPaths=reports/lcov.info

sonar.coverage.exclusions=**\*spec.ts
#sonar.tests=frontend/src
#sonar.test.inclusions=frontend/**/*.spec.ts

To double-check that this was the correct path and that the Python coverage analysis was taking place, I also checked the logs.
sonar runner logs extract

12:54:49.564 INFO: The Python analyzer was able to leverage cached data from previous analyses for 0 out of 53 files. These files were not parsed.
12:54:49.564 INFO: Sensor Python Sensor [python] (done) | time=2263ms
12:54:49.564 INFO: Sensor Cobertura Sensor for Python coverage [python]
12:54:49.564 DEBUG: Using pattern 'reports/coverage.xml' to find reports
12:54:49.581 INFO: Python test coverage
12:54:49.582 INFO: Parsing report '/builds/ky9phFW7/0/censored/censored/reports/coverage.xml'
12:54:49.616 INFO: Sensor Cobertura Sensor for Python coverage [python] (done) | time=52ms

As you can see, the coverage report is found and the analysis is executed successfully without any error message. However, there is still not a single line covered in sonarqube.

As you can see, I also did a similar configuration for the angular part of the project. Everything works fine there.

Do you know why the coverage for the Python part of the project is still at 0% or do you have any idea what could be wrong here? I would be grateful for any advice :slight_smile:

Thanks!

Hi @dabogdan,

Thank you for reaching out to us!

I was wondering if the issue could be due to discrepancies between the file path during the Sonar analysis and the coverage. Have you tried setting the relative_file property to True when running the coverage?
This would require a few modifications to your script as you will need to set this property in a .coveragerc file. You would need as well to set the source property in the .coveragerc file. You can find here a simple set up with tox.

If this does not work, you could also try printing debug logs. When running the analysis, provide the -X argument. For your script, it would be:
sonar-scanner -Dsonar.projectVersion=$CI_COMMIT_SHA -Dsonar.branch.name=dev -X.
This may give you a better idea of what the issue could be.
I hope this helps.

Best regards,

David

Hi,

I changed the project structure to use tox. I also set the parameters you mentioned regarding the relative file paths.

Now it works as desired, thank you. :+1: