目錄
9、ids引數說明
ids
引數就是給每一個變數起一個別名。
示例:
import pytest
data = [("孫悟空", 666), ("豬八戒", 777), ("沙和尚", 888)]
# ids引數的個數要與params引數的個數相同,用的很少
@pytest.fixture(params=data, ids=['suk', 'zbj', 'shs'])
def need_data(request):
return request.param
def test_data(need_data):
print(f"測試人物:{need_data[0]}")
print(f"測試分數:{need_data[1]}")
if __name__ == '__main__':
pytest.main()
"""
之前的測試結果:
test_01.py::test_data[need_data0] 測試人物:孫悟空
測試分數:666
PASSED
test_01.py::test_data[need_data1] 測試人物:豬八戒
測試分數:777
PASSED
test_01.py::test_data[need_data2] 測試人物:沙和尚
測試分數:888
PASSED
加上ids引數後的執行結果:只是[]的內容變化了,這就是ids引數的作用
test_01.py::test_data[suk] 測試人物:孫悟空
測試分數:666
PASSED
test_01.py::test_data[zbj] 測試人物:豬八戒
測試分數:777
PASSED
test_01.py::test_data[shs] 測試人物:沙和尚
測試分數:888
PASSED
"""
10、name引數說明
name
引數就是給Fixture修飾的方法起個別名。
示例:
import pytest
data = [("孫悟空", 666), ("豬八戒", 777), ("沙和尚", 888)]
# ids引數的個數要與params引數的個數相同,用的很少
@pytest.fixture(params=data, name="abc")
def need_data(request):
return request.param
# 注意,如果定義了name屬性,用例的方法引數就需要傳入name屬性定義的值。
# 否則將會報錯。
# 還有用例中呼叫引數的使用,也需要使用name定義的別名。
# 即:當取了別名之後,那麼原來的方法名就用不了了。
def test_data(abc):
print(f"測試人物:{abc[0]}")
print(f"測試分數:{abc[1]}")
if __name__ == '__main__':
pytest.main()
"""
執行結果:
test_01.py::test_data[abc0] 測試人物:孫悟空
測試分數:666
PASSED
test_01.py::test_data[abc1] 測試人物:豬八戒
測試分數:777
PASSED
test_01.py::test_data[abc2] 測試人物:沙和尚
測試分數:888
PASSED
"""
11、scope引數說明
scope
引數有四個級別:function(預設)
,class
,module
,session
。
作用範圍:session
> module
> class
> function
scope="function"
:@pytest.fixture()
裝飾器如果不寫引數,預設引數就是scope="function"
。它的作用範圍是,在每個測試用例執行的前(後)執行一次。scope="class"
:@pytest.fixture()
裝飾器為class
級別的時候,Fixture方法只在此class
裡所有用例開始執行前(後)執行一次。與class
中的function
沒有關係。scope="module"
:@pytest.fixture()
裝飾器為module
級別的時候,在一個.py
指令碼中所有用例開始執行前(後)執行一次。scope="session"
:@pytest.fixture()
裝飾器為session
級別的時候,是可以跨.py
模組呼叫的,每個.py
檔案就是module
。
(1)scope="function"
import pytest
@pytest.fixture(scope="function")
def login():
print("開啟APP")
print("輸入賬號,密碼,進行登入")
yield # 當用例執行完成後,執行yield後的程式碼
print("關閉APP")
def test_add_cart(login):
print("新增購物車--需要登入")
def test_browser_goods():
print("瀏覽商品--不需要登入")
if __name__ == '__main__':
pytest.main()
"""
執行結果: 只作用域方法或者函式範圍
test_01.py::test_add_cart 開啟APP
輸入賬號,密碼,進行登入
新增購物車--需要登入
PASSED關閉APP
test_01.py::test_browser_goods 瀏覽商品--不需要登入
PASSED
"""
(2)scope="class"
import pytest
@pytest.fixture(scope="class")
def login():
print("\nscope=class 作用域的前置函式\n")
yield # 當用例執行完成後,執行yield後的程式碼
print("\n\nscope=class 作用域的後置函式")
class Test_Demo:
def test_add_cart(self, login):
print("新增購物車--測試用例")
def test_add_address(self):
print("新增收貨地址--測試用例")
if __name__ == '__main__':
pytest.main()
"""
執行結果: 只在測試類開始前後執行了
scope=class 作用域的前置函式
新增購物車--測試用例
PASSED
test_01.py::Test_Demo::test_add_address 新增收貨地址--測試用例
PASSED
scope=class 作用域的後置函式
"""
(3)scope="module"
import pytest
@pytest.fixture(scope="module")
def login():
print("\nscope=module 作用域的前置函式\n")
yield # 當用例執行完成後,執行yield後的程式碼
print("\n\nscope=module 作用域的後置函式")
# 如果該用例不傳入fixture方法,該用例會優先與fixture前置執行
def test_browser_goods(login):
print("瀏覽商品--不需要登入")
class Test_Demo:
def test_add_cart(self, login):
print("新增購物車--測試用例")
def test_add_address(self):
print("新增收貨地址--測試用例")
class Test_Demo2:
def test_add_cart(self, login):
print("第2次-新增購物車--測試用例")
def test_add_address(self):
print("第2次-新增收貨地址--測試用例")
if __name__ == '__main__':
pytest.main()
"""
執行結果:
說明一下:scope=module時,整個.py模組中fixture只執行一次
scope=module 作用域的前置函式
瀏覽商品--不需要登入
PASSED
test_01.py::Test_Demo::test_add_cart 新增購物車--測試用例
PASSED
test_01.py::Test_Demo::test_add_address 新增收貨地址--測試用例
PASSED
test_01.py::Test_Demo2::test_add_cart 第2次-新增購物車--測試用例
PASSED
test_01.py::Test_Demo2::test_add_address 第2次-新增收貨地址--測試用例
PASSED
scope=module 作用域的後置函式
"""
(4)scope="session"
test_01.py
檔案中的用例。
import pytest
@pytest.fixture(scope="session")
def login():
print("\nscope=session 作用域的前置函式\n")
yield # 當用例執行完成後,執行yield後的程式碼
print("\n\nscope=session 作用域的後置函式")
# 如果該用例不傳入fixture方法,該用例會優先與fixture前置執行
def test_browser_goods(login):
print("瀏覽商品--不需要登入")
class Test_Demo:
def test_add_cart(self, login):
print("新增購物車--測試用例")
def test_add_address(self):
print("新增收貨地址--測試用例")
if __name__ == '__main__':
pytest.main()
test_02.py
檔案中的用例。
# 如果該用例不傳入fixture方法,該用例會優先與fixture前置執行
def test_browser_goods():
print("第2次-瀏覽商品--不需要登入")
class Test_Demo2:
def test_add_cart(self):
print("第2次-新增購物車--測試用例")
def test_add_address(self):
print("第2次-新增收貨地址--測試用例")
all.py
檔案內容:
import pytest
if __name__ == '__main__':
pytest.main()
"""
執行結果:只在該包內執行一次fixture前後置
scope=session 作用域的前置函式
瀏覽商品--不需要登入
PASSED
test_01.py::Test_Demo::test_add_cart 新增購物車--測試用例
PASSED
test_01.py::Test_Demo::test_add_address 新增收貨地址--測試用例
PASSED
test_02.py::test_browser_goods 第2次-瀏覽商品--不需要登入
PASSED
test_02.py::Test_Demo2::test_add_cart 第2次-新增購物車--測試用例
PASSED
test_02.py::Test_Demo2::test_add_address 第2次-新增收貨地址--測試用例
PASSED
scope=session 作用域的後置函式
"""
說明:
我把
session
作用域的Fixture寫在了test_01.py
檔案中,其實應該提取出來寫到conftest.py
檔案中。(後面文章會說明)
all.py
檔案就是為了執行所有測試用例,pytest.ini
檔案中配置的模糊匹配查詢,這樣兩個檔案中的用例就都能執行到了。這裡就是一個練習,寫的十分不規範,理解其意思就可以。
12、autouse引數說明
示例:實全部用例的前後置
很簡單,只需要把Fixture中的autouse
引數設定為True即可。
Fixture裝飾器會自動執行作用域範圍內的所有用例的前後置。
import pytest
@pytest.fixture(autouse=True)
def login():
print("輸入賬號,密碼,進行登入")
def test_add_cart(): # 不需要傳入fixture方法
print("新增購物車--需要登入")
def test_add_address(): # 不需要傳入fixture方法
print("新增收貨地址--需要登入")
if __name__ == '__main__':
pytest.main()
"""
執行結果:
輸入賬號,密碼,進行登入
新增購物車--需要登入
PASSED輸入賬號,密碼,進行登入
新增收貨地址--需要登入
PASSED
"""