Aller au contenu

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é.