1

Resource次のダミークラスを検討してください。

import pytest


class Resource:

    def __init__(self, param):
        self.param = param
        print "\nResource created", self.param, self

    def __del__(self):
        print "Resource deleted", self.param, self

すべてのテストケースの前に作成し、テストケースの後に完全に初期化したいリソースをエミュレートします。古いスタイルの funcargs を使用して、次のようなテストを作成します。

def pytest_funcarg__resource_fa(request):
    res = Resource(request.param)
    return res

def pytest_generate_tests(metafunc):
    metafunc.parametrize("resource_fa", [1, 2], indirect=True)

def test_funcarg_resource(resource_fa):
    print "Testcase: resource", resource_fa.param

を実行するpy.test -s -vと、次の出力が得られます。

============================================ test session starts =============================================
platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /usr/bin/python
plugins: cov
collected 2 items 

test_factory.py:48: test_funcarg_resource[1] 
Resource created 1 <test_factory.Resource instance at 0x292cab8>
Testcase: resource 1
PASSED
test_factory.py:48: test_funcarg_resource[2] 
Resource created 2 <test_factory.Resource instance at 0x292cfc8>
Testcase: resource 2
PASSED

========================================== 2 passed in 0.01 seconds ==========================================

ご覧のとおり__del__、両方のリソースの が呼び出されていません。新しいスタイルのフィクスチャを使用すると、同じ動作が観察されます。

@pytest.fixture(scope="function", params=[1, 2])
def resource_fx(request):
    res = Resource(request.param)
    return res

def test_fixture_resource(resource_fx):
    print "Testcase: resource", resource_fx.param

もちろん、カスタム ファイナライザーを追加して、リソース内で初期化解除が必要なものを強制的に初期化解除することもできますが、これは少し冗長__del__だと思います。テストケースが終了した場合にPy.Test参照を保持する必要がある理由を確認してください。resの予想される動作Py.Testですか、それともバグを報告する必要がありますか?

4

1 に答える 1

2

__del__ファイナライズはガベージ コレクション サイクル (Python の実装によって異なる) によってトリガーされるため、ファイナライズに依存することはお勧めできません。pytest では、通常request.addfinalizer(resource.finalize)、resource/funcarg ファクトリから呼び出して、ファイナライザー関数を適切に呼び出します。pytest は、GC の詳細から独立したファイナライズを保証します。

于 2013-02-21T15:37:41.513 に答える