it-swarm.com.de

Wie kann ich während des Pytest-Laufs normale Druckausgaben sehen?

Manchmal möchte ich nur einige Druckanweisungen in meinen Code einfügen und sehen, was gedruckt wird, wenn ich es ausführe. Meine übliche Art zu "trainieren" ist mit den bestehenden Tests. Aber wenn ich diese ausführe, kann ich keine Standardausgabe sehen (zumindest in PyCharm, meiner IDE).

Gibt es eine einfache Möglichkeit, die Standardausgabe während eines Pytest-Laufs zu sehen?

223
Des

Der -s-Schalter deaktiviert das Pro-Test-Capturing.

320
hpk42

In einem hochgestuften Kommentar zu akzeptierte Antwort fragt Joe :

Gibt es eine Möglichkeit, auf die Konsole zu drucken [~ # ~] und [~ # ~] die Ausgabe so zu erfassen, dass sie im junit-Bericht angezeigt wird?

In UNIX wird dies allgemein als Abschlag bezeichnet. Im Idealfall ist das Abschlagen und nicht das Erfassen der Standardeinstellung von py.test. Nicht idealerweise unterstützt weder py.test noch ein vorhandenes py.test-Plugin eines Drittanbieters (... , von dem ich sowieso weiß ) das Abschlagen - trotz Python trivial unterstützendes Abschlagen out-of-the-box .

Monkey-Patching py.test zu tun alles nicht unterstützt ist nicht trivial. Warum? Weil:

  • Die meiste py.test-Funktionalität ist hinter einem privaten _pytest - Paket gesperrt nicht das extern importiert werden soll. Der Versuch, dies zu tun, ohne zu wissen, was Sie tun, führt normalerweise dazu, dass das öffentliche Paket pytest zur Laufzeit unklare Ausnahmen auslöst.  Vielen Dank, py.test. Wirklich robuste Architektur, die Sie dort erhalten haben.
  • Auch wenn Sie do herausfinden, wie Sie die private _pytest - API auf sichere Weise mit Affen patchen können, müssen Sie dies tun before Ausführen des öffentlichen Pakets pytest, das vom externen Befehl py.test ausgeführt wird. Sie können kann nicht in einem Plug-in ausführen (z. B. einem conftest-Modul der obersten Ebene in Ihrer Testsuite). Zu dem Zeitpunkt, an dem py.test sein Plugin nur mühsam dynamisch importiert, ist jede py.test-Klasse, die Sie monkey-patchen wollten, längst instanziiert - und Sie haben nicht Zugriff zu dieser Instanz. Dies bedeutet, dass Sie den externen Befehl py.test Nicht mehr sicher ausführen können, wenn Ihr Affen-Patch sinnvoll angewendet werden soll. Stattdessen müssen Sie die Ausführung dieses Befehls mit einem benutzerdefinierten Befehl setuptools test abschließen, der (in der angegebenen Reihenfolge):
    1. Monkey-Patches der privaten _pytest API.
    2. Ruft die öffentliche Funktion pytest.main() auf, um den Befehl py.test Auszuführen.

Diese Antwort ändert die Optionen -s Und --capture=no Von py.test, um stderr, aber nicht stdout zu erfassen. Standardmäßig erfassen diese Optionen weder stderr noch stdout. Das ist natürlich nicht so schlimm. Aber jede große Reise beginnt mit einem mühsamen Vorspiel, das jeder in fünf Jahren vergisst.

Warum das machen? Ich werde es dir jetzt sagen. Meine py.test-gesteuerte Testsuite enthält langsame Funktionstests. Die Anzeige der Standardanzahl dieser Tests ist hilfreich und beruhigend und verhindert, dass leycec nach killall -9 py.test Greift, wenn ein erneuter, lang andauernder Funktionstest wochenlang nichts unternimmt. Durch die Anzeige des Stderr dieser Tests wird jedoch verhindert, dass py.test Exception-Tracebacks bei Testfehlern meldet. Welches ist völlig wenig hilfreich. Daher zwingen wir py.test, stderr aber nicht stdout zu erfassen.

In dieser Antwort wird vorausgesetzt, dass Sie bereits einen benutzerdefinierten Befehl setuptools test haben, der py.test aufruft. Wenn nicht, lesen Sie den Unterabschnitt Manual Integration in py.test's gut geschriebenem Good Practices Seite.

Do not install pytest-runner , ein Setuptools-Plugin eines Drittanbieters, das einen benutzerdefinierten Befehl setuptools test bereitstellt und auch py.test aufruft. Wenn pytest-runner bereits installiert ist, müssen Sie dieses pip3-Paket wahrscheinlich deinstallieren und dann den oben genannten manuellen Ansatz anwenden.

Angenommen, Sie haben die Anweisungen in Manual Integration wie oben hervorgehoben befolgt, sollte Ihre Codebasis jetzt eine PyTest.run_tests() -Methode enthalten. Ändern Sie diese Methode, um zu ähneln:

class PyTest(TestCommand):
             .
             .
             .
    def run_tests(self):
        # Import the public "pytest" package *BEFORE* the private "_pytest"
        # package. While importation order is typically ignorable, imports can
        # technically have side effects. Tragicomically, that is the case here.
        # Importing the public "pytest" package establishes runtime
        # configuration required by submodules of the private "_pytest" package.
        # The former *MUST* always be imported before the latter. Failing to do
        # so raises obtuse exceptions at runtime... which is bad.
        import pytest
        from _pytest.capture import CaptureManager, FDCapture, MultiCapture

        # If the private method to be monkey-patched no longer exists, py.test
        # is either broken or unsupported. In either case, raise an exception.
        if not hasattr(CaptureManager, '_getcapture'):
            from distutils.errors import DistutilsClassError
            raise DistutilsClassError(
                'Class "pytest.capture.CaptureManager" method _getcapture() '
                'not found. The current version of py.test is either '
                'broken (unlikely) or unsupported (likely).'
            )

        # Old method to be monkey-patched.
        _getcapture_old = CaptureManager._getcapture

        # New method applying this monkey-patch. Note the use of:
        #
        # * "out=False", *NOT* capturing stdout.
        # * "err=True", capturing stderr.
        def _getcapture_new(self, method):
            if method == "no":
                return MultiCapture(
                    out=False, err=True, in_=False, Capture=FDCapture)
            else:
                return _getcapture_old(self, method)

        # Replace the old with the new method.
        CaptureManager._getcapture = _getcapture_new

        # Run py.test with all passed arguments.
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

Um diesen Affen-Patch zu aktivieren, führen Sie py.test wie folgt aus:

python setup.py test -a "-s"

Stderr aber nicht stdout wird jetzt erfasst. Raffiniert!

Die Ausweitung des oben genannten Affenfeldes auf Tee stdout und stderr wird dem Leser als Übung mit einem Fass voller Freizeit überlassen.

46
Cecil Curry

Gemäß pytest-Dokumentation kann Version 3 von pytest die Erfassung in einem Test vorübergehend deaktivieren:

def test_disabling_capturing(capsys):
    print('this output is captured')
    with capsys.disabled():
        print('output not captured, going directly to sys.stdout')
    print('this output is also captured')
20
Roman Susi

Wenn Sie den Test ausführen, verwenden Sie die -s-Option. Alle Druckanweisungen in exampletest.py werden auf der Konsole gedruckt, wenn der Test ausgeführt wird.

py.test exampletest.py -s
18
Summerfun

Versuchen Siepytest -s -v test_login.pyfür weitere Informationen in der Konsole.

-ves ist eine kurze--verbose

-sbedeutet "Alle Aufnahmen deaktivieren"



8
Alex Makarenko

Wenn Sie die PyCharm IDE verwenden, können Sie diesen einzelnen Test oder alle Tests mithilfe der Symbolleiste ausführen ausführen. Das Run-Tool-Fenster zeigt die von Ihrer Anwendung generierte Ausgabe an, und Sie können alle Druckanweisungen darin als Teil der Testausgabe anzeigen.

0
Gemini Jain
pytest -v -s scriptname(for single test script)

pytest -v -s (for complete module/package)

pytest -v -s scriptname::function(indiviual function)
0
v.k

Die anderen Antworten funktionieren nicht. Die nur Methode zum Anzeigen der erfassten Ausgabe verwendet das folgende Flag:

pytest --show-capture all

0
aaa90210