Project

General

Profile

HowDoWeDoTests

Lancer les tests

Avec nox

  • À chaque lancement, nox va réinstaller l'environnement virtuel, passé le premier lancement c'est inutile. Pour réutiliser l'environnement et gagner en rapidité :
    $ nox -R
    
  • Lancer seulement les tests Django :
    $ nox -e tests
    
  • Lancer seulement pylint :
    $ nox -e pylint
    
  • Passer des options à pylint, par exemple une option pour conserver la base de données et ne pas rejouer les migrations :
    $ nox -e tests -- tests --reuse-db
    
À la place ou en parallèle de --reuse-db, on peut ajouter :
  • --pdb pour s'arrêter avec pdb à la première erreur.
  • -k nom_dun_test pour ne lancer qu'un test particulier.
  • tests/test_foo.py pour lancer les tests d'un fichier.
  • --last-failed pour reprendre au dernier test qui a planté.
  • --sw pour s'arrêter dès la première erreur et reprendre là où l'on s'est arrêté au prochain lancement

Avec tox (en cours de dépréciation au 04/06/24)

Une fois qu'on a tox de configuré pour lancer les tests py.test on peut faire pas mal de choses amusantes, je donne mes exemples dans le contexte du projet authentic2.

  • lancer les tests dans un environnement donné (parce qu'on a pas besoin de tout tester là maintenant, ça c'est pour jenkins)
    $ tox -e dj18-authentic-sqlite
    
  • lancer les tests en conservant la base de donnée (ça permet de passer l'étape laborieuse des migrations)
    $ tox -e dj18-authentic-sqlite -- tests --reuse-db
    
  • s'arrêter avec pdb dans le dernier test qui a planté (--lf pour lastfail et --pdb pour ouvrir pdb sur une exception)
    $ tox -e dj18-authentic-sqlite -- tests --lf --reuse-db --pdb
    
  • ne lancer qu'un test en particulier (on peut passer à l'option -k n'importe quelle sous chaîne pertinente du nom du ou des fonctions de test)
    $ tox -e dj18-authentic-sqlite -- tests -k test_moncul --reuse-db --pdb
    
  • ne lancer que les tests présent dans le(s) fichier(s) indiqué(s) (combinable avec -k )
    $ tox -e dj18-authentic-sqlite -- tests/test_foo.py tests/test_bar.py --reuse-db --pdb
    
  • recréer la base de test (parce qu'on a ajouté une migration)
    $ tox -e dj18-authentic-sqlite -- tests --reuse-db --create-db
    

Ressources

Utiliser un debugger alternatif

Par défaut, utiliser l'option --pdb ou taper breakpoint dans le code ouvrira l'interpréteur pdb de base.
Il est possible d'utiliser un autre interpréteur, par exemple IPython.

Avec nox

Créer le fichier `.config/nox/eo-hooks.py` avec comme contenu :

def setup_venv(session, packages):
    if session.name.startswith("tests"):
        packages.append("ipdb")

def run(session, run_args, run_kwargs):
    if session.name.startswith("tests"):
        run_kwargs.setdefault('env', {})['PYTHONBREAKPOINT'] = ''

Et ajouter dans son .bashrc :

export PYTEST_ADDOPTS='--pdbcls=IPython.terminal.debugger:TerminalPdb'

Tant qu'à faire, pour utiliser ipdb vraiment partout :

export PYTHONBREAKPOINT=ipdb.set_trace

Avec tox (en cours de dépréciation au 04/06/24)

L'environnement installé par tox n'inclut pas IPython. Il faut donc injecter globalement la dépendance via un plugin : pip install tox-ipdb-plugin.

Ensuite, il faut dire à pytest d'utiliser cet interpréteur pour pdb. Là encore un peu de gymnastique pour que la configuration soit globale, il faut ajouter deux variables d'environnement dans son .bashrc :

export PYTEST_ADDOPTS='--pdbcls=IPython.terminal.debugger:TerminalPdb'
export TOX_OVERRIDE='testenv.pass_env+=USER,PYTEST_ADDOPTS'

Et tant qu'à faire, pour utiliser ipdb vraiment partout :

export PYTHONBREAKPOINT=ipdb.set_trace

Voilà, vive l'autocomplétion.

Utiliser l'ouverture d'un navigateur par webtest

Dans un debugger ouvert au cours d'une exécution tox, si on dispose d'un objet réponse de webtest, il est possible de la visualiser dans un navigateur moyennant là encore des variables d'environnement :

export BROWSER='firefox'
export TOX_OVERRIDE='testenv.pass_env+=USER,XDG_RUNTIME_DIR,DISPLAY,BROWSER'

Si ça ne marche pas, tenter de passer toutes les variables d'environnements peut faire le job :

export TOX_TESTENV_PASSENV=*

Ce qui permet de faire fonctionner :

> /xxx/tests/test.py(24)test_xxx()
   2151     resp = app.get('/')
   2152     
   2153     breakpoint()
-> 2154     resp = resp.click('xxx')
   2155

ipdb> resp.showbrowser()

Note : avec nox, il n'est bien sûr pas nécessaire de définir les variables TOX_*.

Tests manuels

Also available in: PDF HTML TXT