Measuring Django Code Quality with SonarQube, Pytest, and Coverage: Continued

Ridwan Yusuf
5 min readAug 7, 2023
SonarQube analysis for Django code quality

Hi friends and welcome.

This guide complements an article I recently published on the FreeCodeCamp publication.

In the previous article, we successfully built a Python/Django project from the ground up. We integrated automated tests using Pytest and implemented coverage analysis to gauge the extent of test coverage. Furthermore, we incorporated SonarQube to identify code quality issues and potential security vulnerabilities.

In this guide, we will enhance the project by introducing additional features that add more depth and functionality.

By the end of this guide, you will have achieved the following objectives:

  1. Implement PostgreSql database support for SonarQube, ensuring that project analysis results remain persistent even when the SonarQube container is halted or rebooted.
  2. Incorporate a file-based configuration for SonarQube, replacing the need for manual setup on the SonarQube project dashboard.

Prerequisites for following along:

  1. Complete the initial section of the article available here.

Without further ado, let’s delve right in.

Configuring a PostgreSQL Database for SonarQube

To keep things straightforward, we will establish a PostgreSQL database within a Docker container.

Create a docker-compose.yml file at your preferred location and update its contents as shown below:

docker-compose.yml

version: "3.8"

services:
db:
image: postgres:12.1-alpine
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
env_file:
- ./.env
ports:
- "20432:5432"

pgadmin:
image: dpage/pgadmin4
restart: unless-stopped
container_name: pgadminsonar
env_file:
- ./.env
ports:
- "5050:80"
volumes:
- pgadmin-data:/var/lib/pgadmin

volumes:
postgres_data: ~
pgadmin-data: ~

Create another file named .env at the same location as the docker-compose.yml file and update its contents as follows. This file contains the environment variables for the database instance to be created:

.env

POSTGRES_USER=sonar-user
POSTGRES_PASSWORD=sonar-pass
POSTGRES_DB=sonar-db
PGADMIN_DEFAULT_EMAIL=root@root.com
PGADMIN_DEFAULT_PASSWORD=root

Initiate the PostgreSQL container by executing this command:

docker-compose up

Utilizing a File-Based Configuration for SonarQube

At the root directory of the Django project, create a file named sonar-project.properties and update its contents as follows:

sonar.projectKey=django-sonar-test
sonar.sources=.
sonar.host.url=http://localhost:9000
sonar.token=sqp_b382e840615dc050c64aa20e4c95b61110f86cf3
sonar.exclusions=**/venv/**,**/htmlcov/**,**/requirements/**,**/docker/**,**/k8s/**
sonar.python.coverage.reportPaths=coverage.xml
sonar.coverage.exclusions=**/tests/**,**/migrations/**,**/admin.py,**/apps.py,core/asgi.py,core/wsgi.py,manage.py
sonar.python.version=3
sonar properties values in SonarQube Dashboard

sonar.projectKey property sets a unique identifier for the project in SonarQube. This key can be found on the dashboard

sonar.sources property specifies the source code directories that SonarQube should analyze. The value “.” indicates that the analysis should be performed on the current directory (the root of the project).

sonar.token is the token generated by sonarqube on the dashboard for this particular project

sonar.exclusions are the patterns used to exclude some source files from analysis.

sonar.python.coverage.reportPath property tells SonarQube where to find the coverage report files.

sonar.coverage.exclusions are the patterns used to exclude some files from coverage report.

Once you have completed all the setup steps, execute the following command to initiate SonarQube:

docker run -d -p 9000:9000 -p 9092:9092 sonarqube -Dsonar.jdbc.url=jdbc:postgresql://172.17.0.1:20432/sonar-db -Dsonar.jdbc.username=sonar-user -Dsonar.jdbc.password=sonar-pass

It’s important to note that the Docker container is being run in detached mode by using the -d flag. If this is your first time setting it up, it's recommended to omit this flag. This way, you can observe any error logs that might arise during the process.

The command provided above includes crucial information about the database instance to be utilized. In our scenario, we have supplied all the pertinent details for the previously created database:

-Dsonar.jdbc.url=jdbc:postgresql://172.17.0.1:20432/sonar-db 
-Dsonar.jdbc.username=sonar-user
-Dsonar.jdbc.password=sonar-pass

If you come across an error related to Elasticsearch resembling the one shown in the image below, follow these steps to address the issue.

SonarQube elastic search error

This error is related to the virtual memory limits set on the host system, and Elasticsearch requires a higher value for proper functioning. To resolve this issue, you need to adjust the vm.max_map_count kernel setting on the host machine.

On Linux, you can temporarily increase the vm.max_map_count value using the following command as the root user or with sudo privileges:

sudo sysctl -w vm.max_map_count=262144

If you want to make this change permanent, you can add the following line to the /etc/sysctl.conf file (You may need to reboot the system for the new setting to take effect)

Ready to elevate 🚀 your Python 🐍 skills? Check out YouTube for exclusive content. Consider subscribing to stay updated.

vm.max_map_count=262144

Running a SonarQube Analysis on the Project

At the root directory of the project, execute this command to run analysis on the project:

sonar-scanner

Here is the folder structure of the project:

├── blog
├── core
├── coverage.xml
├── db.sqlite3
├── manage.py
├── pytest.ini
├── README.md
├── requirements
├── setup.cfg
├── sonar-project.properties
└── venv
Output from sonar-scanner command

After the command successfully executes, visit the dashboard to view the results of the project analysis.

Project Analysis result on Dashboard.

At this point, the analysis of all projects remains unaffected when stopping or restarting the SonarQube container due to the implementation of a persistent database.

The complete source code of this project can be found here.

Wrapping up

This guide has demonstrated a comprehensive approach to evaluating Django code quality through the utilization of SonarQube, Pytest, and Coverage. By integrating PostgreSql database support into SonarQube, the persistence of analysis results has been ensured even across container disruptions. Additionally, the transition to a file-based configuration method for SonarQube eliminates the need for manual adjustments on the project dashboard. Through these steps, a robust and streamlined process for measuring and maintaining code quality in Django projects has been achieved.

Enjoyed this article?

Feel free to explore my video collection on YouTube for more educational content. Don’t forget to subscribe to the channel to stay updated with future releases.

LinkedIn

Highlighted Blog Post:

Setting Up Multiple Virtual Hosts Using a Single RabbitMQ Instance

--

--

Ridwan Yusuf

RidwanRay.com -I provide engineers with actionable tips and guides for immediate use