UNE RÉVOLUTION DANS LE MONDE DES TESTS
UNE RÉVOLUTION DANS LE MONDE DES TESTS
Boris Feld - PyConfr 2018
octobus.net
Slide 2
Slide 2 text
PRESENTATION
PRESENTATION
Slide 3
Slide 3 text
BORIS FELD
BORIS FELD
Expert Mercurial, Python
et DevOps.
Enthousiaste sur la
qualité.
https://octobus.net/
@lothiraldan
Slide 4
Slide 4 text
QUI FAIT DES TESTS?
QUI FAIT DES TESTS?
Slide 5
Slide 5 text
SONDAGE: COMBIEN DE PERSONNES
SONDAGE: COMBIEN DE PERSONNES
ÉCRIVENT DES TESTS ?
ÉCRIVENT DES TESTS ?
Slide 6
Slide 6 text
SONDAGE: COMBIEN DE PERSONNES
SONDAGE: COMBIEN DE PERSONNES
EXECUTENT DES TESTS ?
EXECUTENT DES TESTS ?
Slide 7
Slide 7 text
VOUS N’ÊTES PAS LES SEULS
VOUS N’ÊTES PAS LES SEULS
2017 2018
0.00%
10.00%
20.00%
30.00%
40.00%
50.00%
60.00%
70.00%
80.00%
Launching tests
Writing tests
=> 70% lancent des tests
Slide 8
Slide 8 text
ÉTAT DE L’ART EN PYTHON
ÉTAT DE L’ART EN PYTHON
Slide 9
Slide 9 text
OUTILS
OUTILS
Unittest
Nosetests
Pytest
Autre ?
Slide 10
Slide 10 text
UNITTEST
UNITTEST
Inclut dans Python
Permet d’écrire des tests sous la forme de classes
Fournit des assertions sous la forme de méthodes
d’assertions.
Slide 11
Slide 11 text
UNITTEST EXEMPLE
UNITTEST EXEMPLE
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertTrue('Foo'.isupper())
if __name__ == '__main__':
unittest.main()
Slide 12
Slide 12 text
EXECUTION AVEC UNITTEST
EXECUTION AVEC UNITTEST
F.
=================================================================
=====
FAIL: test_isupper (__main__.TestStringMethods)
-----------------------------------------------------------------
-----
Traceback (most recent call last):
File "test.py", line 10, in test_isupper
self.assertTrue('Foo'.isupper())
AssertionError: False is not true
-----------------------------------------------------------------
-----
Ran 2 tests in 0.000s
FAILED (failures=1)
Slide 13
Slide 13 text
NOSETESTS
NOSETESTS
Un unittest meilleur
Un ecosystem de plugin
Une vraie avancée
Mais deux paquets Pypi, nose et nose2
Un écosystème parcemé
Slide 14
Slide 14 text
EXECUTION AVEC NOSETESTS
EXECUTION AVEC NOSETESTS
F.
=================================================================
=====
FAIL: test_isupper (test.TestStringMethods)
-----------------------------------------------------------------
-----
Traceback (most recent call last):
File
"/home/lothiraldan/Labo/presentations/balto_revolution_fr/src/tes
t.py", line 10, in test_isupper
self.assertTrue('Foo'.isupper())
AssertionError: False is not true
-----------------------------------------------------------------
-----
Ran 2 tests in 0.000s
FAILED (failures=1)
Slide 15
Slide 15 text
REDNOSE (PLUGIN NOSE1)
REDNOSE (PLUGIN NOSE1)
F.
=================================================================
=====
1) FAIL: test_isupper (test.TestStringMethods)
-----------------------------------------------------------------
-----
Traceback (most recent call last):
test.py line 10 in test_isupper
self.assertTrue('Foo'.isupper())
AssertionError: False is not true
-----------------------------------------------------------------
------------
2 tests run in 0.001 seconds.
1 FAILED (1 test passed)
Slide 16
Slide 16 text
PYTEST
PYTEST
La vraie étoile montante du marché
Un meilleur unittest
Tests sous forme de fonctions
Fixtures
De nombreux utilitaires
De nombreux plugins
PLUS DE DONNÉES
PLUS DE DONNÉES
Temps
Messages de log
Sortie standard et sortie standard d’erreur
Diff de text ou d’images
Fichier, ligne, etc…
Slide 48
Slide 48 text
LANCER UN TEST SPECIFIQUE?
LANCER UN TEST SPECIFIQUE?
Slide 49
Slide 49 text
SORTIE VS ENTRÉE
SORTIE VS ENTRÉE
On as aussi besoin d’un format d’entrée:
{
"collect_only": true
}
{
"files": ["file1.py", "file2.py"],
"nodes": ["file1.py::test_func"]
}
Slide 50
Slide 50 text
COMMENT RÉCUPÉRER UN IDENTIFIANT?
COMMENT RÉCUPÉRER UN IDENTIFIANT?
Ajoutons un nouveau champ de sortie:
{
"test_name": "test_success",
"outcome": "passed",
"_id": "test_func.py::test_success"
}
Slide 51
Slide 51 text
LA POST-RÉVOLUTION
LA POST-RÉVOLUTION
Slide 52
Slide 52 text
EXEMPLE DE SORTIE
EXEMPLE DE SORTIE
{
"test_name": "test_failed",
"_id": "test_func.py::test_success",
"outcome": "failed",
"error": {
"humanrepr": "def test_fails():\n> assert False\nE
assert False\n\ntest_func.py:9: AssertionError"
}
}
Slide 53
Slide 53 text
ET SI ON ALLAIT PLUS LOIN ?
ET SI ON ALLAIT PLUS LOIN ?
Et si on faisait un plugin nosetests pour ce format?
Slide 54
Slide 54 text
ET SI ON ALLAIT ENCORE PLUS LOIN ?
ET SI ON ALLAIT ENCORE PLUS LOIN ?
Et si on faisait un plugin pour un test runner dans un
autre langage?
Slide 55
Slide 55 text
JUSQU’AU PEUT-ON ALLER ?
JUSQU’AU PEUT-ON ALLER ?
Et si on lisait la sortie standard d’autre chose qu’un
process ? Comme une commande ssh ou un container
Docker ?
Slide 56
Slide 56 text
VERS L’INFINIE ET AU-DELÀ
VERS L’INFINIE ET AU-DELÀ
Balto etant base sur Asyncio, et si on lancait plusieurs
suites pytest en parallelle ? Ou plusieurs suites dans
des langages differents sur une machine distante avec
Docker?
Slide 57
Slide 57 text
RÉVOLUTION DEMO
RÉVOLUTION DEMO
Slide 58
Slide 58 text
LA VRAIE RÉVOLUTION
LA VRAIE RÉVOLUTION
Slide 59
Slide 59 text
UN NOUVEAU PROTOCOLE
UN NOUVEAU PROTOCOLE
Similaire à HTTP ou LSP, c’est une fondation au dessus
duquel construire les nouveaux outils de demain.
Slide 60
Slide 60 text
EXEMPLE
EXEMPLE
Vous voulez un dashboard curses pour lancer vos tests?
Vous pouvez !
Vous voulez un rapport sur les temps de chacun de vos
tests? Vous pouvez !
Slide 61
Slide 61 text
LITF
LITF
Language Independent Test Format
Slide 62
Slide 62 text
BALTO
BALTO
BAlto is a Language Independent Test Orchestrator
Slide 63
Slide 63 text
INSTALLER BALTO
INSTALLER BALTO
Télécharger la dernière release sur Github:
https://github.com/Lothiraldan/balto/releases
Le mettre dans le path
Installer le plugin litf de votre test runner
Pro ter
Slide 64
Slide 64 text
QUE POUVEZ-VOUS FAIRE ?
QUE POUVEZ-VOUS FAIRE ?
Utiliser Balto
Parler de Balto autour de vous
Parler de LITF au mainteneur de votre test runner
préféré
Slide 65
Slide 65 text
CONTRIBUER
CONTRIBUER
Balto et LITF sont open-source :
https://github.com/lothiraldan/litf
https://github.com/lothiraldan/balto