大家好,我是J哥~
1、Pytest簡(jiǎn)介1.1 入門階段1.1.1 運(yùn)行測(cè)試用例一切的理論,都是為了實(shí)戰(zhàn)準(zhǔn)備的, 所以,我們第一步,先上例子,直接實(shí)戰(zhàn)! 編寫簡(jiǎn)單的測(cè)試用例,文件名稱為'test_sample.py' # pytest test_sample.py def inc(x): return x + 1
def test_answer(): assert inc(3) == 5
這兩個(gè)方法都非常的簡(jiǎn)單, - test_answer()對(duì)目標(biāo)函數(shù)inc進(jìn)行斷言;- pytest test_sample.py 運(yùn)行測(cè)試用例 我們看向運(yùn)行結(jié)果
測(cè)試結(jié)果顯示,運(yùn)行了一個(gè)測(cè)試用例,結(jié)果是紅色,表示失敗。錯(cuò)誤信息顯示,在代碼的第7行拋出AssertionError??梢愿囊幌麓a,讓測(cè)試用例綠色通過。 這個(gè)測(cè)試用例涉及pytest的3個(gè)簡(jiǎn)單的規(guī)則: - 測(cè)試模塊以 test_ 前綴命名- 測(cè)試用例(函數(shù))同樣以 test_ 前綴命名- 結(jié)果判斷使用 assert 斷言即可
1.1.2. 異常處理捕獲異常,及異常處理,是每段代碼中必要條件, 當(dāng)然,pytest也支持異常的捕獲, 方法為:使用 with + pytest.raises 捕獲目標(biāo)函數(shù)的異常: # -*- coding:utf-8 -*- # @Time : 2021-09-05 # @Author : Carl_DJ
import pytest
def f(): raise SystemExit(1)
def test_mytest(): #捕獲異常 with pytest.raises(SystemExit): f()
1.1.3 測(cè)試類當(dāng)然,pytest也支持測(cè)試類, 測(cè)試類的作用:用來做測(cè)試用來分組 # -*- coding:utf-8 -*- # @Time : 2021-09-05 # @Author : Carl_DJ
class TestClass: #test_開頭 def test_one(self): x = 'this' assert 'h' in x #test_開頭 def test_two(self): x = 'hello' assert hasattr(x, 'check')
這里,都是以test_開頭, 跟unittest都是一樣。 如果不是test_開頭,則無法被調(diào)用的。
1.1.4 自動(dòng)運(yùn)行測(cè)試腳本如果一個(gè)suit文件夾有多個(gè)測(cè)試用例腳本, 我們只需要輸入一個(gè) pytest,即可運(yùn)行全部測(cè)試腳本。 如下圖
這就是開啟了懶人模式。
1.2 進(jìn)階技巧1.2.1 parametrize俗話說,代碼不參數(shù),變參淚兩行! 所以,能參數(shù)的時(shí)候,就盡量參數(shù),不管重構(gòu)苦不苦。我們先看下parametrize的用法,如下: 在測(cè)試用例的前面加上:@pytest.mark.parametrize(“參數(shù)名”,列表數(shù)據(jù)) 參數(shù)名:用來接收每一項(xiàng)數(shù)據(jù),并作為測(cè)試用例的參數(shù)。列表數(shù)據(jù):一組測(cè)試數(shù)據(jù)。 看例子 不添加parametrize,看看咋寫測(cè)試用例 def test_eval(): assert eval('3+5') == 8 assert eval(''2'+'4'') == '24' assert eval('6*9') == 54
看著很麻煩, 我們?cè)儆靡幌聀arametrize優(yōu)化一下,看看是否簡(jiǎn)潔很多 #使用parametrize對(duì)測(cè)試用例參數(shù)化 @pytest.mark.parametrize('test_input,expected', [ ('3+5', 8), (''2'+'4'', '24'), ('6*9', 54) ]) def test_eval_1(test_input, expected): assert eval(test_input) == expected
看了這段代碼,就很簡(jiǎn)潔了。我們再來看看,parametrize做了什么。 - 先調(diào)整測(cè)試函數(shù)的參數(shù)為輸入和期望;- 然后在parametrize填寫參數(shù)值;- 運(yùn)行時(shí)候會(huì)自動(dòng)進(jìn)行函數(shù)參數(shù)賦值。這樣再增加測(cè)試條件,不需要改動(dòng)test_eval_1的函數(shù)體, 增加條件數(shù)組就可以了。
1.2.2. markmark就是一個(gè)標(biāo)簽,標(biāo)記哪些測(cè)試用例執(zhí)行,哪些不執(zhí)行。 #標(biāo)簽 @pytest.mark.slow def test_mark(): print('test mark') # 模擬運(yùn)行很耗時(shí)的測(cè)試用例 time.sleep(10) assert 5 == 5
然后目錄下增加 pytest.ini 文件,對(duì)pytest進(jìn)行配置: [pytest] markers = slow: marks tests as slow (deselect with '-m 'not slow'')
使用下面命令可以跳過標(biāo)記的函數(shù),加快測(cè)試速度: pytest test_sample.py -m 'not slow'
也可以僅僅運(yùn)行標(biāo)記的函數(shù) pytest -m slow
1.2.3 fixturefixture 就類似于unittest的 setup/teardown,但是功能比這個(gè)強(qiáng)大一些。舉個(gè)例子 # -*- coding:utf-8 -*- # @Time : 2021-09-05 # @Author : Carl_DJ
import pytest
#設(shè)置fixture @pytest.fixture def first_entry(): return 'a'
#設(shè)置fixture @pytest.fixture def second_entry(): return 2
#設(shè)置fixture @pytest.fixture def order(first_entry, second_entry): return [first_entry, second_entry]
#設(shè)置fixture @pytest.fixture def expected_list(): return ['a', 2, 3.0]
def test_string(order, expected_list): order.append(3.0)
# 斷言 assert order == expected_list
當(dāng)然了,fixture還可以嵌套,order嵌套了first_entry和second_entry。 那測(cè)試數(shù)據(jù)庫寫入的用例,需要一個(gè)數(shù)據(jù)庫鏈接,怎么辦呢?這個(gè),也不難,fixture也可以搞定。在測(cè)試用例目錄編寫conftest.py @pytest.fixture def database_connection(): # coding... ...
1.2.4 plugin&&hook可以編寫pytest的插件plugin和hook對(duì)pytest進(jìn)行擴(kuò)展。先創(chuàng)建一個(gè)目錄a,然后再目錄a中創(chuàng)建conftest.py和test_sub.py 兩個(gè)文件。 #在目錄a下創(chuàng)建conftest.py def pytest_runtest_setup(item): # 在目錄a下運(yùn)行每個(gè)用例 print('setting up', item) # 在目錄a下創(chuàng)建test_sub.py def test_sub(): pass
使用 pytest a/test_sub.py --capture=no 會(huì)加載我們編寫的pluging和hook,在console中可以看到下面字樣: ... a/test_sub.py setting up <Function test_sub>
敲黑板:使用pytest_runtest_setup可以實(shí)現(xiàn)測(cè)試框架中的setup類似功能。
2、總結(jié)以上就是總結(jié)的一些pytest常用的功能,是不是也很簡(jiǎn)單呢。 我們再回顧一下,今天都講了哪些知識(shí)! 測(cè)試目錄一般使用 tests 命名和src同層級(jí)- 測(cè)試模塊使用 test_ 前綴- 測(cè)試類使用 Test 前綴,不需要繼承其它父類- 測(cè)試用例也使用 test_ 前綴- 可以使用parametrize進(jìn)行參數(shù)化處理- 可以使用mark給測(cè)試用例加標(biāo)簽- 可以使用fixture模擬測(cè)試條件- 使用pytest.ini文件對(duì)pytest進(jìn)行配置- 可以編寫插件和hoo對(duì)pytest擴(kuò)展 關(guān)于pytest更多的內(nèi)容, 可以持續(xù)關(guān)注, 也可以閱讀官方文檔。
|