pytest框架精髓fixture的使用方法

前言:fixture區別於unnitest的傳統單元測試(setup/teardown)有顯著改進:

  1、有獨立的命名,並通過聲明它們從測試函數、模塊、類或整個項目中的使用來激活;

  2、按模塊化的方式實現,每個fixture都可以互相調用;

  3、fixture的範圍從簡單的單元測試到複雜的功能測試,可以對fixture配置參數,或者跨函數function,類class,模塊module或整個測試session範圍。

環境:python3、sublime text3、pytest

用法:@pytest.fixture(),fixture命名不要以test開頭,跟用例區分開;fixture是有返回值,沒有返回值默認為None;用例調用fixture的返回值,直接就是把fixture的函數名稱當做變量名稱。下面就是演示一下fixture的相關特性。

1、單個fixture的使用

<code>import pytest

#可作為變量
@pytest.fixture()
def test_01():
m = 'hello pytest'
return m

def test_02(test_01):
assert test_01 == 'hello pytest'

if __name__ == '__main__':

\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

2、單個fixture的使用

注:如果用例需要用到多個fixture的返回數據,fixture也可以返回一個元祖,list或字典,然後從裡面取出對應數據

<code>import pytest

#可作為變量
@pytest.fixture()
def test_01():
m = 'hello pytest'
n = 'learning'
print("傳出參數m和n")
return (m,n)

def test_02(test_01):
\tx = test_01[0]
\ty = test_01[1]
\tassert x == 'hello pytest'
\tassert y == 'learning'
\tprint('success')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

3、多個fixture相互調用

<code>import pytest

#可作為變量
@pytest.fixture()
def test_01():
m = 'hello pytest'
print("傳出參數m")
return m
@pytest.fixture()
def test_02():
n = 'learning'
print("傳出參數n")
return n

def test_03(test_01,test_02):
\tx = test_01
\ty = test_02
\tassert x == 'hello pytest'
\tassert y == 'learning'
\tprint('傳入多個fixture參數success')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

4、上面是fixture的3中常用使用方式,下面介紹一下fixture的作用範圍(scope)

1)fixture的作用範圍

fixture裡面有個scope參數可以控制fixture的作用範圍:session>module>class>function

-function:每一個函數或方法都會調用

-class:每一個類調用一次,一個類中可以有多個方法

-module:每一個.py文件調用一次,該文件內又有多個function和class

-session:是多個文件調用一次,可以跨.py文件調用,每個.py文件就是module

2)fixture源碼詳解

fixture(scope='function',params=None,autouse=False,ids=None,name=None):

scope:有四個級別參數"function"(默認),"class","module","session"

params:一個可選的參數列表,它將導致多個參數調用fixture功能和所有測試使用它。

autouse:如果True,則為所有測試激活fixture func可以看到它。如果為False則顯示需要參考來激活fixture

ids:每個字符串id的列表,每個字符串對應於params這樣他們就是測試ID的一部分。如果沒有提供ID它們將從params自動生成

name:fixture的名稱。這默認為裝飾函數的名稱。如果fixture在定義它的統一模塊中使用,夾具的功能名稱將被請求夾具的功能arg遮蔽,解決這個問題的一種方法時將裝飾函數命令"fixture_<fixturename>"然後使用"@pytest.fixture(name='<fixturename>')"。/<fixturename>/<fixturename>

1)scope="function",作用於方法中

注:@pytest.fixture()如果不寫參數,參數就是scope="function",它的作用範圍是每個測試用例來之前運行一次,銷燬代碼在測試用例之後運行。

<code>import pytest

@pytest.fixture()
def test_01():
m = 'hello pytest'
print("傳出m")
return m
@pytest.fixture(scope='function')
def test_02():
n = 'learning'
print("\\n傳出n")
return n

def test_03(test_01):
\tx = 'hello pytest'
\tassert x == test_01
\tprint('找到x')


def test_04(test_02):
\ty = 'learning'
\tassert y == test_02
\tprint('找到y')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

2)scope="function",作用於類中的每個方法

<code>import pytest

# 在類中調用
@pytest.fixture()
def test_01():

m = 'hello pytest'
print("傳出m")
return m
@pytest.fixture(scope='function')
def test_02():
n = 'learning'
print("\\n傳出n")
return n

class Test_one():
\tdef test_03(self,test_01):
\t\tx = 'hello pytest'
\t\tassert x == test_01
\t\tprint('找到x')

\tdef test_04(self,test_02):
\t\ty = 'learning'
\t\tassert y == test_02
\t\tprint('找到y')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>

3)scope="class"

注:fixture為class級別的時候,如果一個class裡面有多個用例,都調用了次fixture,那麼此fixture只在此class裡所有用例開始前執行一次。例如:下面例子中,方法test_02被類調用了2次,但是隻會在用例開始錢執行一次。

<code>import pytest

@pytest.fixture()
def test_01():
m = 'hello pytest'
print("傳出m")
return m
@pytest.fixture(scope='class')
def test_02():
name = '張三'

print("\\n傳出name")
return name

class Test_one():
\tdef test_03(self,test_02):
\t\tx = 'hello pytest'
\t\tprint('找不到x')
\t\tassert x == test_02
\t\t

\tdef test_04(self,test_02):
\t\ty = '張三'
\t\tassert y == test_02
\t\tprint('\\n找到y')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

4)scope="module"

注:fixture為module時,在當前.py腳本里面所有用例開始前只執行一次;例如在下面例子中test_02被test_03和類Test_one中的test_04調用了2次,但是隻執行一次test_02。

<code>import pytest

@pytest.fixture(scope='module')
def test_02():
name = '張三'
print("\\n傳出name")
return name

def test_03(test_02):
\t\tx = 'hello pytest'
\t\tprint('找不到x')
\t\tassert x == test_02
\t\t

class Test_one():
\tdef test_04(self,test_02):
\t\ty = '張三'
\t\tassert y == test_02
\t\tprint('\\n找到y')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

5)scope="session"

fixture為session級別是可以跨.py模塊調用的,當存在多個.py文件的用例時,如果多個用例只需調用一次fixture,那就可以設置為scope="session",並且寫到conftest.py文件裡。

conftest.py文件名稱是固定的,pytest會自動識別該文件;放到項目的根目錄下就可以全局調用了,如果放到某個package下,那就在該package內有效。

文件目錄為:


pytest框架精髓fixture的使用方法

<code>#conftest.py下的代碼
import pytest

@pytest.fixture(scope='session')
def test_02():
name = '張三'
print("\\n傳出name")
return name/<code>
<code>#調用文件下的代碼
import pytest

def test_03(test_02):
\t\tx = 'hello pytest'
\t\tprint('找不到x')
\t\tassert x == test_02
\t\t

class Test_one():
\tdef test_04(self,test_02):
\t\ty = '張三'
\t\tassert y == test_02
\t\tprint('\\n找到y')

if __name__ == '__main__':
\tpytest.main(["-s",'-q','test_seven.py'])/<code>


pytest框架精髓fixture的使用方法

參考:pytest框架之fixture詳細使用


分享到:


相關文章: