Tutoriel 9 - Temps de test¶
La plupart des développements de logiciels n'impliquent pas l'écriture d'un nouveau code, mais la modification d'un code existant. S'assurer que le code existant continue à fonctionner comme nous l'attendons est une partie essentielle du processus de développement logiciel. Une façon de s'assurer du comportement de notre application est d'utiliser une suite de tests.
Exécution de la suite de tests¶
Il s'avère que notre projet possède déjà une suite de tests ! Lorsque nous avons
généré notre projet à l'origine, deux répertoires de premier niveau ont été
générés : src et tests. Le dossier src contient le code de notre
application ; le dossier tests contient notre suite de tests. Dans le dossier
tests se trouve un fichier nommé test_app.py avec le contenu suivant :
def test_first():
"""Un premier test pour l'application"""
assert 1 + 1 == 2
Ceci est un Pytest test case - un bloc de code qui peut être exécuté pour vérifier un certain comportement de votre application. Dans ce cas, le test est un placeholder, et ne teste rien de notre application - mais c'est un test que nous pouvons effectuer.
Nous pouvons lancer cette suite de tests en utilisant l'option --test de
briefcase dev. Comme c'est la première fois que nous lançons des tests, nous
devons également passer l'option -r pour nous assurer que les exigences de
test sont également installées :
(beeware-venv) $ briefcase dev --test -r
[helloworld] Installation des dépendances...
...
Installation des dépendances de développement... terminée
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
plateforme darwin -- Python 3.11.0, pytest-7.2.0, pluggy-1.0.0 -- /Users/brutus/beeware-tutorial/beeware-venv/bin/python3.11
cachedir : /var/folders/b_/khqk71xd45d049kxc_59ltp80000gn/T/.pytest_cache
rootdir : /Users/brutus
plugins : anyio-3.6.2
collecte en cours... 1 élément collecté
tests/test_app.py::test_first RÉUSSI [100 %]
============================== 1 test réussi en 0,01 s ===============================
(beeware-venv) $ briefcase dev --test -r
[helloworld] Installation des dépendances...
...
Installation des dépendances de développement... terminée
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
plateforme linux -- Python 3.11.0
pytest==7.2.0
py==1.11.0
pluggy==1.0.0
cachedir : /tmp/.pytest_cache
rootdir : /home/brutus
plugins : anyio-3.6.2
collecte en cours... 1 élément collecté
tests/test_app.py::test_first RÉUSSI [100 %]
============================== 1 test réussi en 0,01 s ===============================
(beeware-venv) C:\...>briefcase dev --test -r
[helloworld] Installation des dépendances...
...
Installation des dépendances de développement... terminée
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
plateforme win32 -- Python 3.11.0
pytest==7.2.0
py==1.11.0
pluggy==1.0.0
cachedir: C:\Users\brutus\AppData\Local\Temp\.pytest_cache
rootdir: C:\Users\brutus
plugins: anyio-3.6.2
collecte en cours... 1 élément collecté
tests/test_app.py::test_first RÉUSSI [100 %]
============================== 1 test réussi en 0,01 s ===============================
Succès ! Nous venons d'exécuter un seul test qui vérifie que les mathématiques Python fonctionnent de la manière attendue (Quel soulagement !).
Remplaçons ce placeholder test par un test pour vérifier que notre méthode
greeting() se comporte comme nous l'attendons. Remplacez le contenu de
test_app.py par ce qui suit :
from helloworld.app import greeting
def test_name():
"""Si un nom est fourni, le message de bienvenue inclut ce nom"""
assert greeting("Alice") == "Bonjour, Alice"
def test_empty():
"""Si aucun nom n'est fourni, un message de bienvenue générique est affiché"""
assert greeting("") == "Bonjour, inconnu"
Ceci définit deux nouveaux tests, vérifiant les deux comportements que nous attendons : la sortie lorsqu'un nom est fourni, et la sortie lorsque le nom est vide.
Nous pouvons maintenant réexécuter la suite de tests. Cette fois, nous n'avons
pas besoin de fournir l'option -r, puisque les pré-requis pour les tests ont
déjà été installés ; nous avons seulement besoin d'utiliser l'option --test :
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 2 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 50 %]
tests/test_app.py::test_empty RÉUSSI [100 %]
============================== 2 tests réussis en 0,11 s ===============================
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 2 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 50 %]
tests/test_app.py::test_empty RÉUSSI [100 %]
============================== 2 tests réussis en 0,11 s ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 2 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 50 %]
tests/test_app.py::test_empty RÉUSSI [100 %]
============================== 2 tests réussis en 0,11 s ===============================
Excellent ! Notre méthode utilitaire greeting() fonctionne comme prévu.
Développement piloté par les tests¶
Maintenant que nous disposons d'une suite de tests, nous pouvons l'utiliser pour
développer de nouvelles fonctionnalités. Modifions notre application pour avoir
un message d'accueil spécial pour un utilisateur particulier. Nous pouvons
commencer par ajouter un scénario de test pour le nouveau comportement que nous
aimerions voir au bas de test_app.py :
def test_brutus():
"""Si le nom est Brutus, un message d'accueil spécial s'affiche"""
assert greeting("Brutus") == "Méfiez-vous des IDE Python !"
Ensuite, exécutez la suite de tests avec ce nouveau test :
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus ÉCHOUÉ [100 %]
=================================== ÉCHECS ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""Si le nom est Brutus, un message d'accueil spécial est affiché"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== Informations succinctes sur le test ============================
ÉCHEC tests/test_app.py::test_brutus - AssertionError: assert 'Hello, Brutus...
========================= 1 échec, 2 réussites en 0,14 s ==========================
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
Collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus ÉCHOUÉ [100 %]
=================================== ÉCHECS ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""Si le nom est Brutus, fournir un message d'accueil spécial"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== bref résumé des tests ============================
ÉCHEC tests/test_app.py::test_brutus - AssertionError: assert 'Bonjour, Brutus...
========================= 1 échec, 2 réussis en 0,14 s ==========================
============================== 2 réussis en 0,11 s ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus ÉCHOUÉ [100 %]
=================================== ÉCHECS ===================================
_________________________________ test_brutus __________________________________
def test_brutus():
"""Si le nom est Brutus, afficher un message d'accueil spécial"""
> assert greeting("Brutus") == "BeeWare the IDEs of Python!"
E AssertionError: assert 'Hello, Brutus' == 'BeeWare the IDEs of Python!'
E - BeeWare the IDEs of Python!
E + Hello, Brutus
tests/test_app.py:19: AssertionError
=========================== Informations succinctes sur le test ============================
ÉCHEC tests/test_app.py::test_brutus - AssertionError: assert 'Hello, Brutus...
========================= 1 échec, 2 réussites en 0,14 s ==========================
Cette fois, nous voyons un échec du test - et la sortie explique la source de
l'échec : le test attend la sortie "BeeWare the IDEs of Python!", mais notre
implémentation de greeting() retourne "Hello, Brutus". Modifions
l'implémentation de greeting() dans src/helloworld/app.py pour avoir le
nouveau comportement :
def greeting(name):
if name:
if name == "Brutus":
return "Méfiez-vous des IDE de Python !"
else:
return f"Bonjour, {name}"
else:
return "Bonjour, inconnu"
Si nous exécutons à nouveau les tests, nous constatons qu'ils sont réussis :
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 tests réussis en 0,15 s ===============================
(beeware-venv) $ briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 tests réussis en 0,15 s ===============================
(beeware-venv) C:\...>briefcase dev --test
[helloworld] Exécution de la suite de tests dans l'environnement de développement...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 tests réussis en 0,15 s ===============================
Tests d'exécution¶
Jusqu'à présent, nous avons exécuté les tests en mode développement. C'est particulièrement utile lorsque vous développez de nouvelles fonctionnalités, car vous pouvez rapidement itérer sur l'ajout de tests et l'ajout de code pour faire passer ces tests. Cependant, à un moment donné, vous voudrez vérifier que votre code s'exécute correctement dans l'environnement de l'application groupée.
Les options --test et -r peuvent également être passées à la commande run.
Si vous utilisez briefcase run --test -r, la même suite de tests s'exécutera,
mais elle s'exécutera dans le paquetage de l'application plutôt que dans votre
environnement de développement :
(beeware-venv) $ briefcase run --test -r
[helloworld] Mise à jour du code de l'application...
Installation de src/helloworld... terminée
Installation des tests... terminée
[helloworld] Mise à jour des dépendances...
...
[helloworld] Compilation de build/helloworld/macos/app/Hello World.app (mode test)
[helloworld] Lancement de la suite de tests...
===========================================================================
Configuration de Python isolé...
Pré-initialisation du runtime Python...
PythonHome : /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
PYTHONPATH :
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python311.zip
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/support/python-stdlib/lib-dynload
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app_packages
- /Users/brutus/beeware-tutorial/helloworld/macOS/app/Hello World/Hello World.app/Contents/Resources/app
Configuration de argc/argv...
Initialisation du runtime Python...
Installation du gestionnaire NSLog Python...
Exécution du module d'application : tests.helloworld
---------------------------------------------------------------------------
============================= Début de la session de test ==============================
...
Collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 réussis en 0,21 s ===============================
[helloworld] Suite de tests réussie !
(beeware-venv) $ briefcase run --test -r
[helloworld] Finalisation de la configuration de l'application...
Cible : ubuntu:jammy (base Debian du fournisseur)
Détermination de la version de glibc... terminé
Cible : glibc 2.35
Cible : Python 3.10
[helloworld] Mise à jour du code de l'application...
Installation de src/helloworld... terminée
Installation des tests... terminée
[helloworld] Mise à jour des dépendances...
...
[helloworld] Compilation de build/helloworld/linux/ubuntu/jammy/helloworld-0.0.1/usr/bin/helloworld (mode test)
[helloworld] Lancement de la suite de tests...
===========================================================================
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 tests réussis en 0,21 s ===============================
(beeware-venv) C:\...>briefcase run --test -r
[helloworld] Mise à jour du code de l'application...
Installation de src/helloworld... terminée
Installation des tests... terminée
[helloworld] Mise à jour des dépendances...
...
[helloworld] Création de build\helloworld\windows\app\src\Hello World.exe (mode test)
===========================================================================
Début du journal : 02/12/2022 10:57:34Z
Pré-initialisation du runtime Python...
PythonHome : C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
PYTHONPATH :
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\python311.zip
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app_packages
- C:\Users\brutus\beeware-tutorial\helloworld\windows\app\Hello World\src\app
Configuration de argc/argv...
Initialisation du runtime Python...
Exécution du module d'application : tests.helloworld
---------------------------------------------------------------------------
============================= Début de la session de test ==============================
...
collecte en cours... 3 éléments collectés
tests/test_app.py::test_name RÉUSSI [ 33 %]
tests/test_app.py::test_empty RÉUSSI [ 66 %]
tests/test_app.py::test_brutus RÉUSSI [100 %]
============================== 3 réussis en 0,21 s ===============================
Comme pour briefcase dev --test, l'option -r n'est nécessaire que la
première fois que vous exécutez la suite de tests pour vous assurer que les
dépendances des tests sont présentes. Lors des exécutions suivantes, vous pouvez
omettre cette option.
Vous pouvez également utiliser l'option --test sur les backends mobiles : -
ainsi briefcase run iOS --test et briefcase run android --test
fonctionneront tous les deux, lançant la suite de tests sur l'appareil mobile
que vous avez sélectionné.