python自動化フレームワークpytest(二)--fixture

7527 ワード

本稿ではpytestのfixtureの詳細な使い方を紹介し、pytestのデータ駆動実装について説明します.
四、pytestのfixture
[email protected]()装飾器は関数を装飾し、この関数はfixtureです.
4.1、fixture優勢
  • ネーミング方式は柔軟で、setupとteardownのいくつかのネーミング
  • に限らない.
  • conftest.py構成ではデータ共有が可能で、importを必要とせずにfixture
  • を自動的に見つけることができます.
  • scope="module"は複数実現可能である.pyファイル間共有フロント
  • scope="session"は、複数を実現する.pyファイル間で1つのセッションを使用して複数のインスタンス
  • を完了
    4.2、fixtureソースの詳細
    @pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)
    パラメータの説明:scope:タグ付けメソッドの役割ドメイン
  • function"(default):テストメソッドごとにtestごとに
  • を1回実行します.
  • 「class」:クラス全体に作用し、各classのすべてのtestは
  • のみ実行されます.
  • 「module」:モジュール全体に作用し、各moduleのすべてのtestは
  • のみ実行されます.
  • "セッション:セッション全体に作用し、セッションごとに
  • のみが実行されます.
    params:オプションのパラメータリストです.複数のパラメータがfixture機能を呼び出し、すべてのテストで使用されます.
    Autouse:デフォルト:False、このfixtureを手動で呼び出す必要があります.Trueの場合、すべての役割ドメイン内のテスト・インスタンスが自動的に呼び出されます.
    ids:各文字列idのリスト、各文字列はparamsに対応し、テストIDの一部です.IDが指定されていない場合はparamsから自動的に生成されます
    name:fixtureの名前.これは、既定では装飾関数の名前です.fixtureが定義された統合モジュールで使用されている場合、治具の機能名は治具の機能argによって隠され、この問題を解決する方法の1つとして、関数コマンド「fixture_」を装飾する次に「@pytest.fixture(name=')」を使用します.
    注意:sessionの役割ドメイン:テストセッション全体、すなわちpytestの実行からテストの終了まで
    4.3、テスト用例がfixtureを呼び出す三つの方式
  • 1、fixture名を試験用例関数とする入力パラメータ
  • 2、試験用例に装飾器を加える:@pytest.mark.usefixtures(fixture_name)
  • 3、fixture設定autouse=Trueは、各インスタンスが実行する前に
  • を呼び出す.
    import pytest
    
    @pytest.fixture
    def login():
        print("   fixture1-----------")
    
    @pytest.fixture
    def login2():
        print("   fixture2----------")
    
    #      ,     
    def test_0001(login):
        print("   1:         111")
    
    def test_0002():  #    login
        print("   2:     ,   222")
    
    
    #                :@pytest.mark.usefixtures(fixture_name),    fixture ,  
    @pytest.mark.usefixtures("login2", "login")
    def test_0003():
        print("  3:         111")
    
    #       fixture  autouse=True
    @pytest.fixture(autouse=True)
    def login3():
        print("   fixture3====auto===")
    
    #   test  ,          fixture
    @pytest.mark.usefixtures("login2")
    def loginss():
        print(123)
    
    if __name__ == '__main__':
        pytest.main(["-s", "test_002.py"])
    

    出力結果:
    test_002.py    fixture3====auto===
       fixture1-----------
       1:         111
    .   fixture3====auto===
       2:     ,   222
    .   fixture3====auto===
       fixture2----------
       fixture1-----------
      3:         111
    
    .
    
    ============================== 3 passed in 0.06s ==============================
    

    义齿
    注意:fixtureに戻り値がある場合、usefixtureは戻り値を取得できません.これは、アクセサリーusefixtureと使用例がfixtureパラメータを直接伝える違いです.fixtureでreturnから出たパラメータを使用する必要がある場合は、パラメータ名を直接パラメータが入力され、returnから出たパラメータを使用する必要がない場合にのみ、両方の方法で使用できます.
    import pytest
    
    @pytest.fixture
    def login():
        print("   fixture1-----------")
        return "  login"
    
    def test_0001(login):
        print(login)
    
    if __name__ == '__main__':
        pytest.main(["-s", "test_002.py"])
    

    fixuerのparamsパラメータはrequestで取得して返します
    @pytest.fixtureにはparamsパラメータがあり、リストを受け入れ、リスト内の各データを例として入力することができます.つまり、どれだけのデータがあるか、どれだけの用例が形成されるかということです.毎回入力パラメータはrequestを用いる.paramが取得する
    import pytest
    @pytest.fixture(params=[1, 2, 3])
    def need_data(request): #     request       
        return request.param #        ,       
    class Test_ABC:
     
        def test_a(self,need_data):
            print("------->test_a")
            assert need_data != 3 #   need_data   3
     
    if __name__ == '__main__':
        pytest.main(["-s","test_abc.py"])
     
         :
          #            
    collecting ... collected 3 items
    demo.py::Test_ABC::test_a[1] ------->test_a
    PASSED
    demo.py::Test_ABC::test_a[2] ------->test_a
    PASSED
    demo.py::Test_ABC::test_a[3] ------->test_a
    FAILED
    

    4.4、fixture作用範囲
    上記のすべてのインスタンスはデフォルトで関数レベルなので、テスト関数はfixtureを呼び出すだけで、テスト関数が実行される前にfixtureを指定します.scopeパラメータはfixtureの作用範囲を定義できます.次に、fixtureの作用範囲を一例で具体的に見てみましょう.
    # test_002.py
    import pytest
    
    @pytest.fixture(scope='module', autouse=True)
    def module_fixture():
        print('
    -----------------') print(' module fixture') print('-----------------') @pytest.fixture(scope='class') def class_fixture(): print('
    -----------------') print(' class fixture') print('-------------------') @pytest.fixture(scope='function', autouse=True) def func_fixture(): print('
    -----------------') print(' function fixture') print('-------------------') def test_1(): print('
    test1') @pytest.mark.usefixtures('class_fixture') class TestFixture1(object): def test_2(self): print('
    class1 test2') def test_3(self): print('
    class1 test3') @pytest.mark.usefixtures('class_fixture') class TestFixture2(object): def test_4(self): print('
    class2 test4') def test_5(self): print('
    class2 test5') if __name__=='__main__': pytest.main(['-s', '-v', 'test_002.py'])

    出力結果:
    test_002.py::test_1 
    -----------------
      module fixture
    -----------------
    
    -----------------
      function fixture
    -------------------
    
       test1
    PASSED
    test_002.py::TestFixture1::test_2 
    -----------------
      class fixture
    -------------------
    
    -----------------
      function fixture
    -------------------
    
      class1   test2
    PASSED
    test_002.py::TestFixture1::test_3 
    -----------------
      function fixture
    -------------------
    
      class1   test3
    PASSED
    test_002.py::TestFixture2::test_4 
    -----------------
      class fixture
    -------------------
    
    -----------------
      function fixture
    -------------------
    
      class2   test4
    PASSED
    test_002.py::TestFixture2::test_5 
    -----------------
      function fixture
    -------------------
    
      class2   test5
    PASSED
    
    ============================== 5 passed in 0.10s ==============================
    
    

    モジュール全体でmoduleレベルのfixtureが1回しか実行されず、各クラスではclassレベルのfixtureが1回実行され、各関数の前にfunctionレベルのfixtureが1回実行されていることがよくわかります.
    4.5 fixture実装teardown
    前のすべてのインスタンスは、テスト・インスタンスが実行される前の準備作業をしただけですが、インスタンスが実行された後、環境のクリーンアップ作業をどのように実現すればいいのでしょうか.これはyieldキーワードと言わざるを得ません.皆さんが多かれ少なかれこのキーワードを知っているよりも、彼の役割はreturnとは差が少なく、呼び出し者にデータを返すことができます.唯一の違いは、落とされた関数の実行がyieldに遭遇すると実行が停止し、呼び出し先の関数が実行され、呼び出された関数の実行が完了するとyieldキーの後ろのコードが実行されます.
    import pytest
    
    @pytest.fixture
    def login():
        print("   fixture1-----------        ")
        yield "   fixture    "
        print("   fixture1-----------        ")
    
    def test_0001(login):
        print(login)
    
    if __name__ == '__main__':
        pytest.main(["-s", "test_002.py"])
    

    実行結果:
    test_002.py    fixture1-----------        
       fixture    
    .   fixture1-----------        
    
    
    ============================== 1 passed in 0.09s ==============================
    

    使用例が実行される前にfixtureのyieldの前のコードが実行され、使用例が実行された後にfixture関数yieldの後のコードが実行されることに注意すべきことは、次のとおりである.
  • yieldの前のコード、すなわちsetup部分に異常が投げ出された場合、yieldの後のteardownコンテンツ
  • は実行する.
  • 試験例が異常を投げ出す場合、yieldの後のteardownコンテンツは
  • 正常に実行されます.
    4.6 pytest検索fixtureの順序
    pytestはfixtureの名前に従ってfixtureを検索します.検索順は次のとおりです.
    現在のテストが存在するクラスを優先的に検索し、現在のテストが存在するモジュールを検索してconftestを検索する.py次に内蔵fixtureを検索最後にサードパーティプラグインを検索
    上一篇:pythonオートメーションフレームワークpytest(三)--データ駆動(パラメトリック)