快速開(kāi)始
pytest是目前比較流行的單元測(cè)試工具,可以幫助研發(fā)做單元測(cè)試, 可以幫助測(cè)試構(gòu)造自動(dòng)化測(cè)試case。
pytest
結(jié)合報(bào)告生成工具Allure
,可以讓我們更好的查看測(cè)試結(jié)果。
1、用例文件:所有文件名為 test_ 開(kāi)頭 或者 _test 開(kāi)頭的文件會(huì)被識(shí)別為用例文件。
2、用例類,測(cè)試文件中每個(gè)Test開(kāi)頭的類就是一個(gè)測(cè)試用例類。
3、測(cè)試用例:測(cè)試類中每個(gè)test開(kāi)頭的方法就是一條測(cè)試用例,測(cè)試文件中每個(gè)test開(kāi)頭的函數(shù)也是一條測(cè)試用例
4、執(zhí)行用例:pytest 會(huì)遞歸查找當(dāng)前目錄下所有以 test 開(kāi)始或結(jié)尾的 Python 腳本,并執(zhí)行文件內(nèi)的所有以 test 開(kāi)始或結(jié)束的函數(shù)和方法。
Case 1
1. 編寫(xiě)用例
用例函數(shù)
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
2. 執(zhí)行測(cè)試
測(cè)試文件test_learn.py
文件夾下執(zhí)行pytest
PyTest$ pytest
============================================================================= test session starts =============================================================================
platform darwin -- Python 3.9.6, pytest-7.2.1, pluggy-1.0.0
rootdir: /Users/**/technical-operation-master/FSHandle/PyTest
plugins: allure-pytest-2.12.0
collected 1 item
test_learn.py .
============================================================================== 1 passed in 0.02s ==============================================================================
test_learn.py .
測(cè)試結(jié)果中 .代表測(cè)試通過(guò)
, S代表測(cè)試跳過(guò)
,<font color='red'> F代表測(cè)試失敗
</font>
Case 2
1. 編寫(xiě)用例 test_ 開(kāi)頭 或者 _test 開(kāi)頭
用例類和函數(shù)
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
class TestCalculateMethod:
def subtraction(self, a, b):
return a - b
def test_subtraction(self):
return self.subtraction(2, 1) == 1
def test_add(self):
assert add(1, 2) == 4
執(zhí)行測(cè)試pytest
========== test session starts ==========
platform darwin -- Python 3.9.6, pytest-7.2.1, pluggy-1.0.0
rootdir: /Users/**/technical-operation-master/FSHandle/PyTest
plugins: allure-pytest-2.12.0
collected 3 items
test_learn.py ..F [100%]
========== FAILURES ==========
一共3個(gè)test case, 2個(gè)成功,1個(gè)失敗
測(cè)試函數(shù)
斷言
assert ** 判斷**為真
assert not ** 判斷**不為真
assert a in b 判斷b包含a
assert a == b 判斷a等于b
assert a != b 判斷a不等于b
測(cè)試異常捕獲 pytest.raises(CustomException)
有些case需要測(cè)試,異常情況下是否可以正常拋出異常
import pytest
class CustomException(Exception):
pass
class TestPytest:
def test_exception_catch(self):
with pytest.raises(CustomException) as e:
raise CustomException("custom exception")
assert e.value.args[0] == "custom exception"
參數(shù)化 pytest.mark.parametrize("param_name", params)
比如登錄模塊,我們要驗(yàn)證正常用戶名、密碼、錯(cuò)誤的用戶名密碼、還有異常的用戶名密碼等case,無(wú)需再寫(xiě)多個(gè)case,或者在測(cè)試方法里邊構(gòu)造循環(huán),只需引入?yún)?shù)化即可實(shí)現(xiàn)。
@pytest.mark.parametrize("user_name, user_pass",
[("jack001", "eflds8fse30f4lfj"),
("jack01", "sdfssfef"),
("jack", "sdfs"),
("jack", "sdfsdfsdf")])
def test_login(user_name, user_pass):
assert len(user_name) > 5
assert len(user_pass) > 5
執(zhí)行測(cè)試
? pytest
=================== test session starts ===================
platform darwin -- Python 3.9.6, pytest-7.2.1, pluggy-1.0.0
rootdir: /Users/**/technical-operation/FSHandle
plugins: allure-pytest-2.12.0
collected 4 items
test_function.py ..FF [100%]
=================== FAILURES ===================
一共收集到了4個(gè)Case,2個(gè)成功,2個(gè)失敗
預(yù)見(jiàn)錯(cuò)誤 pytest.mark.xfail
import sys
@pytest.mark.xfail(sys.platform != 'darwin',
reason='other version is not implement')
def test_new_method():
print(sys.platform)
Case跳過(guò) @pytest.mark.skip(reason='')
@pytest.mark.skip(reason='method is not ready')
def test_skip():
assert True
@pytest.mark.skipif(sys.platform != 'darwin',
reason='other platform is not support')
def test_skip_if():
assert True
通過(guò)運(yùn)行測(cè)試時(shí)制定測(cè)試內(nèi)容
pytest.main (['./path/test_module.py::TestClass::test_method'])
pytest ./path/test_module.py::TestClass::test_method
pytest.main(['-k','new','./path/test_module.py'])
預(yù)處理和后處理
@pytest.fixture(scope='function')
def func_scope():
print('before')
yield
print('after')
@pytest.fixture(scope='module')
def mod_scope():
print('before')
yield
print('after')
@pytest.fixture(scope='session')
def sess_scope():
print('before')
yield
print('after')
@pytest.fixture(scope='class')
def class_scope():
print('before')
yield
print('after')
class TestScope(object):
def test_scope(self, class_scope, sess_scope, mod_scope, func_scope):
pass
def test_scope01(self, class_scope, sess_scope, mod_scope, func_scope):
pass
運(yùn)行測(cè)試
? pytest -s --setup-show
========== test session starts ==========
platform darwin -- Python 3.9.6, pytest-7.2.1, pluggy-1.0.0
rootdir: /Users/Developer/technical-operation/FSHandle
plugins: allure-pytest-2.12.0
collected 2 items
test_function.py before
SETUP S sess_scopebefore
SETUP M mod_scopebefore
SETUP C class_scopebefore
SETUP F func_scope
test_function.py::TestScope::test_scope (fixtures used: class_scope, func_scope, mod_scope, sess_scope).after
TEARDOWN F func_scopebefore
SETUP F func_scope
test_function.py::TestScope::test_scope01 (fixtures used: class_scope, func_scope, mod_scope, sess_scope).after
TEARDOWN F func_scopeafter
TEARDOWN C class_scopeafter
TEARDOWN M mod_scopeafter
TEARDOWN S sess_scope
=========== 2 passed in 0.02s ===========
按照如下順序執(zhí)行:
- scope = session 被執(zhí)行了一次
- scope = module 被執(zhí)行了一次
- scope = class 如果func被放在class中, 則只執(zhí)行一次
- scope = class 如果func沒(méi)被放在class中, 則每個(gè)函數(shù)執(zhí)行前,都執(zhí)行一次
- scope = function 每次執(zhí)行方法前都會(huì)執(zhí)行
pytest參數(shù)說(shuō)明
-v 說(shuō)明:可以輸出用例更加詳細(xì)的執(zhí)行信息,比如用例所在的文件及用例名稱等
-s 說(shuō)明:輸入我們用例中的調(diào)式信息,比如print的打印信息等
-x:遇到錯(cuò)誤的用例,立即退出執(zhí)行,并輸出結(jié)果
-k "關(guān)鍵字" 說(shuō)明:執(zhí)行用例包含“關(guān)鍵字”的用例,允許使用or、and
-q 說(shuō)明:簡(jiǎn)化控制臺(tái)的輸出,可以看出輸出信息和上面的結(jié)果都不一樣,下圖中有兩個(gè)..點(diǎn)代替了pass結(jié)果
# 如果要運(yùn)行多個(gè)標(biāo)識(shí)的話,用表達(dá)式,如下
pytest -k "slow or faster" test_1.py 運(yùn)行有slow標(biāo)識(shí)或 faster標(biāo)識(shí)用例
通過(guò)pytest.main()執(zhí)行測(cè)試
pytest.main(['./'])
# 指定路徑、模塊、類、方法
pytest.main (['./path/test_module.py::TestClass::test_method'])
# 指定關(guān)鍵字
pytest.main(['-k','new','./path/test_module.py'])
# -s,測(cè)試結(jié)果中顯示測(cè)試用例里print的內(nèi)容
pytest.main(["-s", "testcase/test_case.py"])
# -v,設(shè)置測(cè)試結(jié)果顯示的詳細(xì)程度
pytest.main(["-v", "testcase/test_case.py"])
# -q,設(shè)置測(cè)試結(jié)果顯示的詳細(xì)程度
pytest.main(["-q", "testcase/test_case.py"])
祝你好運(yùn)