Pythonはどうやってstdout出力をテストしますか?


問題
あなたのプログラムには標準出力に出力する方法があります。つまり、テキストはスクリーンの上に印刷されます。テストを書いて証明したいです。入力が与えられています。出力は正常に表示されます。
ソリューション
unittest.mockモジュールのpatch()関数を使用すると非常に簡単で、単一テストのためにsys.stdoutを模擬してからロールバックし、大量の一時変数を発生しない、またはテストの用例で直接状態変数を暴露することができます。
一例として、私たちはmymoduleモジュールで次の関数を定義します。

# mymodule.py

def urlprint(protocol, host, domain):
  url = '{}://{}.{}'.format(protocol, host, domain)
  print(url)
デフォルトで内蔵されているprint関数は、sys.stdoutに出力されます。出力をテストするために本当にそこにいます。身代わりの対象を使ってシミュレーションして、判定を使って結果を確認してください。unittest.mockモジュールのpatch()を使用すると、テスト動作のコンテキストでオブジェクトを交換しやすくなり、テストが完了すると自動的に元の状態に戻ります。以下はmymoduleモジュールのテストコードです。

from io import StringIO
from unittest import TestCase
from unittest.mock import patch
import mymodule

class TestURLPrint(TestCase):
  def test_url_gets_to_stdout(self):
    protocol = 'http'
    host = 'www'
    domain = 'example.com'
    expected_url = '{}://{}.{}
'.format(protocol, host, domain) with patch('sys.stdout', new=StringIO()) as fake_out: mymodule.urlprint(protocol, host, domain) self.assertEqual(fake_out.getvalue(), expected_url)
討論する
urlprint関数は3つのパラメータを受け取ります。テスト方法は最初に各パラメータの値を設定します。expected_url変数は、所望の出力を含む文字列に設定されます。
unittest.mock.patch()関数をコンテキストマネージャとして使用し、sys.stdout.fake_の代わりにStrigIOオブジェクトを使用します。out変数は、このプロセスで作成されたアナログオブジェクトです。with文では様々な検査ができます。with文が終わると、patchはすべてのものをテスト開始前の状態に戻します。いくつかのPythonに対するC拡張は、sys.stdoutの構成を無視して標準出力に直接書き込むことができるので注意が必要です。紙面に限られていますが、今回はこの方面の解説には触れません。Pythonコードを使っています。本当にC拡張でI/Oを捕捉する必要があるなら、一時ファイルを開いてから標準出力をファイルにリダイレクトしてもいいです。
以上はPythonがどのようにstdout出力の詳細をテストしますか?Pythonテストstdout出力の詳細については、他の関連記事に注目してください。