Tester une application Python Django - TDD

Nous allons à présent nous attaquer à une problématique fondamentale dans toute application qu’elle soit Web, mobile ou autres : Les tests.

TDD

TDD veut dire Test Driven Development c’est à dire Développement dirigé par les tests C’est une démarche mise en avant en Méthodologie Agile Elle consiste en général en l’application des points suivants:

  • écrire un test

  • vérifier qu’il échoue (car le code qu’il teste n’existe pas)

  • commiter votre code

  • écrire juste le code suffisant pour passer le test

  • vérifier que le test passe

  • faire un commit

  • procéder à un refactoring du code, c’est-à-dire l’améliorer en gardant les mêmes fonctionnalités.

  • vérifier que le test passe toujours

  • commiter

  • etc.

Intérêt de la démarche:

Les avantages principaux de cette démarche sont :

  • Préciser au mieux les spécifications du code et l’API envisagée

  • Ceci oblige à faire des choix de conception qui restent parfois trop dans le flou au début du développement

  • Plus tard, disposer d’une large base de tests est une riche pour une application car elle permet de vérifier à tout moment que les tests installés ne sont pas mis en défaut par de nouveaux développements ou des refactoring de code

Tous les langages de programmation disposent de Frameworks de tests. Par exemple Java offre JUnit, PHP quand à lui propose PHPUnit. Python propose unittest et permet aussi d’utiliser facilement la librairie selenium pour réaliser des tests fonctionnels.

Tests fonctionnels

Ces tests visent à vérifier le comportement global de notre application, pour mimer la navigation d’un client web sur le site.

Prérequis

Installer selenium via pip dans votre virtualenv :

pip install selenium

Eventuellement, installer selenium-standalone, qui offre plus de possibilités pour utiliser des browsers différents.

yarn add selenium-standalone@latest -g
selenium-standalone install
selenium-standalone start

Pour vérifier les paquets node globalement installés

npm list -g --depth=0

Pour vérifier les paquets node localement installés

npm list  --depth=0

Puis écrivons notre premier test fonctionnel dans le dossier Tests :

from selenium import webdriver
import time

browser = webdriver.Chrome(executable_path='./chromedriver')
time.sleep(3)
browser.get('http://localhost:8000')

assert 'Django' in browser.title
browser.quit()

Pour tester (dans le terminal où venv est actif):

python functional-test1.py

ou avec manage.py de django :

./manage.py test functional-test1.py

Danger

python est python3X (celui du venv que vous avez créé) Vous devrez remettre temporairement DEBUG = FALSE pour que ce test passe. Pourquoi ?

Pour l’instant notre test échoue si notre serveur est arrété ou si il est en mode DEBUG. Commitons.

Relançons le serveur …

./manage.py runserver

Puis relançons le test et constatons qu’il passe. Commitons lorsque c’est le cas.

Configuration complémentaire de la debug toolbar

Ajout de debug-toolbar

On peut ajouter django-debug-toolbar à notre venv pour voir cet outil à l’oeuvre. (les autres réglages nécessaires seront faits dans settings.py)

pip install django-debug-toolbar

Corrigez, les requirements:

pip freeze > requirements.txt

Commitez.

Complétons les settings de notre projet

Ajoutons la debug_toolbar aux INSTALLED_APPS Puis les panels que l’on souhaite voir afficher, le middleware nécessaire, et les IPs autorisées. On a déjà configuré la langue, le timezone, le format des dates, etc.

DEBUG = True

 # ../..

if DEBUG:
    INTERNAL_IPS = ('127.0.0.1', 'localhost',)

    MIDDLEWARE += (
                'debug_toolbar.middleware.DebugToolbarMiddleware',
                )

    INSTALLED_APPS += (
                'debug_toolbar',
                )


    DEBUG_TOOLBAR_PANELS = [
                'debug_toolbar.panels.versions.VersionsPanel',
                'debug_toolbar.panels.timer.TimerPanel',
                'debug_toolbar.panels.settings.SettingsPanel',
                'debug_toolbar.panels.headers.HeadersPanel',
                'debug_toolbar.panels.request.RequestPanel',
                'debug_toolbar.panels.sql.SQLPanel',
                'debug_toolbar.panels.staticfiles.StaticFilesPanel',
                'debug_toolbar.panels.templates.TemplatesPanel',
                'debug_toolbar.panels.cache.CachePanel',
                'debug_toolbar.panels.signals.SignalsPanel',
                'debug_toolbar.panels.logging.LoggingPanel',
                'debug_toolbar.panels.redirects.RedirectsPanel',
                'debug_toolbar.panels.profiling.ProfilingPanel',
    ]

    DEBUG_TOOLBAR_CONFIG = {
                'INTERCEPT_REDIRECTS': False,
        }



# ../..

LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Europe/Paris'

On complète urls.py

Dans le fichier général urls.py, on intègre la debug_toolbar :

from django.urls import path, include
from django.contrib import admin

urlpatterns = [
        path('admin/', admin.site.urls),
        path('lesTaches', include('lesTaches.urls'))
]
# Pour la debug_toolbar:
from django.conf import settings

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
        path('__debug__/', include(debug_toolbar.urls)),
                  ] + urlpatterns

La doc se trouve là

et les panels complémentaires que l’on peut installer sont documentés ici.

Attention : beaucoup de ces panels complémentaires sont obsolètes et non maintenus !

Enfin le dépôt Github de l’extension python contient la version la plus à jour du code.