web-dev-qa-db-ja.com

py.testの各テストの前後にコードを実行しますか?

テストスイートの各テストの前後に追加のセットアップとティアダウンチェックを実行したい。私はフィクスチャを見ましたが、それらが正しいアプローチであるかどうかはわかりません。各テストの前にセットアップコードを実行する必要があり、各テストの後にティアダウンチェックを実行する必要があります。

私のユースケースは、正しくクリーンアップしないコードをチェックしています:一時ファイルを残します。セットアップではファイルをチェックし、分解ではファイルもチェックします。余分なファイルがある場合、テストを失敗させます。

38

py.testフィクスチャは、目的を達成するための技術的に適切な方法です。

次のようなフィクスチャを定義する必要があります。

@pytest.fixture(autouse=True)
def run_around_tests():
    # Code that will run before your test, for example:
    files_before = # ... do something to check the existing files
    # A test function will be run at this point
    yield
    # Code that will run after your test, for example:
    files_after = # ... do something to check the existing files
    assert files_before == files_after

autouse=Trueでフィクスチャを宣言することにより、同じモジュールで定義された各テスト関数に対してフィクスチャが自動的に呼び出されます。

ただし、注意点が1つあります。セットアップ/ティアダウンでのアサートは、物議を醸す実践です。私はpy.testの主な著者がそれを好まないという印象を受けています(私もそれが好きではないので、私自身の知覚を色づけるかもしれません)。

49
tawmas

フィクスチャはまさにあなたが望むものです。それは彼らが設計されたものです。

pytestスタイルフィクスチャ、またはsetupおよびteardown(モジュール、クラス、またはメソッドレベル)xUnitスタイルのフィクスチャは、状況と個人の好みに依存します。

あなたが説明していることから、 pytest autouse Fixtures を使用できるように思えます。
またはxUnitスタイルの関数レベル setup_function()/ teardown_function()

Pytestは完全にカバーしています。あまりにも多くの情報があるので、たぶんそれは情報の消火ホースです。

8
Okken

デコレータを使用することはできますが、プログラムで行うため、各メソッドにデコレータを配置する必要はありません。

私は次のコードでいくつかのことを想定しています:

テストメソッドはすべて次のように名前が付けられます: "testXXX()"デコレータは、テストメソッドが実装されている同じモジュールに追加されます。

_def test1():
    print ("Testing hello world")

def test2():
    print ("Testing hello world 2")

#This is the decorator
class TestChecker(object):
    def __init__(self, testfn, *args, **kwargs):
        self.testfn = testfn

    def pretest(self):
        print ('precheck %s' % str(self.testfn))
    def posttest(self):
        print ('postcheck %s' % str(self.testfn))
    def __call__(self):
        self.pretest()
        self.testfn()
        self.posttest()


for fn in dir() :
    if fn.startswith('test'):
        locals()[fn] = TestChecker(locals()[fn])
_

テストメソッドを呼び出すと...

_test1()
test2()
_

出力は次のようになります。

_precheck <function test1 at 0x10078cc20>
Testing hello world
postcheck <function test1 at 0x10078cc20>
precheck <function test2 at 0x10078ccb0>
Testing hello world 2
postcheck <function test2 at 0x10078ccb0>
_

クラスメソッドとしてテストメソッドがある場合、このアプローチも有効です。例えば:

_class TestClass(object):
    @classmethod
    def my_test(cls):
        print ("Testing from class method")

for fn in dir(TestClass) :
    if not fn.startswith('__'):
        setattr(TestClass, fn, TestChecker(getattr(TestClass, fn)))
_

TestClass.my_test()の呼び出しは次を出力します:

_precheck <bound method type.my_test of <class '__main__.TestClass'>>
Testing from class method 
postcheck <bound method type.my_test of <class '__main__.TestClass'>>
_
5
Roberto

Pytestのモジュールレベルのセットアップ/ティアダウンフィクスチャを使用できます。

リンクはこちら

http://pytest.org/latest/xunit_setup.html

次のように機能します。

 def setup_module(module):
     """ setup any state specific to the execution of the given module."""

 def teardown_module(module):
     """ teardown any state that was previously setup with a setup_module
     method."""

 Test_Class():
        def test_01():
          #test 1 Code

このテストの前にsetup_moduleを呼び出し、テストの完了後にteardown_moduleを呼び出します。

このフィクスチャを各テストスクリプトに含めて、テストごとに実行できます。

ディレクトリ内のすべてのテストに共通するものを使用する場合パッケージ/ディレクトリレベルのフィクスチャノーズフレームワークを使用できます。

http://pythontesting.net/framework/nose/nose-fixture-reference/#package

パッケージの__init__.pyファイルには、以下を含めることができます

     def setup_package():
       '''Set up your environment for test package'''

     def teardown_package():
        '''revert the state '''
5
Arvind

備品にはデフォルトでscope=function。したがって、次のような定義を使用する場合

@pytest.fixture
def fixture_func(self)

デフォルトは(scope='function')

したがって、フィクスチャ関数のファイナライズは、各テストの後に呼び出されます。

参照:1. http://programeveryday.com/post/pytest-creating-and-using-fixtures-for-streamlined-testing/

0
alpha_989