Send Unit Tests report and coverage to Sonarqube

Sonarqube is a code quality inspection tool able to detect bugs, security vulnerabilities and various patterns of code smells. It is highly integrated with Maven and out of the box Java tools but if your are the DevOps guy of a team working on a python project, lost in the middle of Java projects, you might ask yourself: how can I keep my pipeline on tracks. If you are using pytest to run your tests, good news: sending coverage and reports in a Sonarqube friendly format will be fairly easy.

Project setting

I won't go into the details on how to set things server side. Concerning your project, I'll assume the following structure (adapt to your needs)

your_project/
    some_package/
        ...
    __main__.py
tests/
    some_test.py
sonar-project.properties

You should thus add the following sonar-project.properties file at the root of the repository.

sonar.host.url=https://sonar.somewhere.com:8200
sonar.projectKey=some_key
sonar.projectName=some_project
sonar.projectVersion=1.0.0
sonar.sources=your_project
sonar.sources=tests
sonar.language=py
sonar.sourceEncoding=UTF-8
# Test Results
sonar.python.xunit.reportPath=pytest.xml
# Coverage
sonar.python.coverage.reportPaths=coverage.xml

Edit the Run Test step of your pipeline

Sonarqube expects coverage information and unit tests reports to be send in XML. Both coverage and pytest can export their results in the adequate format using

coverage run --source='./your_project' -m pytest tests --junitxml=pytest.xml
coverage xml

This will produce a pytest.xml and a coverage.xml file during the pipeline execution. Add the following lines to your .gitignore in case some messy developer runs these commands on his workstation.

#.gitignore
pytest.xml
coverage.xml

Analyse code and send metrics

If the agent running the CI jobs or the docker image you use does not have SonarScanner installed, pre-compiled binaries can be found here. To scan your project and send the coverage and UT report to the server, just add the following command to your pipeline

./path/to/sonar-scanner -Dproject.settings=./sonar-project.properties -Dsonar.password=$password -Dsonar.login=$login

That's all folks