web-dev-qa-db-ja.com

pytestの実行中に作成された通常の印刷出力を見るにはどうすればいいですか?

ときどき自分のコードにprintステートメントをいくつか挿入して、それを実行したときに何が出力されるのかを確認したいことがあります。それを「行使」するための私の通常の方法は、既存のpytestテストを使うことです。しかし、これらを実行しても、(少なくとも私のIDEのPyCharmからは)標準出力を見ることができないようです。

Pytestの実行中に標準出力を見る簡単な方法はありますか?

271
Des

-sスイッチ はテスト毎のキャプチャを無効にします。

377
hpk42

賛成のコメント受け入れられた答えJoe に尋ねる:

コンソールに出力する方法はありますかANDは出力をキャプチャして、junitレポートに表示しますか?

UNIXでは、これは一般に teeing と呼ばれます。理想的には、キャプチャではなくティーイングがpy.testのデフォルトになります。理想的ではない、py.testも既存のサードパーティpy.testプラグイン(...とにかく知っている)は、ティーをサポートします-Pythonティーを簡単にサポートします すぐに使える

サポートされていないanythingを行うモンキーパッチpy.testは重要です。どうして?なぜなら:

  • ほとんどのpy.test機能は、外部からインポートすることを目的としたプライベート_pytestパッケージnotの背後でロックされています。あなたが何をしているのか知らずにそうしようとすると、通常、パブリックpytestパッケージが実行時にあいまいな例外を発生させます。 py.testに感謝します。本当に堅牢なアーキテクチャです。
  • doがプライベート_pytest AP​​Iを安全な方法でモンキーパッチする方法を見つけたとしても、パブリックpytestを実行する必要がありますbefore外部py.testコマンドによって実行されるパッケージ。プラグインでこれを行うできません(たとえば、テストスイートの最上位conftestモジュール)。 py.testがプラグインを動的にインポートするまでに時間が経つ頃には、モンキーパッチにしたいpy.testクラスはインスタンス化されてからずっと経ち、そのインスタンスにnotアクセスできます。これは、モンキーパッチを有意義に適用したい場合、外部py.testコマンドを安全に実行できないことを意味します。代わりに、そのコマンドの実行をカスタムsetuptools testコマンドでラップする必要があります(順番に):
    1. プライベート_pytest AP​​Iをサルパッチします。
    2. Public pytest.main()関数を呼び出して、py.testコマンドを実行します。

この回答は、py.testの-sおよび--capture=noオプションを標準パッチに適用しますが、not stdoutです。デフォルトでは、これらのオプションはstderrもstdoutもキャプチャしません。もちろん、これはかなりの量ではありません。しかし、素晴らしい旅はすべて、5年後に誰もが忘れる退屈な前編から始まります。

どうしてですか?私は今あなたに伝えましょう。 py.test-drivenテストスイートには、低速の機能テストが含まれています。これらのテストの標準出力を表示することは有用で安心です。また、別の長時間実行される機能テストが何週間も続けて失敗した場合に leyceckillall -9 py.testに到達しないようにします。ただし、これらのテストの標準エラーを表示すると、テストの失敗時にpy.testが例外トレースバックを報告できなくなります。これはまったく役に立ちません。したがって、py.testを強制してstderrをキャプチャしますが、not stdoutをキャプチャします。

ここに進む前に、この回答では、py.testを呼び出すカスタムsetuptools testコマンドが既にあると仮定しています。そうでない場合は、py.testのよく書かれた Good Practices ページの Manual Integration サブセクションを参照してください。

not install pytest-runner を実行します。これは、py.testを呼び出すカスタムsetuptools testコマンドを提供するサードパーティのsetuptoolsプラグインです。 pytest-runnerが既にインストールされている場合、おそらくそのpip3パッケージをアンインストールしてから、上記にリンクされている手動のアプローチを採用する必要があります。

上記の 手動統合 の指示に従ったとすると、コードベースにはPyTest.run_tests()メソッドが含まれているはずです。このメソッドを次のように変更します。

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)

このモンキーパッチを有効にするには、次のようにpy.testを実行します。

python setup.py test -a "-s"

Stderrがnot stdoutがキャプチャされるようになりました。気の利いた!

上記のモンキーパッチをtee stdoutとstderrに拡張することは、自由な時間をたっぷり使って読者に練習として残されます。

46
Cecil Curry

pytest documentation によると、pytestのバージョン3はテストのキャプチャを一時的に無効にすることができます:

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

テストを実行するときは-sオプションを使用してください。 testが実行されると、exampletest.py内のすべてのprintステートメントはコンソールに表示されます。

py.test exampletest.py -s
19
Summerfun

コンソールの詳細については、pytest -s -v test_login.pyを試してください。

-v短いです--verbose

-sは「すべてのキャプチャを無効にする」という意味です。



8
Alex Makarenko

あなたがPyCharm IDEを使用しているならば、あなたはそれから個々のテストを実行するか、またはツールバーの実行を使ってすべてのテストを実行することができます。 [実行]ツールウィンドウには、アプリケーションによって生成された出力が表示され、そこにあるすべてのprintステートメントをテスト出力の一部として見ることができます。

1
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

他の答えはうまくいきません。キャプチャされた出力を表示するのみの方法は、次のフラグを使うことです。

pytest --show-capture all

0
aaa90210