テストの実行中 stdout と stderr へ送られる全ての出力内容はキャプチャされます。テストまたはセットアップメソッドが失敗した場合、そこでキャプチャされた出力は、通常、エラートレースバックと一緒に表示されます。
加えて stdin は、その読み込みに失敗する “null” オブジェクトがセットされます。その理由は自動テストを実行するときに対話式の入力を待つのを考慮することはほとんどないからです。
デフォルトのキャプチャは、低レベルのファイルディスクリプタへの書き込みを横取りします。単純な print 文からの出力も、あるテストが生成したサブプロセスからの出力も同じようにキャプチャできます。
py.test でキャプチャを実行する方法が2つあります:
コマンドラインから出力内容のキャプチャ設定を制御できます:
py.test -s # 全てのキャプチャを無効にする
py.test --capture=sys # sys.stdout/stderr を in-mem ファイルに置き換える
py.test --capture=fd # ファイルディスクリプタ1と2を一時ファイルに差し向ける
デフォルトで 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 という関数の引数を使います。