J'essaie d'utiliser TDD (développement piloté par les tests) avec pytest
. pytest
ne sera pas print
sur la console lorsque j'utilise print
.
J'utilise pytest my_tests.py
pour l'exécuter.
La documentation
semble indiquer que cela devrait fonctionner par défaut: http://pytest.org/latest/capture.html
Mais:
import myapplication as tum
class TestBlogger:
@classmethod
def setup_class(self):
self.user = "alice"
self.b = tum.Blogger(self.user)
print "This should be printed, but it won't be!"
def test_inherit(self):
assert issubclass(tum.Blogger, tum.Site)
links = self.b.get_links(posts)
print len(links) # This won't print either.
Rien ne s'imprime sur ma console de sortie standard (uniquement la progression normale et le nombre de tests réussis/échoués).
Et le script que je teste contient print:
class Blogger(Site):
get_links(self, posts):
print len(posts) # It won't get printed in the test.
Dans le module unittest
, tout est imprimé par défaut, ce qui est exactement ce dont j'ai besoin. Cependant, je souhaite utiliser pytest
pour d'autres raisons.
Quelqu'un sait-il comment faire en sorte que les déclarations imprimées soient affichées?
Par défaut, py.test
capture le résultat de la sortie standard afin qu'il puisse contrôler la façon dont il est imprimé. Si cela ne fonctionnait pas, cela générerait beaucoup de texte sans le contexte du test imprimé.
Toutefois, si un test échoue, il inclura une section dans le rapport résultant indiquant ce qui a été imprimé conformément à la norme dans ce test particulier.
Par exemple,
def test_good():
for i in range(1000):
print(i)
def test_bad():
print('this should fail!')
assert False
Résultats dans la sortie suivante:
>>> py.test tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items
tmp.py .F
=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________
def test_bad():
print('this should fail!')
> assert False
E assert False
tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================
Notez la section Captured stdout
.
Si vous souhaitez voir les instructions print
au fur et à mesure de leur exécution, vous pouvez passer l'indicateur -s
à py.test
. Cependant, notez que cela peut parfois être difficile à analyser.
>>> py.test tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items
tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F
=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________
def test_bad():
print('this should fail!')
> assert False
E assert False
tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================
L'utilisation de l'option -s
imprimera le résultat de toutes les fonctions, ce qui peut être trop.
Si vous avez besoin de résultats particuliers, la page de documentation que vous avez mentionnée offre quelques suggestions:
Insérez assert False, "dumb assert to make PyTest print my stuff"
à la fin de votre fonction et vous verrez votre sortie en raison d’un échec du test.
PyTest vous a transmis un objet spécial et vous pouvez écrire la sortie dans un fichier pour l'inspecter ultérieurement, comme
def test_good1(capsys):
for i in range(5):
print i
out, err = capsys.readouterr()
open("err.txt", "w").write(err)
open("out.txt", "w").write(out)
Vous pouvez ouvrir les fichiers out
et err
dans un onglet séparé et laisser l’éditeur l’actualiser automatiquement, ou exécuter une simple commande py.test; cat out.txt
Shell pour exécuter votre test.
C’est une façon plutôt rigoureuse de faire des choses, mais c’est peut-être ce dont vous avez besoin: après tout, TDD signifie que vous jouez avec des choses et que vous les laissez propres et silencieuses quand elles sont prêtes :-).
Utilisez l'option -s
:
pytest -s
De les docs :
Pendant l'exécution du test, toute sortie envoyée à stdout et à stderr est capturée. Si un test ou une méthode de configuration échoue, sa sortie capturée sera généralement affichée avec le suivi des défaillances.
pytest
a l'option --capture=method
dans lequel method
est une méthode de capture par test et peut être l'un des suivants: fd
, sys
ou no
. pytest
a également l'option -s
qui est un raccourci pour --capture=no
, et cette option vous permettra de voir vos instructions d'impression dans la console.
pytest --capture=no # show print statements in console
pytest -s # equivalent to previous command
pytest
peut effectuer la capture de deux manières:
capture de niveau de descripteur de fichier (FD) (par défaut): toutes les écritures destinées aux descripteurs de fichier du système d'exploitation 1 et 2 seront capturées.
capture de niveau sys : seules les écritures dans Python fichiers _sys.stdout et sys.stderr seront capturées. Aucune capture des écritures dans les archives de fichiers n'est effectuée.
pytest -s # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd # also point filedescriptors 1 and 2 to temp file
J'avais besoin d'imprimer un avertissement important concernant les tests ignorés au moment exact où PyTest
était coupé littéralement tout.
Je ne voulais pas échouer à un test pour envoyer un signal, alors j'ai fait un hack comme suit:
def test_2_YellAboutBrokenAndMutedTests():
import atexit
def report():
print C_patch.tidy_text("""
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.""")
if sys.stdout != sys.__stdout__:
atexit.register(report)
Le module atexit
me permet d’imprimer des choses après que PyTest
ait libéré les flux de sortie. La sortie se présente comme suit:
============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /media/Storage/henaro/smyth/Alchemist2-git/sources/C_patch, inifile:
collected 15 items
test_C_patch.py .....ssss....s.
===================== 10 passed, 5 skipped in 0.15 seconds =====================
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.
~/.../sources/C_patch$
Le message est imprimé même lorsque PyTest
est en mode silencieux et est non imprimé si vous exécutez des commandes avec py.test -s
, donc tout est déjà bien testé.
Selon le pytest docs , pytest --capture=sys
devrait fonctionner. Si vous souhaitez capturer la norme dans un test, reportez-vous à la page d’installation de Capsys.