webentwicklung-frage-antwort-db.com.de

Wie drucke ich in pytest auf die Konsole?

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?

120
BBedit

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 ======================
151
tbekolay

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:

  1. 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.

  2. 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 :-).

45
dmitry_romanov

Kurze Antwort

Verwenden Sie die -s Möglichkeit:

pytest -s

Ausführliche Antwort

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

Festlegen von Erfassungsmethoden oder Deaktivieren der Erfassung

Es gibt zwei Möglichkeiten, wie pytest die Erfassung durchführen kann:

  1. Erfassung auf Dateideskriptorebene (Standard): Alle Schreibvorgänge, die zu den Dateideskriptoren 1 und 2 des Betriebssystems gehen, werden erfasst.

  2. 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
13
lmiguelvargasf

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.

10
dmitry_romanov

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.