Je teste mon code
avec py.test
Ronan Amicel
@amicel
PyCon FR — 25 octobre 2014 — Lyon
Slide 2
Slide 2 text
Ronan Amicel
Fondateur
@ Pocket Sensei
Hacker en résidence
@ The Family
Slide 3
Slide 3 text
Préambule
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
C’est quoi py.test ?
Slide 6
Slide 6 text
$ py.test
• Un outil en ligne de commande pour lancer vos
tests :
• découverte
• exécution
• affichage des résultats
Slide 7
Slide 7 text
import pytest
• Un framework pour écrire vos tests
• avec très peu de bla bla
• avec un mécanisme de fixtures très flexible
Slide 8
Slide 8 text
Le plan
• Écrire ses tests avec py.test
• Moins de bla bla
• Utiliser les fixtures
• Lancer ses tests avec py.test
• Comment passer facilement à py.test
Slide 9
Slide 9 text
Écrire ses tests
avec py.test
Slide 10
Slide 10 text
Moins de bla bla
Slide 11
Slide 11 text
Rappel : unittest
import unittest
def fact(n):
return 1 if n <= 1 else n * fact(n - 1)
class TestFact(unittest.TestCase):
def test_three(self):
self.assertEqual(fact(3), 6)
if __name__ == '__main__':
unittest.main()
Slide 12
Slide 12 text
Avec py.test
def fact(n):
return 1 if n <= 1 else n * fact(n - 1)
def test_fact(self):
assert fact(3) == 6
Slide 13
Slide 13 text
Démo assertions
Slide 14
Slide 14 text
Les fixtures
Slide 15
Slide 15 text
Setup
from selenium import webdriver
import pytest
@pytest.fixture
def browser():
return webdriver.Firefox()
def test_pycon(browser):
browser.get('http://pycon.fr/')
assert 'Bienvenue' in browser.title
Slide 16
Slide 16 text
Durée de vie
@pytest.fixture(scope='function')
...
@pytest.fixture(scope='module')
...
@pytest.fixture(scope='session')
...
Slide 17
Slide 17 text
Teardown (1/2)
@pytest.fixture
def browser(request):
b = webdriver.Firefox()
def teardown():
b.quit()
request.addfinalizer(teardown)
return b
Slide 18
Slide 18 text
Teardown (2)
@pytest.yield_fixture
def browser():
b = webdriver.Firefox()
yield b
b.quit()
Découverte
• Parcours récursif des répertoires
• Fichiers test_*.py ou *_test.py
• Classes qui commencent par Test
• Fonctions et méthodes qui commencent par test_
• Reconnait les tests unittest et nose existants
Slide 24
Slide 24 text
Exécuter seulement
certains tests
$ py.test tata/
$ py.test toto.py
$ py.test --pyargs mon.module
Slide 25
Slide 25 text
Collecter les tests uniquement
$ py.test --collect-only
Slide 26
Slide 26 text
Un test bien précis
$ py.test fichier.py::fonction
$ py.test fichier.py::Classe::methode
Slide 27
Slide 27 text
Seulement les tests dont le
nom contient un mot-clé
$ py.test -k toto
$ py.test -k 'toto or tata'
Slide 28
Slide 28 text
Exécution
Slide 29
Slide 29 text
S’arrêter en cas d'erreur
$ py.test -x
$ py.test --maxfail=3
Slide 30
Slide 30 text
Lancer le debugger
en cas d’erreur
$ py.test --pdb
$ py.test -x --pdb
Slide 31
Slide 31 text
Contrôle de l'affichage
Slide 32
Slide 32 text
Afficher le nom des tests
$ py.test -v
Slide 33
Slide 33 text
Ne pas capturer
la sortie standard
$ py.test -s
$ py.test --capture=no
Slide 34
Slide 34 text
Niveau de détail des
tracebacks
$ py.test --tb=auto # défaut
$ py.test --tb=long
$ py.test --tb=short
$ py.test --tb=line
$ py.test --tb=native
$ py.test --tb=no
Slide 35
Slide 35 text
Afficher les valeurs des
variables locales
$ py.test --showlocals
$ py.test -l
Slide 36
Slide 36 text
Afficher un résumé à la fin
$ py.test -rf # failures
Slide 37
Slide 37 text
Afficher les tests les plus lents
$ py.test --durations=10
Slide 38
Slide 38 text
Plugins
Slide 39
Slide 39 text
Lancer ses tests en parallèle
$ pip install pytest-xdist
$ py.test -n4
Recette facile en 2 étapes
1. Utilisez py.test pour lancer vos tests existants
(unittest, doctest, nose, Django)
2. Commencez à (ré)écrire vos tests dans le style
py.test