Bien configurer ses tests Python avec tox et Travis

Le plus difficile dans le développement des tests unitaires c'est souvent de se motiver à écrire les premières lignes... Alors qu'une fois que c'est initié, ça devient très simple d'en ajouter. Nous verrons dans cet article de blog comment le faire rapidement avec tox et Travis !

Le blog Makina-corpus

Le plus difficile dans le développement des tests unitaires c'est souvent de se motiver à écrire les premières lignes... Alors qu'une fois que c'est initié, ça devient très simple d'en ajouter. Nous verrons dans cet article de blog comment le faire rapidement avec tox et Travis !

Une fois les tests prêts, il faudrait qu'ils tournent automatiquement à chaque changement du code, et ce sur toutes les versions de Python et du framework (ici Django) supportées. L'idée étant d'avoir le résultat suivant : https://travis-ci.org/makinacorpus/django-tracking-fields

L'idée est de mettre en place ces tests, puis de les faire tourner avec tox avec toutes les versions de Python nécessaires, et enfin d'automatiser le tout avec Travis.

Pour vos tests, cela dépendra de votre projet. Dans notre cas, les tests seront lancés
avec un script runtests.py.

Tox

La configuration de Tox est assez basique. On commence par définir les versions de Python en fonction des versions de Django que l'on veut dans le tox.ini :

[tox]
envlist =
    {py27,py34,py35,py36}-django111,
    {py34,py35,py36,py37}-django20,
    {py35,py36,py37}-django21,
    {py35,py36,py37}-djangomaster

Les accolades permettent de définir plusieurs chaines d'un coup. Cette ligne :

{py35,py36,py37}-djangomaster

Équivaut à :

py35-djangomaster,
py36-djangomaster,
py37-djangomaster

Il faut ensuite configurer la commande de test ainsi que les dépendances à installer, en fonction de l'environnement de tox en cours d'execution :

[testenv]
commands = ./runtests.py
deps =
    django111: Django>=1.11,<2.0
    django20: Django>=2.0,<2.1
    django21: Django>=2.1,<2.2
    djangomaster: https://github.com/django/django/archive/master.tar.gz
    -r requirements.txt

Ainsi, lorsque py36-django111 tournera, Django>=1.11,<2.0 sera installé spécifiquement.

Nous pouvons maintenant faire tourner nos tests juste avec la commande tox !

Travis

Voyons tout d'abord la configuration du .travis.yml en détail. Nous commençons par définir le langage puis activons le cache pour pip, ce qui permet d’accélérer l'initialisation.

language: python
cache: pip

Nous avons ensuite la matrice, qui contient toutes les versions testées.

matrix:
  fast_finish: true
  include:
    - { python: "2.7", env: DJANGO=1.11 }

    - { python: "3.4", env: DJANGO=1.11 }
    - { python: "3.4", env: DJANGO=2.0 }

    - { python: "3.5", env: DJANGO=1.11 }
    - { python: "3.5", env: DJANGO=2.0 }
    - { python: "3.5", env: DJANGO=2.1 }
    - { python: "3.5", env: DJANGO=master }

    - { python: "3.6", env: DJANGO=1.11 }
    - { python: "3.6", env: DJANGO=2.0 }
    - { python: "3.6", env: DJANGO=2.1 }
    - { python: "3.6", env: DJANGO=master }

    - { python: "3.7", env: DJANGO=2.0 }
    - { python: "3.7", env: DJANGO=2.1 }
    - { python: "3.7", env: DJANGO=master }

  allow_failures:
    - env: DJANGO=master

La variable DJANGO est utilisée pour déterminer quelle version de Django installer dans tox, cela requiert un ajout dans le tox.ini :

[travis:env]
DJANGO =
    1.11: django111
    2.0: django20
    2.1: django21
    master: djangomaster

Il y a deux choses à noter dans la matrice. Nous testons sur la branche master de Django, ce qui peut évidemment échouer. Cela permet surtout d'anticiper les changements requis pour rester compatible. Nous pouvons dire que ces tests peuvent échouer en ajoutant l'option allow_failures. L'option fast_finish permet quant à elle de dire à Travis qu'il n'y a pas besoin d'attendre les tests pouvant échouer avant de déclarer si les tests sont un succès ou non.

Nous installons tox` ainsi que `tox-travis. `tox-travis` nous permet notamment d'utiliser `[travis:env]`.

install:
  - pip install tox tox-travis

Et enfin le script de test, tout simplement tox.

script:
  - tox

En bonus, la couverture

J'ai l'habitude d'utiliser coveralls pour avoir une visualisation de la couverture de tests. Il suffit de deux ajouts pour que cela fonctionne. Dans le tox.ini, on installe coverage et on fait tourner les tests avec :

[testenv]
commands = coverage run ./runtests.py
deps =
    [...]
    coverage

Et dans .travis.yml, on envoie les rapports vers coveralls en cas de succès :

after_success:
  - pip install coveralls
  - coveralls

Et voila !

Maintenant que vous êtes un pro, n'hésitez pas à mettre en place des tests dans tous vos projets.

N'hésitez-pas à aller voir nos formations sur les tests.

Actualités en lien

Image
Django Python Keycloak
18/11/2021

Administrer des comptes Keycloak depuis une application Python/Django

Dans cet article, nous allons créer une application Python/Django qui agira en tant que maître sur Keycloak afin de pouvoir ajouter facilement des comportements personnalisés à Keycloak.

Voir l'article
Image
Geotrek Signalement
29/09/2021

Gestion des territoires naturels : Geotrek intègre l’écosystème Suricate

Makina Corpus, missionnée par le département du Gard, et en collaboration avec le Ministère chargé des Sports ainsi que la société Arut@m, développe une intégration du dispositif Suricate aux applications Geotrek-Rando et Geotrek-Admin.

Voir l'article
Image
Python_logo_3
08/07/2020

Migrer une application de Python 2 à Python 3

Le support de Python 2 est officiellement terminé, c'est le moment de passer vos applications à Python 3 ! Voici quelques conseils pour réussir cette migration.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus