Measuring Django Code Quality with SonarQube, Pytest, and Coverage: Continued
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:
- Implement PostgreSql database support for SonarQube, ensuring that project analysis results remain persistent even when the SonarQube container is halted or rebooted.
- Incorporate a file-based configuration for SonarQube, replacing the need for manual setup on the SonarQube project dashboard.
Prerequisites for following along:
- 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.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.
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
After the command successfully executes, visit the dashboard to view the results of the project analysis.
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.
Highlighted Blog Post:
Setting Up Multiple Virtual Hosts Using a Single RabbitMQ Instance