目次

前のトピックへ

拡張された xUnit スタイルのセットアップフィクスチャ

次のトピックへ

モンキーパッチ/モックのモジュールと環境

標準出力/標準エラーのキャプチャ

デフォルトの stdout/stderr/stdin のキャプチャ処理

テストの実行中 stdoutstderr へ送られる全ての出力内容はキャプチャされます。テストまたはセットアップメソッドが失敗した場合、そこでキャプチャされた出力は、通常、エラートレースバックと一緒に表示されます。

加えて stdin は、その読み込みに失敗する “null” オブジェクトがセットされます。その理由は自動テストを実行するときに対話式の入力を待つのを考慮することはほとんどないからです。

デフォルトのキャプチャは、低レベルのファイルディスクリプタへの書き込みを横取りします。単純な print 文からの出力も、あるテストが生成したサブプロセスからの出力も同じようにキャプチャできます。

メソッドをキャプチャする、または無効にする設定

py.test でキャプチャを実行する方法が2つあります:

  • ファイルディスクリプタ (FD) レベルのキャプチャ (デフォルト): オペレーティングシステムのファイルディスクリプタ1と2への全ての書き込みをキャプチャする
  • sys レベルのキャプチャ: Python ファイル sys.stdoutsys.stderr への書き込みのみキャプチャする、ファイルディスクリプタへの書き込みはキャプチャしない

コマンドラインから出力内容のキャプチャ設定を制御できます:

py.test -s            # 全てのキャプチャを無効にする
py.test --capture=sys # sys.stdout/stderr を in-mem ファイルに置き換える
py.test --capture=fd  # ファイルディスクリプタ1と2を一時ファイルに差し向ける

デバッグに print 文を使う

デフォルトで stdout/stderr の出力をキャプチャする主な利点の1つとして、デバッグに print 文が使えます:

# test_module.py の内容
def setup_function(function):
    print ("setting up %s" % function)

def test_func1():
    assert True

def test_func2():
    assert False

このモジュールを実行すると、失敗するテスト関数の出力を適切に表示して、成功するもう1つのテストを非表示にします:

$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
collecting ... collected 2 items

test_module.py .F

================================= FAILURES =================================
________________________________ test_func2 ________________________________

    def test_func2():
>       assert False
E       assert False

test_module.py:9: AssertionError
----------------------------- Captured stdout ------------------------------
setting up <function test_func2 at 0x20160c8>
==================== 1 failed, 1 passed in 0.01 seconds ====================

テスト関数からキャプチャされた出力へのアクセス

関数の引数を使った依存性の注入 により、テスト関数のシグネチャに capsys または capfd という名前を使うだけで、簡単にキャプチャされた出力へアクセスできます。次に関連する値の確認を行うテスト関数のサンプルを紹介します:

def test_myoutput(capsys): # または fd レベルの "capfd" を使う
    print ("hello")
    sys.stderr.write("world\n")
    out, err = capsys.readouterr()
    assert out == "hello\n"
    assert err == "world\n"
    print "next"
    out, err = capsys.readouterr()
    assert out == "next\n"

readouterr() 呼び出しは、その時点での出力内容のスナップショットを返し、その後もキャプチャが続行されます。テスト関数が終了した後、元のストリームが復元されます。 capsys を使うことで、テスト内で出力ストリームをセット/リセットすることに注意を払わなくてよくなります。また、pytest が保持するテスト単位のキャプチャも扱えます。

fd レベルのキャプチャを行う場合も全く同じインターフェースを提供する capfd という関数の引数を使います。