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


216

私は最近発見しましたpytest。それは素晴らしいようです。ただし、ドキュメントの方が良いと思います。

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

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

2つの質問があります。

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

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


8
あなたはで私を持っていたIt seems great. However, I feel the documentation could be better.
user9074332

6
ええ、ドキュメントはもっと良いかもしれません。私はpytestのドキュメント全体を検索しましたが、conftest.pyこれを行うことやconftestファイルでそのことを行うことへの多くの参照がありますが、ドキュメントのどこにもpytestがディスカバリをテストすると、 すべてのconftest.pyファイルが(テスト検出が行われているディレクトリ構造)は、テスト収集フェーズ(テストが実行される前)中に実行されます。実験でそれを理解しなければなりませんでした。
Daniel Goldfarb

回答:


287

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

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

いくつかのケースが当てはまる可能性があります:

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

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.py こちらをご覧ください

編集:

異なるモジュールのいくつかのテストから呼び出されるプレーンなヘルパー関数が必要な場合はどうしたらよいですか-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'))

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

を使用する場合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))

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

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

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です。


最初の単体テストモジュールtest_aaaaa.pyが、フィクスチャのセットアップがで完了するに実際に実行しようとしている状況に遭遇していますconftest.py。なぜこれが起こっているのかについての考えはありますか?
user9074332

conftest.pyがないと、テストルートパスはsys.pathに追加されず、「ModuleNotFoundError:No module named 'foobar'」のようなエラーが表示されます。
Cale Sweeney

10

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


10

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

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

他の用途はありますか?

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

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

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.