Pytest の conftest.py とは何ですか? 質問する

Pytest の conftest.py とは何ですか? 質問する

conftest.pyファイルが何のために使用されるのかを理解しようとしています。

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

質問が2つあります。

  1. これは の正しい使い方ですかconftest.py?他の使い方はありますか?
  2. 複数のconftest.pyファイルを持つことはできますか? いつそれを行えばよいでしょうか? 例をいただければ幸いです。

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

ベストアンサー1

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

はい、そうです。フィクスチャは、 の潜在的かつ一般的な用途ですconftest.py。定義するフィクスチャは、テスト スイート内のすべてのテスト間で共有されます。ただし、ルートでフィクスチャを定義してもconftest.py無駄になる可能性があり、そのようなフィクスチャがすべてのテストで使用されない場合は、テストの速度が低下します。

他にも用途はありますか?

はい、そうです。

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

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

    pytest_plugins = "someapp.someplugin"

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

      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ファイルにはディレクトリ スコープがあります。したがって、ターゲットを絞ったフィクスチャとヘルパーを作成することをお勧めします。

いつそれを実行すればよいのでしょうか? 例を教えていただければ幸いです。

いくつかのケースが当てはまります:

特定のテスト グループ用のツールまたはフックのセットを作成します。

ルート/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"

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

ルート/mod/conftest.py

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

ルート/mod2/conftest.py

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

ルート/mod2/test.py

def test(fixture):
    print(fixture)

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

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

ルート/mod/conftest.py

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

ルート/conftest.py

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

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

詳細については、conftest.py ここ

編集:

異なるモジュール内の複数のテストから呼び出される単純なヘルパー関数が必要な場合は、conftest.py に配置すると使用できるようになりますか? それとも、単に helpers.py モジュールに配置し、テスト モジュールでインポートして使用すればよいのでしょうか?

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

ルート/ヘルパー/redis/redis.py

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

ルート/テスト/スタッフ/conftest.py

pytest_plugin="helper.redis.redis"

ルート/テスト/スタッフ/test.py

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

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

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

ルート/テスト/conftest.py

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

ルート/テスト/スタッフ/test.py

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

他にできることは、インストール可能なプラグインを書くことです。その場合、ヘルパーはどこにでも書くことができますが、自分のテストフレームワークや他の潜在的なテストフレームワークにインストールするためのエントリポイントを定義する必要があります。これ

フィクスチャを使用したくない場合は、もちろん、単純なヘルパーを定義して、必要な場所で単純な古いインポートを使用することもできます。

ルート/テスト/ヘルパー/redis.py

class MockRedis():
    # stuff

ルート/テスト/スタッフ/test.py

from helper.redis import MockRedis

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

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

ルート/テスト/ヘルパー/ init .py

from .redis import MockRedis

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

おすすめ記事