web-dev-qa-db-ja.com

pytestでは、conftest.pyファイルの使用は何ですか?

最近pytestを発見しました。素晴らしいようです。ただし、ドキュメントの方が優れていると思います。

conftest.pyファイルの用途を理解しようとしています。

私の(現在は小さな)テストスイートでは、プロジェクトルートにconftest.pyファイルが1つあります。これを使用して、テストに注入するフィクスチャを定義します。

2つの質問があります。

  1. これはconftest.pyの正しい使用ですか?他の用途がありますか?
  2. 複数のconftest.pyファイルを使用できますか?いつそれをしたいですか?例が評価されます。

より一般的には、py.testテストスイートでconftest.pyファイルの目的と正しい使用をどのように定義しますか?

140
Aviv Cohn

これはconftest.pyの正しい使用ですか?

はい、そうです。フィクスチャはconftest.pyの潜在的で一般的な使用法です。定義するフィクスチャは、テストスイートのすべてのテストで共有されます。ただし、ルートconftest.pyでフィクスチャを定義することは役に立たない場合があり、そのようなフィクスチャがすべてのテストで使用されない場合、テストの速度が低下します。

他の用途がありますか?

はい、そうです。

  • フィクスチャ:テストで使用される静的データのフィクスチャを定義します。このデータは、特に指定がない限り、スイート内のすべてのテストからアクセスできます。これは、すべてのテストに渡されるモジュールのヘルパーと同様にデータである可能性があります。

  • 外部プラグインの読み込みconftest.pyは、外部プラグインまたはモジュールのインポートに使用されます。次のグローバル変数を定義することにより、pytestはモジュールをロードし、そのテストに使用できるようにします。プラグインは通常、プロジェクトで定義されたファイル、またはテストに必要な他のモジュールです。 here の説明に従って、事前定義されたプラグインのセットをロードすることもできます。

    pytest_plugins = "someapp.someplugin"

  • フック:テストを改善するために、セットアップメソッドやティアダウンメソッドなどのフックを指定できます。使用可能なフックのセットについては、 here をお読みください。例:

    def pytest_runtest_setup(item):
         """ called before ``pytest_runtest_call(item). """
         #do some stuff`
    
  • ルートパスのテスト:これは少し隠された機能です。ルートパスでconftest.pyを定義すると、pytestを指定せずにPYTHONPATHがアプリケーションモジュールを認識するようになります。バックグラウンドで、py.testはルートパスから見つかったすべてのサブモジュールを含めることでsys.pathを変更します。

Conftest.pyファイルを複数持つことはできますか?

はい、できます。テスト構造がやや複雑な場合は強くお勧めします。 conftest.pyファイルにはディレクトリスコープがあります。したがって、ターゲットを絞ったフィクスチャとヘルパーを作成することをお勧めします。

いつそれをしたいですか?例が評価されます。

いくつかのケースが適合する可能性があります。

特定のテストグループ用のツールセットまたはhooksの作成。

root/mod/conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff


test root/mod2/test.py will NOT produce "I am mod"

一部のテスト用にフィクスチャのセットをロードしますが、他のテストにはロードしません。

root/mod/conftest.py

@pytest.fixture()
def fixture():
    return "some stuff"

root/mod2/conftest.py

@pytest.fixture()
def fixture():
    return "some other stuff"

root/mod2/test.py

def test(fixture):
    print(fixture)

「その他のもの」を印刷します。

ルート(conftest.py)から継承されたフックをオーバーライドします。

root/mod/conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff

root/conftest.py

def pytest_runtest_setup(item):
    print("I am root")
    #do some stuff

root/mod内でテストを実行すると、「I am mod」のみが出力されます。

conftest.pyhere の詳細を読むことができます。

編集:

普通のヘルパー関数を異なるモジュールの多数のテストから呼び出す必要がある場合-conftest.pyに入れると利用可能になりますか?または、単にhelpers.pyモジュールに入れて、テストモジュールでインポートして使用する必要がありますか?

conftest.pyを使用して、ヘルパーを定義できます。ただし、一般的な慣行に従う必要があります。ヘルパーは、少なくともpytestでフィクスチャとして使用できます。たとえば、私のテストには、この方法でテストに注入する模擬redisヘルパーがあります。

root/helper/redis/redis.py

@pytest.fixture
def mock_redis():
    return MockRedis()

root/tests/stuff/conftest.py

pytest_plugin="helper.redis.redis"

root/tests/stuff/test.py

def test(mock_redis):
    print(mock_redis.get('stuff'))

これは、テストに自由にインポートできるテストモジュールになります。 モジュールredisにさらにテストが含まれている場合は、redis.pyconftest.pyとして名前を付けることができます。ただし、あいまいさがあるため、この方法は推奨されません。

conftest.pyを使用する場合は、そのヘルパーをルートconftest.pyに配置し、必要に応じて挿入するだけです。

root/tests/conftest.py

@pytest.fixture
def mock_redis():
    return MockRedis()

root/tests/stuff/test.py

def test(mock_redis):
    print(mock_redis.get(stuff))

もう1つできることは、インストール可能なプラグインを作成することです。その場合、ヘルパーはどこにでも書くことができますが、自分や他の潜在的なテストフレームワークにインストールするエントリポイントを定義する必要があります。 this を参照してください。

フィクスチャを使用したくない場合は、単純なヘルパーを定義し、必要な場合は単純に古いインポートを使用できます。

root/tests/helper/redis.py

class MockRedis():
    # stuff

root/tests/stuff/test.py

from helper.redis import MockRedis

def test():
    print(MockRedis().get(stuff))

ただし、ここではモジュールがテストの子フォルダーにないため、パスに問題がある可能性があります。 __init__.pyをヘルパーに追加することにより、これを克服できるはずです(テストされていません)。

root/tests/helper/__ init __。py

from .redis import MockRedis

または、ヘルパーモジュールをPYTHONPATHに追加するだけです。

188
Simone Zandara

広い意味で、conftest.pyはローカルのディレクトリごとのプラグインです。ここでは、ディレクトリ固有のフックとフィクスチャを定義します。私の場合、プロジェクト固有のテストディレクトリを含むルートディレクトリがあります。いくつかの一般的な魔法は、「ルート」conftest.pyに配置されています。プロジェクト固有-独自のもの。広く使用されていない限り、conftest.pyにフィクスチャを保存することで悪いものを見ることはできません(その場合、テストファイルで直接定義することを好みます)

9
Furious Duck

conftest.pyファイルを使用して、テストに注入するフィクスチャを定義します。これはconftest.pyの正しい使用ですか?

はい、通常、フィクスチャは複数のテストのデータを準備するために使用されます。

他の用途がありますか?

はい、フィクスチャは、実際のテスト関数の前に、場合によってはpytestによって実行される関数です。フィクスチャ内のコードは、あなたがやりたいことは何でもできます。たとえば、フィクスチャを使用して、テスト用のデータセットを取得したり、テストを実行する前にシステムを既知の状態にしたりできます。

複数のconftest.pyファイルを使用できますか?いつそれをしたいですか?

まず、フィクスチャを個々のテストファイルに入れることができます。ただし、複数のテストファイル間でフィクスチャを共有するには、すべてのテストで中央にあるconftest.pyファイルを使用する必要があります。フィクスチャはどのテストでも共有できます。フィクスチャをそのファイル内のテストでのみ使用する場合は、個別のテストファイルに配置できます。

第二に、yes、トップテストディレクトリのサブディレクトリに他のconftest.pyファイルを置くことができます。そうした場合、これらの下位レベルのconftest.pyファイルで定義されたフィクスチャは、そのディレクトリおよびサブディレクトリのテストで利用可能になります。

最後に、テストルートのconftest.pyファイルにフィクスチャを配置すると、すべてのテストファイルでフィクスチャが使用可能になります。

5
lmiguelvargasf