Ich versuche, TDD (testgetriebene Entwicklung) mit pytest
zu verwenden. pytest
wird nicht print
an die Konsole gesendet, wenn ich print
verwende.
Ich benutze pytest my_tests.py
, um es auszuführen.
Das documentation
scheint zu sagen, dass es standardmäßig funktionieren soll: http://pytest.org/latest/capture.html
Aber:
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.
Auf meiner Standard-Ausgabekonsole wird nichts gedruckt (nur der normale Fortschritt und die Anzahl der bestandenen/fehlgeschlagenen Tests).
Und das Skript, das ich teste, enthält print:
class Blogger(Site):
get_links(self, posts):
print len(posts) # It won't get printed in the test.
Im unittest
Modul wird standardmäßig alles gedruckt, genau das, was ich brauche. Ich möchte jedoch pytest
aus anderen Gründen verwenden.
Weiß jemand, wie die print-Anweisungen angezeigt werden?
Standardmäßig, py.test
erfasst das Ergebnis der Standardausgabe, damit es steuern kann, wie es ausgedruckt wird. Wenn es dies nicht tun würde, würde es viel Text ausspucken, ohne den Kontext dessen, welcher Test diesen Text druckte.
Wenn ein Test jedoch fehlschlägt, enthält der resultierende Bericht einen Abschnitt, in dem angegeben ist, was in diesem bestimmten Test als Standard ausgegeben wurde.
Beispielsweise,
def test_good():
for i in range(1000):
print(i)
def test_bad():
print('this should fail!')
assert False
Ergebnisse in der folgenden Ausgabe:
>>> 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 ======================
Beachten Sie das Captured stdout
Sektion.
Wenn Sie die Anweisungen print
sehen möchten, während sie ausgeführt werden, können Sie die Anweisungen -s
flag to py.test
. Beachten Sie jedoch, dass dies manchmal schwierig zu analysieren ist.
>>> 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 ======================
Mit der Option -s
Werden alle Funktionen ausgegeben, die möglicherweise zu umfangreich sind.
Wenn Sie eine bestimmte Ausgabe benötigen, bietet die von Ihnen erwähnte Dokumentseite einige Vorschläge:
Geben Sie am Ende Ihrer Funktion assert False, "dumb assert to make PyTest print my stuff"
Ein, und Sie sehen Ihre Ausgabe aufgrund eines fehlgeschlagenen Tests.
Sie haben ein spezielles Objekt von PyTest erhalten, und Sie können die Ausgabe in eine Datei schreiben, um sie später zu überprüfen, wie z
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)
Sie können die Dateien out
und err
auf einer separaten Registerkarte öffnen und vom Editor automatisch aktualisieren lassen oder einen einfachen Shell-Befehl py.test; cat out.txt
Ausführen, um den Test auszuführen.
Das ist eine ziemlich hackige Art, Dinge zu tun, aber vielleicht ist es das, was Sie brauchen: TDD bedeutet schließlich, dass Sie mit Dingen herumspielen und es sauber und leise lassen, wenn es fertig ist :-).
Verwenden Sie die -s
Möglichkeit:
pytest -s
Von den Dokumenten :
Während der Testausführung werden alle an stdout und stderr gesendeten Ausgaben erfasst. Wenn ein Test oder eine Einrichtungsmethode fehlschlägt, wird die entsprechende erfasste Ausgabe in der Regel zusammen mit dem Fehlerverfolgungsprotokoll angezeigt.
pytest
hat die Option --capture=method
wobei method
eine testweise Erfassungsmethode ist und eine der folgenden sein kann: fd
, sys
oder no
. pytest
hat auch die Option -s
das ist eine Abkürzung für --capture=no
, und dies ist die Option, mit der Sie Ihre Druckanweisungen in der Konsole anzeigen können.
pytest --capture=no # show print statements in console
pytest -s # equivalent to previous command
Es gibt zwei Möglichkeiten, wie pytest
die Erfassung durchführen kann:
Erfassung auf Dateideskriptorebene (Standard): Alle Schreibvorgänge, die zu den Dateideskriptoren 1 und 2 des Betriebssystems gehen, werden erfasst.
sys level capture : Nur Schreibvorgänge in die Dateien Python= sys.stdout und sys.stderr werden erfasst Schreibvorgänge in Filedescriptors werden ausgeführt.
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
Ich musste wichtige Warnungen zu übersprungenen Tests genau dann ausgeben, wenn PyTest
buchstäblich stummgeschaltet war alles.
Ich wollte keinen Test bestehen, um ein Signal zu senden, also habe ich einen Hack wie folgt durchgeführt:
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)
Das Modul atexit
ermöglicht mir das Drucken von Material , nachdem PyTest
die Ausgabestreams freigegeben hat. Die Ausgabe sieht wie folgt aus:
============================= 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$
Die Nachricht wird gedruckt, auch wenn sich PyTest
im unbeaufsichtigten Modus befindet, und wird nicht gedruckt, wenn Sie Dinge mit py.test -s
Ausführen. also ist schon alles schön getestet.
Nach den pytest docs , pytest --capture=sys
sollte arbeiten. Wenn Sie den Standard innerhalb eines Tests erfassen möchten, beziehen Sie sich auf das Capsys-Gerät.