您好,登錄后才能下訂單哦!
這篇文章主要講解了“Pytest自動化測試框架如何使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Pytest自動化測試框架如何使用”吧!
如何區分這兩者,很簡單unittest作為官方的測試框架,在測試方面更加基礎,并且可以再次基礎上進行二次開發,同時在用法上格式會更加復雜;而pytest框架作為第三方框架,方便的地方就在于使用更加靈活,并且能夠對原有unittest風格的測試用例有很好的兼容性,同時在擴展上更加豐富,可通過擴展的插件增加使用的場景,比如一些并發測試等;
pip安裝:
pip install pytest
測試安裝成功:
pytest --help py.test --help
檢查安裝版本:
pytest --version
Pytest編寫規則:
測試文件以test_開頭(以_test為結尾)
測試的類以Test開頭;
測試的方法以test_開頭
斷言使用基本的assert
test_example.py
def count_num(a: list) -> int: return len(a) def test_count(): assert count_num([1, 2, 3]) != 3
執行測試:
pytest test_example.py
執行結果:
C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest>pytest test_example.py -v
================================================================= test session starts =================================================================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- d:\coding\python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collected 1 item
test_example.py::test_count FAILED [100%]
====================================================================== FAILURES =======================================================================
_____________________________________________________________________ test_count ______________________________________________________________________
def test_count():
> assert count_num([1, 2, 3]) != 3
E assert 3 != 3
E + where 3 = count_num([1, 2, 3])
test_example.py:11: AssertionError
=============================================================== short test summary info ===============================================================
FAILED test_example.py::test_count - assert 3 != 3
================================================================== 1 failed in 0.16s ==================================================================
備注:
.代表測試通過,F代表測試失敗;
-v顯示詳細的測試信息, -h顯示pytest命令詳細的幫助信息;
默認情況下,pytest會在當前目錄下尋找以test_為開頭(以_test結尾)的測試文件,并且執行文件內所有以test_為開頭(以_test為結尾)的所有函數和方法;
指定運行測試用例,可以通過::顯示標記(文件名::類名::方法名)(文件名::函數名)
pytest test_example3.py::test_odd
指定一些測試用例測試運行,可以使用-k模糊匹配
pytest -k example
通過pytest.mark.skip()或者pytest.makr.skipif()條件表達式,跳過指定的測試用例
import pytest test_flag = False @pytest.mark.skip() def test_odd(): num = random.randint(0, 100) assert num % 2 == 1 @pytest.mark.skipif(test_flag is False, reason="test_flag is False") def test_even(): num = random.randint(0, 1000) assert num % 2 == 0
通過pytest.raises()捕獲測試用例可能拋出的異常
def test_zero(): num = 0 with pytest.raises(ZeroDivisionError) as e: num = 1/0 exc_msg = e.value.args[0] print(exc_msg) assert num == 0
預先知道測試用例會失敗,但是不想跳過,需要顯示提示信息,使用pytest.mark.xfail()
@pytest.mark.xfail() def test_sum(): random_list = [random.randint(0, 100) for x in range(10)] num = sum(random_list) assert num < 20
對測試用例進行多組數據測試,每組參數都能夠獨立執行一次(可以避免測試用例內部執行單組數據測試不通過后停止測試)
@pytest.mark.parametrize('num,num2', [(1,2),(3,4)]) def test_many_odd(num: int, num2: int): assert num % 2 == 1 assert num2 % 2 == 0
固件就是一些預處理的函數,pytest會在執行測試函數前(或者執行后)加載運行這些固件,常見的應用場景就有數據庫的連接和關閉(設備連接和關閉)
簡單使用
import pytest @pytest.fixture() def postcode(): return "hello" def test_count(postcode): assert postcode == "hello"
按照官方的解釋就是當運行測試函數,會首先檢測運行函數的參數,搜索與參數同名的fixture,一旦pytest找到,就會運行這些固件,獲取這些固件的返回值(如果有),并將這些返回值作為參數傳遞給測試函數;
接下來進一步驗證關于官方的說法:
import pytest @pytest.fixture() def connect_db(): print("Connect Database in .......") yield print("Close Database out .......") def read_database(key: str): p_info = { "name": "zhangsan", "address": "China Guangzhou", "age": 99 } return p_info[key] def test_count(connect_db): assert read_database("name") == "zhangsan"
執行測試函數結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 1 item
test_example.py::test_count Connect Database in .......
PASSED [100%]Close Database out .......
============================== 1 passed in 0.07s ==============================
備注:
首先從結果上看驗證了官方的解釋,pytest執行測試函數前會尋找同名的固件加載運行;
connect_db固件中有yield,這里pytest默認會判斷yield關鍵詞之前的代碼屬于預處理,會在測試前執行,yield之后的代碼則是屬于后處理,將在測試后執行;
從前面大致了解了固件的作用,抽離出一些重復的工作方便復用,同時pytest框架中為了更加精細化控制固件,會使用作用域來進行指定固件的使用范圍,(比如在這一模塊中的測試函數執行一次即可,不需要模塊中的函數重復執行)更加具體的例子就是數據庫的連接,這一連接的操作可能是耗時的,我只需要在這一模塊的測試函數運行一次即可,不需要每次都運行。
而定義固件是,一般通過scop參數來聲明作用,常用的有:
function: 函數級,每個測試函數都會執行一次固件;
class: 類級別,每個測試類執行一次,所有方法都可以使用;
module: 模塊級,每個模塊執行一次,模塊內函數和方法都可使用;
session: 會話級,一次測試只執行一次,所有被找到的函數和方法都可用。
import pytest @pytest.fixture(scope="function") def func_scope(): print("func_scope") @pytest.fixture(scope="module") def mod_scope(): print("mod_scope") @pytest.fixture(scope="session") def sess_scope(): print("session_scope") def test_scope(sess_scope, mod_scope, func_scope): pass def test_scope2(sess_scope, mod_scope, func_scope): pass
執行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example2.py::test_scope session_scope
mod_scope
func_scope
PASSED [ 50%]
test_example2.py::test_scope2 func_scope
PASSED [100%]
============================== 2 passed in 0.07s ==============================
從這里可以看出module,session作用域的固件只執行了一次,可以驗證官方的使用介紹
有人可能會說,這樣子怎么那么麻煩,unittest框架中直接定義setUp就能自動執行預處理,同樣的pytest框架也有類似的自動執行; pytest框架中固件一般通過參數autouse控制自動運行。
import pytest @pytest.fixture(scope='session', autouse=True) def connect_db(): print("Connect Database in .......") yield print("Close Database out .......") def test1(): print("test1") def test2(): print("test")
執行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example.py::test1 Connect Database in .......
PASSED [ 50%]test1
test_example.py::test2 PASSED [100%]test
Close Database out .......
============================== 2 passed in 0.07s ==============================
從結果看到,測試函數運行前后自動執行了connect_db固件;
前面簡單的提到過了@pytest.mark.parametrize通過參數化測試,而關于固件傳入參數時則需要通過pytest框架中內置的固件request,并且通過request.param獲取參數
import pytest @pytest.fixture(params=[ ('redis', '6379'), ('elasticsearch', '9200') ]) def param(request): return request.param @pytest.fixture(autouse=True) def db(param): print('\nSucceed to connect %s:%s' % param) yield print('\nSucceed to close %s:%s' % param) def test_api(): assert 1 == 1
執行結果:
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
test_example.py::test_api[param0]
Succeed to connect redis:6379
PASSED [ 50%]
Succeed to close redis:6379
test_example.py::test_api[param1]
Succeed to connect elasticsearch:9200
PASSED [100%]
Succeed to close elasticsearch:9200
============================== 2 passed in 0.07s ==============================
這里模擬連接redis和elasticsearch,加載固件自動執行連接然后執行測試函數再斷開連接。
感謝各位的閱讀,以上就是“Pytest自動化測試框架如何使用”的內容了,經過本文的學習后,相信大家對Pytest自動化測試框架如何使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。