pytest のパラメータ化: テスト ケースの作成を簡素化する強力なツール

ここに画像の説明を挿入します

実際のシナリオでは、ユーザー名とパスワードを必要とする単純な登録機能をテストします。ユーザー名とパスワードにはいくつかのルールがあり、登録機能を検証するにはさまざまなデータ ルールが必要です。もちろん、リクエストは同じでもリクエスト データが異なる複数のケースを記述することができます。しかし、これには問題があり、大量の重複コードが発生し、管理が容易ではありません。では、それをエレガントに解決するにはどうすればよいでしょうか? もちろんパラメータ化ですが、pytest はどのようにパラメータ化を行うのでしょうか? 質問とともに調べてみましょう。

pytest パラメータ化の概要

パラメーター化されたテストとは、テスト ケースでさまざまなパラメーターを渡して複数のテストを実行し、テスト対象の関数またはメソッドのさまざまな入力と出力を検証することを指します。

Pytest のパラメータ化により、テスト ケースを簡単に拡張し、冗長なコードを削減し、テストの効率を向上させることができます。

pytestのパラメータ化の使用方法

使用方法はまだ非常に簡単ですが、最初にケースを見てみましょう。

@pytest.mark.parametrize("input, expected", [
    (2, 4),
    (3, 9),
    (4, 16)
])
def test_square(input, expected):
    assert input**2 == expected

上記のコードは、test_square という名前のテスト ケースを定義しており、これは @pytest.mark.parametrize デコレーターを使用してパラメーター化されています。パラメータ化されたパラメータ リストには、複数の入力セットと必要な出力が含まれており、各パラメータ セットの間はカンマで区切られています。

次にテストを実行して結果を確認します。

コマンドラインで次のコマンドを実行してテストを実行します。

============================= test session starts ==============================
collecting ... collected 3 items
​
test_demo.py::test_square[2-4] 
test_demo.py::test_square[3-9] 
test_demo.py::test_square[4-16]============================== 3 passed in 0.13s ===============================

アプリケーションシナリオ

利用方法も上記と同様で非常にシンプルなので、応用シーンに注目してみましょう。

単一のパラメトリック アプリケーション

一般的な使用シナリオ: テスト メソッド内で変更されるデータは 1 つだけです。つまり、複数のテスト データ セットがパラメーターを通じて渡されます。実行中、データの各セットが 1 回実行されます。

たとえば、確認コードを登録する場合、現在複数の携帯電話番号を登録する必要があります。

import pytest
​
​
@pytest.mark.parametrize("mobile", [
    16300000000,
    16300000001,
    16300000002
])
def test_register(mobile):
    print(f"当前注册手机号为:{mobile}")

実行結果は以下の通りです。

PASSED                          [ 33%]当前注册手机号为:16300000000
PASSED                          [ 66%]当前注册手机号为:16300000001
PASSED                          [100%]当前注册手机号为:16300000002

テスト ケースに複数のデータがある場合、テスト ケースが複数回実行されることがわかります。

マルチパラメータアプリケーション

テストの入力データは式にすることができ、入力パラメーターは複数にすることができます。複数のデータをタプルに編成できます。

たとえば、計算関数をテストする場合は、次のように記述できます。

import pytest
​
​
@pytest.mark.parametrize("input, expected", [
    (2+2, 4),
    (10-1, 9),
    (4**2, 16)
])
def test_square(input, expected):
    print(input)
    assert input == expected

このコードは、入力値に対してさまざまな計算操作を実行し、結果が期待どおりであることを確認します。

複数のパラメータ化

ユースケースは、複数の @pytest.mark.parametrize を使用してマークできます。例えば:

import pytest
​
​
@pytest.mark.parametrize('input', [1, 2, 3])
@pytest.mark.parametrize("output, expected", [
    (4, 5),
    (6, 7)
])
def test_square(input, output, expected):
    print(f"input:{input},output:{output},expected:{expected}")
    result = input + output
    assert result == expected

2 つのレベルのネストされた @pytest.mark.parametrize デコレーターを使用します。外側のパラメータ化されたデコレータは入力パラメータの値の範囲を [1, 2, 3] として指定し、内側のパラメータ化されたデコレータは出力パラメータと予期されるパラメータの値の各セットを指定します。

パラメータ化とフィクスチャの組み合わせ

フィクスチャもパラメータ化することができますが、前回の記事で詳しく紹介していますので、今回は紹介しません、やり方が分からない学生はこの記事を読んでください。

pytestmark はパラメータ化を実装します

pytestmark を使用すると、テスト モジュール レベルまたはクラス レベルでデコレータを適用できます。pytestmark を使用すると、テスト モジュール内の複数のテスト関数にパラメーター化を均一に適用できます。

ケースを見てみましょう:

import pytest
​
pytestmark = pytest.mark.parametrize('input', [1, 2, 3])
​
def test_square(input):
    result = input ** 2
    assert result == 4

このコードでは、モジュール レベルの pytestmark 変数で pytest.mark.parametrize デコレーターを使用し、入力パラメーターを [1, 2, 3] のパラメーター化された値に設定します。

これは、テスト モジュール内の各テスト関数にパラメーター化が適用され、[1, 2, 3] の各値に対してテストが実行されることを意味します。test_square テスト関数では、入力をパラメーターとして直接使用してパラメーター化された値にアクセスし、入力の 2 乗を計算し、結果が 4 であることをアサートします。

pytestmark を使用すると、すべてのテスト関数で同じデコレータを繰り返すことなく、テスト モジュール全体にパラメータ化を簡単に適用できます。このアプローチは、同じパラメータ化を複数のテスト関数に均一に適用する必要がある場合に特に役立ちます。

pytestmark を使用する場合、モジュール全体のすべてのテスト関数にパラメーター化が適用されることに注意することが重要です。特定のテスト関数にパラメーター化のみを適用したい場合は、pytestmark 変数を使用せずに、デコレーターをその関数に直接適用できます。

パラメータ化をさらに深く掘り下げる

まずソースコードを見てみましょう: /_pytest/python.py

def parametrize(
        self,
        argnames: Union[str, Sequence[str]],
        argvalues: Iterable[Union[ParameterSet, Sequence[object], object]],
        indirect: Union[bool, Sequence[str]] = False,
        ids: Optional[
            Union[Iterable[Optional[object]], Callable[[Any], Optional[object]]]
        ] = None,
        scope: "Optional[_ScopeName]" = None,
        *,
        _param_mark: Optional[Mark] = None,
    ) -> None:

argnames: パラメータ名。テスト関数のパラメータ名を表す文字列または文字列のリストを指定できます。パラメータが複数ある場合は、リストを介して複数の名前を指定できます。

argvalues: パラメーター値。反復可能なオブジェクトにすることができます。各要素はパラメーター値のセットを表します。パラメーター値の各セットは、タプル、リスト、または単一のオブジェクトにすることができます。

indirect: パラメータをテスト対象の関数の間接パラメータとして使用するかどうか。True に設定するか、特定のパラメーター名を指定した場合、テスト関数が実行されると、パラメーターはパラメーター値として直接ではなく、他のフィクスチャ関数からの戻り値として渡されます。

ids: テスト ケースの識別子。テスト レポート内でパラメーター化されたさまざまなテスト ケースをより適切に区別するために使用されます。ID を生成する反復可能または関数を指定できます。

スコープ: パラメーターのスコープ。複数のテスト関数間でパラメーターを共有する場合に使用されます。「関数」(デフォルト)、「クラス」、「モジュール」または「セッション」に設定できます。

_param_mark: 内部パラメータ。パラメータ マークを指定するために使用されます。一般的には注意する必要はありません。

pytest.parametrize 関数を複数回呼び出すことで、複数の異なるパラメーター化セットをテスト関数に追加できます。各呼び出しでは、以前に追加したパラメーター化に加えてパラメーター化が適用されます。

pytest.parametrize 関数は、テスト ケースが実行されるたびにパラメーターを動的に生成するのではなく、テスト ケースの収集フェーズ中にパラメーター化されることに注意してください。

フック関数 pytest_generate_tests を parametrize と組み合わせて使用​​し、テスト ケースを動的に生成します。

pytest.param

強力で使いやすいテスト フレームワークとして、Pytest はパラメーター化されたテストをサポートする @pytest.mark.parametrize デコレーターを提供します。pytest.param 関数は、パラメーター化されたテストをさらに強化するツールであり、より柔軟な方法でパラメーター化されたテスト ケースを定義および制御できるようになります。

パラメトリック識別

パラメトリック テストでは、各テスト ケースに複数のパラメーター セットが含まれる場合があり、多数のテスト結果が生成される場合があります。この時点で、テスト結果をよりよく理解してデバッグするには、パラメーター化された各テスト ケースにわかりやすい識別子を割り当てることが合理的です。pytest.param 関数の id パラメーターでこれを行うことができます。

たとえば、乗算テストでは、次のようにパラメーター化されたテスト ケースを定義できます。

import pytest
​
@pytest.mark.parametrize("input, expected", [
    pytest.param(2, 4, id="case1"),
    pytest.param(3, 9, id="case2"),
    pytest.param(5, 25, id="case3")
])
def test_multiply(input, expected):
    assert input * input == expected

パラメーター化されたテスト ケースごとに pytest.param を使用すると、各テスト ケースの識別子を指定できるため、読みやすく理解しやすくなります。テストの実行が完了すると、テスト レポート内の特定情報は、問題をより正確に特定するのに役立ちます。

カスタムオプション

パラメーターの識別に加えて、pytest.param 関数は、個々のテスト ケースにカスタム マーカーを適用するために使用される、marks パラメーターなどの追加パラメーターも受け入れることができます。マーク パラメータを使用すると、パラメータ化されたテストにさまざまなカスタマイズ オプションを柔軟に追加できます。

たとえば、スキップする必要があるパラメーター化されたテスト ケースがあると仮定すると、次のように定義できます。

import pytest
​
@pytest.mark.parametrize("input, expected", [
    pytest.param(2, 4, marks=pytest.mark.skip),
    pytest.param(3, 9, marks=pytest.mark.skip),
    pytest.param(5, 25)
])
def test_multiply(input, expected):
    assert input * input == expected

上の例では、pytest.mark.skip マークを使用して、最初の 2 つのテスト ケースをスキップします。このようにして、pytest.mark.skip、pytest.mark.xfail などのさまざまなパラメーター化されたテスト ケースにさまざまなマークを適用して、より柔軟なテスト制御を実現できます。

やっと

この記事の導入を通じて、pytest のパラメーター化の概念、使用法、および事例のデモンストレーションについて学びました。Pytest のパラメータ化により、テスト ケースの作成が大幅に簡素化され、コードの再利用性と保守性が向上します。実際のソフトウェア テストでは、pytest パラメータ化を合理的に使用すると、テストをより効率的に行い、潜在的な問題をより迅速に見つけることができます。さらに、フック関数 pytest_generate_tests と組み合わせて複雑なシナリオを実装できる parametrize の高度な使用法も紹介しました。最後に、非常に便利な関数 pytest.param を導入しました。これは、より多くのカスタマイズ オプションとパラメータ化されたテストの制御を提供します。したがって、パラメーター化されたテストを作成するときは、テストの品質と効率を向上させるために pytest.param の使用を検討することをお勧めします。

最後に:以下の完全なソフトウェア テスト ビデオ チュートリアルが編集されてアップロードされているので、必要な友人は自分で入手できます。【保证100%免费】

ここに画像の説明を挿入します

ソフトウェアテスト面接文書

私たちは高給の仕事を見つけるために勉強しなければなりません。以下の面接の質問は、アリババ、テンセント、バイトなどの一流インターネット企業の最新の面接資料であり、一部のバイトの上司が権威ある回答をしています。面接情報に基づいて、誰もが満足のいく仕事を見つけることができると思います。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/m0_67695717/article/details/133362421