pytest-fixture


pytest-fixture

fixture是在測試函數運行前后,由pytest執行的外殼函數。fixture中的代碼可以定制,滿足多變的測試需求,包括定義傳入測試中的數據集,配置測試前系統的初始狀態,為批量測試提供數據源,等等。

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

@pytest.fixture()
def fixturefun():
    return 2

def test_one(fixturefun):
    assert fixturefun == 2
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 1 item                                                                             

test_001.py .                                                                          [100%]

===================================== 1 passed in 0.02s ======================================

fixture

@pytest.fixture()裝飾器用於聲明函數是一個fixture,如果測試用例的參數中包含此fixture函數,則在測試用例運行前會先運行此fixture函數。如果fixture函數有返回值,則將返回值傳遞給測試用例函數

調用方式

  1. 使用fixture名字作為參數
#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest

@pytest.fixture()
def fixturetest():
    print('fixturetest')

def test_1(fixturetest):
    print('test_1')
  1. 使用 @pytest.mark.usefixtures('fixture') 裝飾器
#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest

@pytest.fixture()
def fixturetest():
    print('fixturetest')

@pytest.mark.usefixtures('fixturetest')
def test_2():
    print('test_2')
  1. 使用autouse參數所有test_*自動執行fixture
#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest

@pytest.fixture(autouse=True)
def fixturetest():
    print('fixturetest')

def test_1():
    print('test_1')


def test_2():
    print('test_2')

class Test_class():
    def test_3(self):
        print('test_3')
結果:  
================================================== test session starts ===================================================  
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1  
rootdir: /media/_dde_data/python  
collected 3 items                                                                                                          
    
test2.py fixturetest  
test_1  
.fixturetest  
test_2  
.fixturetest  
test_3  
.  
    
=================================================== 3 passed in 0.01s ====================================================  

usefixtures與傳fixture區別

如果fixture有返回值,那么usefixture就無法獲取到返回值,這個是裝飾器usefixture與用例直接傳fixture參數的區別。

當fixture需要用到return出來的參數時,只能講參數名稱直接當參數傳入,不需要用到return出來的參數時,兩種方式都可以。

使用fixture傳遞測試數據

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

@pytest.fixture()
def fixturefun():
    return (1,2,3,4)

def test_one(fixturefun):
    assert fixturefun[0] == 2
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 1 item                                                                             

test_001.py 
        SETUP    F fixturefun
        test_001.py::test_one (fixtures used: fixturefun)F
        TEARDOWN F fixturefun

========================================== FAILURES ==========================================
__________________________________________ test_one __________________________________________

fixturefun = (1, 2, 3, 4)

    def test_one(fixturefun):
>       assert fixturefun[0] == 2
E       assert 1 == 2

test_001.py:10: AssertionError
================================== short test summary info ===================================
FAILED test_001.py::test_one - assert 1 == 2
===================================== 1 failed in 0.18s ======================================

使用多個fixture

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

@pytest.fixture()
def fixturefun1():
    print ("**********fixture_1***********")

@pytest.fixture()
def fixturefun2():
    print ("**********fixture_2***********")

def test_one(fixturefun1,fixturefun2):
    print("測試用例")
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 1 item                                                                             

test_001.py **********fixture_1***********
**********fixture_2***********
測試用例
.

===================================== 1 passed in 0.01s ======================================

使用yield實現teardown

@pytest.fixture()
def fixturetest():
    print('setup')
    yield
    print('teardown')

例:

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest

@pytest.fixture(scope='class',autouse=True)
def fixturetest():
    print('----------開始-------------')
    yield
    print('----------結束-------------')

class Test_class1():
    def test_1(self):
        print('test_1')


    def test_2(self):
        print('test_2')

class Test_class2():
    def test_a(self):
        print('test_a')


    def test_b(self):
        print('test_b')
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 4 items                                                                                                        

test2.py ----------開始-------------
test_1
.test_2
.----------結束-------------
----------開始-------------
test_a
.test_b
.----------結束-------------


===================================== 4 passed in 0.02s ======================================

作用范圍

scope參數可以是session, module,class,function; 默認為function

  • session 會話級別:
    每個session只運行一次,session級別的fixture需要定義到conftest.py中

  • module 模塊級別:
    模塊里所有的用例執行前執行一次module級別的fixture

  • class 類級別 :
    每個類執行前都會執行一次class級別的fixture

  • function
    前面實例已經說了,這個模式是默認的模式,函數級別的,每個測試用例執行前都會執行一次function級別的fixture

目錄結構:

.
├── conftest.py
├── __init__.py
├── test_001.py
└── test_002.py
#conftest.py
import pytest
 
@pytest.fixture(scope="session",autouse="True")
def sess_scope():
    print('----------開始session-------------')
    yield
    print('----------結束session-------------')

@pytest.fixture(scope="module",autouse="True")
def mod_scope():
    print('----------開始module-------------')
    yield
    print('----------結束module-------------')

@pytest.fixture(scope="class",autouse="True")
def class_scope():
    print('----------開始class-------------')
    yield
    print('----------結束class-------------')

@pytest.fixture(scope="function",autouse="True")
def fun_scope():
    print('----------開始function-------------')
    yield
    print('----------結束function-------------')
#test_001.py
#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

def test_one():
    print("函數用例 1")

class Test_Class1():
    def test_two(self):
        print("類 1 用例 2")
    
    def test_three(self):
        print("類 1 用例 3")

def test_four():
    print("函數用例 4")
#test_002.py
#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

def test_1():
    print("函數用例 5")

class Test_Class2():
    def test_6(self):
        print("類 2 用例 6")
    
    def test_7(self):
        print("類 2 用例 7")

def test_4():
    print("函數用例 8")
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 8 items                                                                            

test_001.py ----------開始session-------------
----------開始module-------------
----------開始class-------------
----------開始function-------------
函數用例 1
.----------結束function-------------
----------結束class-------------
----------開始class-------------
----------開始function-------------
類 1 用例 2
.----------結束function-------------
----------開始function-------------
類 1 用例 3
.----------結束function-------------
----------結束class-------------
----------開始class-------------
----------開始function-------------
函數用例 3
.----------結束function-------------
----------結束class-------------
----------結束module-------------

test_002.py ----------開始module-------------
----------開始class-------------
----------開始function-------------
函數用例 5
.----------結束function-------------
----------結束class-------------
----------開始class-------------
----------開始function-------------
類 2 用例 6
.----------結束function-------------
----------開始function-------------
類 2 用例 7
.----------結束function-------------
----------結束class-------------
----------開始class-------------
----------開始function-------------
函數用例 8
.----------結束function-------------
----------結束class-------------
----------結束module-------------
----------結束session-------------


===================================== 8 passed in 0.03s ======================================

此例中發現當作用范圍時class(autouse="True")級別時,其實函數用例(類之外的)運行前后也都會運行

為fixture重命名

fixture允許使用@pytest.fixturename參數對fixture重命名

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest 

@pytest.fixture(name='fix')
def fixturefun():
    print("**********fixture*************")

@pytest.mark.usefixtures('fix')
def test_one():
    print("函數用例 1")
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: /media/_dde_data/python
collected 1 item                                                                             

test_001.py **********fixture*************
函數用例 1
.

===================================== 1 passed in 0.01s ======================================

fixture參數化

使用pytest的內建fixturerequest實現參數化

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest


test_param = [(1,2),("a","b"),(False,False),(int,int)]
@pytest.fixture(params=test_param)
def fixturefun(request):
    test = request.param
    return test

def test_001(fixturefun):
    assert fixturefun[0] == fixturefun[1]
==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /media/_dde_data/python
collected 4 items                                                                            

test_001.py::test_001[fixturefun0] FAILED                                              [ 25%]
test_001.py::test_001[fixturefun1] FAILED                                              [ 50%]
test_001.py::test_001[fixturefun2] PASSED                                              [ 75%]
test_001.py::test_001[fixturefun3] PASSED                                              [100%]

========================================== FAILURES ==========================================
___________________________________ test_001[fixturefun0] ____________________________________

fixturefun = (1, 2)

    def test_001(fixturefun):
>       assert fixturefun[0] == fixturefun[1]
E       assert 1 == 2
E         +1
E         -2

test_001.py:13: AssertionError
___________________________________ test_001[fixturefun1] ____________________________________

fixturefun = ('a', 'b')

    def test_001(fixturefun):
>       assert fixturefun[0] == fixturefun[1]
E       AssertionError: assert 'a' == 'b'
E         - b
E         + a

test_001.py:13: AssertionError
================================== short test summary info ===================================
FAILED test_001.py::test_001[fixturefun0] - assert 1 == 2
FAILED test_001.py::test_001[fixturefun1] - AssertionError: assert 'a' == 'b'
================================ 2 failed, 2 passed in 0.20s =================================

fixturehe和@pytest.mark.parametrize結合的參數化

#!/usr/bin/python3
#-*- conding:utf-8 -*-
import pytest


test_param = [(1,2),("a","b"),(False,False),(int,int)]
@pytest.fixture()
def fixturefun(request):
    test = request.param
    return test

@pytest.mark.parametrize("fixturefun",test_param,indirect=True) #indirect=True 聲明fixturefun不是參數,而是一個函數
def test_001(fixturefun):
    assert fixturefun[0] == fixturefun[1]

==================================== test session starts =====================================
platform linux -- Python 3.5.3, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /media/_dde_data/python
collected 4 items                                                                            

test_001.py::test_001[fixturefun0] FAILED                                              [ 25%]
test_001.py::test_001[fixturefun1] FAILED                                              [ 50%]
test_001.py::test_001[fixturefun2] PASSED                                              [ 75%]
test_001.py::test_001[fixturefun3] PASSED                                              [100%]

========================================== FAILURES ==========================================
___________________________________ test_001[fixturefun0] ____________________________________

fixturefun = (1, 2)

    @pytest.mark.parametrize("fixturefun",test_param,indirect=True)
    def test_001(fixturefun):
>       assert fixturefun[0] == fixturefun[1]
E       assert 1 == 2
E         +1
E         -2

test_001.py:14: AssertionError
___________________________________ test_001[fixturefun1] ____________________________________

fixturefun = ('a', 'b')

    @pytest.mark.parametrize("fixturefun",test_param,indirect=True)
    def test_001(fixturefun):
>       assert fixturefun[0] == fixturefun[1]
E       AssertionError: assert 'a' == 'b'
E         - b
E         + a

test_001.py:14: AssertionError
================================== short test summary info ===================================
FAILED test_001.py::test_001[fixturefun0] - assert 1 == 2
FAILED test_001.py::test_001[fixturefun1] - AssertionError: assert 'a' == 'b'
================================ 2 failed, 2 passed in 0.20s =================================


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM