2017-07-28 5 views
0

私はいくつかの印刷ステートメントを含むコードをテストしたいと思います。私は残念ながらそれを取り除くことはできません。私のアプローチは、テスト中にstdoutをキャプチャし、キャプチャされた出力に対してアサーションを実行することでした。このリダイレクションコードを抽出して、多くのテストケースで使用できるようにしたかったのです。たとえば、このユニットテストコードでstdoutリダイレクトを抽出して、他のテストケースで安全に再利用できるようにするにはどうすればよいですか?

# something.py 

def function(): 
    print("something") 
    return 42 

のような非常に単純な関数は、私は、基本クラスでの標準出力のリダイレクトコードを抽出し、この

import io 
import sys 
import unittest 
import something 

# test_something.py 

class RedirectTestCase(unittest.TestCase): 

    def setUp(self): 
     self.original_stdout = sys.stdout 
     self.temporary_stdout = io.StringIO() 
     sys.stdout = self.temporary_stdout 

    def tearDown(self): 
     sys.stdout = self.original_stdout 

    def assertOutputEqual(self, expected_output): 
     self.temporary_stdout.seek(0) 
     captured_output = self.temporary_stdout.read().strip() 
     self.assertEqual(expected_output, captured_output) 


class TestFunction(RedirectTestCase): 

    def setUp(self): 
     super().setUp() 

    def tearDown(self): 
     super().tearDown() 

    def test_output(self): 
     something.function() 
     self.assertOutputEqual("something") 

    def test_return(self): 
     self.assertEqual(42, something.function()) 


if __name__ == "__main__": 
    unittest.main() 

のようにテストされるだろうが、私は、基本クラスを呼び出して好きではないsetUpと各テストケースの実装におけるtearDownメソッド。このアプローチを複数のテストケースにアクセスできるようにする良い方法はありますか?特に、基本クラスsetUpとtearDownを自動的に呼び出して、テストをよりきれいに、安全にすることは可能ですか?このテスト手法を改善するための他の提案は高く評価されています。

答えて

0

mixinクラスを使用して同様の問題をカバーするNed Betchelderのblog postが見つかりました。私は、このアプローチを使ってテストを再構築しました。コードを独立した部分に分割し、実際のテストケースではsuper()の呼び出しを避けます。

class BaseTestCase(unittest.TestCase): 
    """Base test case.""" 

    def setUp(self): 
     super().setUp() 
     # do basic setup stuff here ... 

    def tearDown(self): 
     # do basic teardown stuff here ... 
     super().tearDown() 

    def assertOutputEqual(self, expected_output): 
     self.temporary_stdout.seek(0) 
     captured_output = self.temporary_stdout.read().strip() 
     self.assertEqual(expected_output, captured_output) 


class RedirectMixin(object): 
    """Mixin class for redirecting stdout on setup and teardown.""" 

    def setUp(self): 
     super().setUp() 
     self.original_stdout = sys.stdout 
     self.temporary_stdout = io.StringIO() 
     sys.stdout = self.temporary_stdout 

    def tearDown(self): 
     sys.stdout = self.original_stdout 
     super().tearDown() 


class TestFunction(RedirectMixin, BaseTestCase): 
    """Actual test case using stdout redirection.""" 

    def test_output(self): 
     something.function() 
     self.assertOutputEqual("something") 

    def test_return(self): 
     self.assertEqual(42, something.function()) 
関連する問題