1. ホーム
  2. python

[解決済み] pytestでは、conftest.pyのファイルはどのように使用するのですか?

2022-03-24 13:10:31

質問

最近発見した pytest . これは素晴らしいことだと思います。しかし、私はドキュメントがより良いものになると感じています。

を理解しようとしているのです。 conftest.py ファイルを使用することを意味します。

私の(現在小規模の)テストスイートでは、1つの conftest.py ファイルをプロジェクトルートに作成します。私はこのファイルを、テストに注入するフィクスチャを定義するために使用します。

2つ質問があります。

  1. の使い方は正しいのでしょうか? conftest.py ? 他に使い道はありますか?
  2. 複数持つことはできますか? conftest.py ファイルを作成できますか?どのような場合にそうしたいのでしょうか?例を挙げていただければ幸いです。

より一般的な話として、以下のような目的や正しい使い方をどのように定義しますか? conftest.py ファイルを作成できますか?

解決方法は?

<ブロッククオート

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"

ルート/mod2/conftest.py

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

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

ルート/conftest.py

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

の中で任意のテストを実行することで root/mod と表示され、"I am mod"とだけ表示されます。

を読むことができます。 conftest.py こちら .

EDITです。

多くのヘルパー関数が必要な場合はどうすればよいでしょうか。 のテストは、異なるモジュールのテストでも利用できるのでしょうか? の中にあるのでしょうか?それとも、単純にhelpers.pyに置くべきですか? モジュールに入れ、私のテストモジュールでそれをインポートして使用する必要がありますか?

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

ルート/ヘルパー/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.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))

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

フィクスチャを使いたくない場合は、もちろんシンプルなヘルパーを定義して、必要な場所で昔ながらのimportを使うこともできます。

ルート/テスト/ヘルパー/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/ イニット .py

from .redis import MockRedis

または、単純にヘルパーモジュールを PYTHONPATH .