pytest插件的7種用法
1.pytest-repeat 重復跑
安裝包
pip install pytest-repeat
第一種用法: 裝飾器 @pytest.mark.repeat(次數(shù))
示例代碼
import pytest @pytest.mark.repeat(5) def test_001(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv',__file__])
第二種用法: 命令行參數(shù)
語法
pytest --count=5 test.py
示例代碼
import pytest def test_001(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv','--count=5',__file__])
第三種用法: 結合repeat-scope運行
如果我們要對多個測試函數(shù)進行重復運行,要么加多個裝飾器,要么用命令行參數(shù)
但是上述兩種方法都是A重復,B重復這樣,無法做到AB-AB-AB的模式
如果要實現(xiàn)組合重復運行,那就要用到–repeat-scope
–repeat-scope類似于pytest fifixture的scope參數(shù),–repeat-scope也可以設置參數(shù):session, module , class 或者 function (默認值)
function (默認)范圍針對每個用例重復執(zhí)行,再執(zhí)行下一個用例
class 以class為用例集合單位,重復執(zhí)行class里面的用例,再執(zhí)行下一個
module 以模塊為單位,重復執(zhí)行模塊里面的用例,再執(zhí)行下一個
session 重復整個測試會話,即所有收集的測試執(zhí)行一次,然后所有這些測試再次執(zhí)行等等
示例代碼1:A運行2次,B運行2次
import pytest def test_002(): assert 1==2 def test_001(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv','--count=2',__file__]) #運行結果 FAILED test_demo1.py::test_002[1-2] - assert 1 == 2 FAILED test_demo1.py::test_002[2-2] - assert 1 == 2 FAILED test_demo1.py::test_001[1-2] - assert 1 == 2 FAILED test_demo1.py::test_001[2-2] - assert 1 == 2
示例代碼:A-B運行2次
import pytest def test_002(): assert 1==2 def test_001(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv','--count=2','--repeat-scope=session',__file__]) #AB運行1次后再運行1次AB FAILED test_demo1.py::test_002[1-2] - assert 1 == 2 FAILED test_demo1.py::test_001[1-2] - assert 1 == 2 FAILED test_demo1.py::test_002[2-2] - assert 1 == 2 FAILED test_demo1.py::test_001[2-2] - assert 1 == 2
2.pytest-assume 斷言后繼續(xù)跑
安裝
pip install pytest-assume
實際測試的過程中,有可能遇到一種情況,就是你某個斷言執(zhí)行失敗也想要做下去(比如登錄的測試,測試失敗后,還是要返回主頁繼續(xù)下一輪的測試)。而默認情況下,如果斷言失敗,assert后面的語句是不會執(zhí)行的了。
可以應用在多重斷言的場景?。梢酝瑫r做多個斷言)
沒有assume的示例
import pytest def test_001(): assert 1==2 #如果改為1==1,下面是不會執(zhí)行的 print('\n對了會做,錯了不會做') if __name__ == '__main__': pytest.main(['-s','test_order_001.py'])
有assume的示例
import pytest def test_001(): pytest.assume(1==2) print('\n對了會做,錯了也會做') if __name__ == '__main__': pytest.main(['-sv','test_order_001.py'])
assume的另外一種寫法:上下文管理器
def test_assume2(): with pytest.assume: assert 1==2 assert 1==3
下面圖1直接用pytest.assume不會顯式testid的內(nèi)容,而圖2中assert就能顯示變量的值,要解決這個問題就可以用with的寫法
3.pytest-ordering 用例順序
安裝
pip install pytest-ordering
pytest默認按字母順序去執(zhí)行的(小寫英文—>大寫英文—>0-9數(shù)字)
用例之間的順序是文件之間按照ASCLL碼排序,文件內(nèi)的用例按照從上往下執(zhí)行。
改變測試用例的執(zhí)行順序,用法是加上裝飾器
@pytest.mark.run(order=[number])
示例
import pytest @pytest.mark.run(order=2) # def test_001(): assert 1==1 @pytest.mark.run(order=1) #如果沒有這兩句話,那么運行順序就是001再002 def test_002(): assert 2==2 if __name__ == '__main__': pytest.main(['-v','test_order_001.py'])
其他的運行方式
方式一
第一個執(zhí)行:@ pytest.mark.first
第二個執(zhí)行:@ pytest.mark.second
倒數(shù)第二個執(zhí)行:@ pytest.mark.second_to_last
最后一個執(zhí)行:@pytest.mark.last
方式二
第一個執(zhí)行:@ pytest.mark.run('first')
第二個執(zhí)行:@ pytest.mark.run('second')
倒數(shù)第二個執(zhí)行:@ pytest.mark.run('second_to_last')
最后一個執(zhí)行:@ pytest.mark.run('last')
4.pytest-dependency 用例依賴
主要解決用例之間的依賴關系。如果依賴的上下文失敗后續(xù)的用例會被標識為跳過執(zhí)行,相當于執(zhí)
行了 pytest.mark.skip
安裝
pip install pytest-dependency
函數(shù)示例:
import pytest @pytest.mark.dependency() #打上標記 def test_001(): assert 1==2 @pytest.mark.dependency(depends=['test_001']) #依賴于test_001,test_001斷言 成功了才會繼續(xù)這個。 def test_002(): assert 1==1 if __name__ == '__main__': pytest.main(['-sv','test_order_001.py'])
name示例:
import pytest @pytest.mark.dependency(name='a') def test_001(): assert 1==2 @pytest.mark.dependency(depends=['a']) def test_002(): assert 1==1 if __name__ == '__main__': pytest.main(['-sv','test_order_001.py'])
類示例
import pytest class Test_001(): @pytest.mark.dependency() def test_001(self): assert 1==2 @pytest.mark.dependency(depends=['Test_001::test_001']) def test_002(): assert 1==1 if __name__ == '__main__': pytest.main(['-sv','test_order_001.py'])
5.pytest-rerunfailures 用例失敗重跑
安裝
pip install pytest-rerunfailures
使用方法一: 裝飾器
import pytest import random from arrow import now @pytest.mark.flaky(reruns=50,reruns_delay=2) #重跑50次,每次間隔2s def test_001(): print(now().format('YYYY-MM-DD HH:mm:ss')) assert 1==random.randint(1,5) #只要在多次RERUN中遇到一次成功,即可停止,并最終結果 為PASSED if __name__ == '__main__': pytest.main(['-sv',__file__])
使用方法二: 命令行
import pytest def test_001(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv','--reruns=2','--reruns-delay=2',__file__]) #參數(shù)前千萬不要有空格,會報錯
6.pytest-xdist 分布式執(zhí)行
pytest-xdist,讓自動化測試用例可以分布式執(zhí)行,從而大大節(jié)省測試時間。pytest-xdist 是屬于進程級別的并發(fā)。
分布式測試用例的設計原則:
(1)獨立運行:用例之間是獨立的,并且沒有依賴關系,還可以完全獨立運行。
(2)隨機執(zhí)行:用例執(zhí)行不強制按順序執(zhí)行,支持順序執(zhí)行或隨機執(zhí)行。
(3)不影響其他用例:每個用例都能重復運行,運行結果不會影響其他用例
pytest-xdist 通過一些獨特的測試執(zhí)行模式擴展了 pytest:
(1)測試運行并行化:如果有多個CPU或主機,則可以將它們用于組合的測試運行。這樣可以加快開發(fā)速度或使用遠程計算機的特殊資源。
(2)–looponfail:在子進程中重復運行測試。每次運行之后,pytest 都會等到項目中的文件更改后再
運行之前失敗的測試。重復此過程,直到所有測試通過,然后再次執(zhí)行完整運行。
(3)跨平臺覆蓋:可以指定不同的 Python 解釋器或不同的平臺,并在所有這些平臺上并行運行測試。
用法:
其實就是參數(shù)
-n numprocesses #如 -n 2 就是用2個
-n auto #自動檢測物理CPU個數(shù)
-n logical #檢測邏輯CPU個數(shù)
邏輯CPU個數(shù)=物理cpu數(shù)量x cpu核數(shù) x 1(不支持ht超線程技術,如果開啟就是2)
超線程:一個CPU核就是一個物理線程,由英特爾開發(fā)超線程技術可以把一個物理線程模擬出兩個線程來
使用,使得單個核心用起來像兩個核一樣,以充分發(fā)揮CPU的性能.
參數(shù)
distributed and subprocess testing:
-n numprocesses, --numprocesses=numprocesses
Shortcut for '--dist=load --tx=NUM*popen'. With
'auto',
attempt to detect physical CPU count. With
'logical',
detect logical CPU count. If physical CPU count
cannot
be found, falls back to logical count. This will be
0
when used with --pdb.
--maxprocesses=maxprocesses
limit the maximum number of workers to process the
tests
when using --numprocesses=auto
--max-worker-restart=MAXWORKERRESTART
maximum number of workers that can be restarted when
crashed (set to zero to disable this feature)
--dist=distmode set mode for distributing tests to exec
environments.
each: send each test to all available environments.
load: load balance by sending any pending test to
any
available environment.
loadscope: load balance by sending pending groups of
tests in the same scope to any available
environment.
loadfile: load balance by sending test grouped by
file
to any available environment.
(default) no: run tests inprocess, don't distribute.
--tx=xspec add a test execution environment. some examples: --
tx
popen//python=python2.5 --tx
socket=192.168.1.102:8888
--tx ssh=user@codespeak.net//chdir=testcache
-d load-balance tests. shortcut for '--dist=load'
--rsyncdir=DIR add directory for rsyncing to remote tx nodes.
--rsyncignore=GLOB add expression for ignores when rsyncing to remote
tx
nodes.
--boxed backward compatibility alias for pytest-forked --
forked
--testrunuid=TESTRUNUID
provide an identifier shared amongst all workers as
the
value of the 'testrun_uid' fixture,
,if not provided, 'testrun_uid' is filled with a new
unique string on every test run.
-f, --looponfail run tests in subprocess, wait for modified files and
re•run failing test set until all pass.
7.pytest-xfail 預期失敗
第一種用法:
import pytest @pytest.mark.xfail(True,reason='預期失敗,結果成功') def test_xfail1(): assert True @pytest.mark.xfail(True,reason='預期失敗,結果失敗') def test_xfail2(): assert False @pytest.mark.xfail(False,reason='預期成功,結果失敗') def test_xfail3(): assert False @pytest.mark.xfail(False,reason='預期成功,結果成功') def test_xfail4(): assert True if __name__ == '__main__': pytest.main(['-sv',__file__])
輸出:
test_xfail.py::test_xfail1 XPASS (預期失敗,結果成功)
test_xfail.py::test_xfail2 XFAIL (預期失敗,結果失敗)
test_xfail.py::test_xfail3 FAILED
test_xfail.py::test_xfail4 PASSED
第二種用法:
import pytest @pytest.mark.xfail(raises=AssertionError) def test_xfail2(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv',__file__])
輸出:
test_xfail2.py::test_xfail2 XFAIL
如果這個時候帶上–runxfail參數(shù),就會忽略所有的xfail
import pytest @pytest.mark.xfail(raises=AssertionError) def test_xfail2(): assert 1==2 if __name__ == '__main__': pytest.main(['-sv','--runxfail',__file__]) ###輸出就相當于沒有那個裝飾器 test_xfail2.py::test_xfail2 FAILED ================================== FAILURES =================================== _________________________________ test_xfail2 _________________________________ @pytest.mark.xfail(raises=AssertionError) def test_xfail2(): > assert 1==2 E assert 1 == 2 E +1 E -2 test_xfail2.py:6: AssertionError =========================== short test summary info =========================== FAILED test_xfail2.py::test_xfail2 - assert 1 == 2 ============================== 1 failed in 0.06s ==============================
第三種用法:
def test_xfail3(): pytest.xfail() assert 1==2 if __name__ == '__main__': pytest.main(['-sv',__file__])
同上輸出
到此這篇關于pytest插件的7種用法的文章就介紹到這了,更多相關pytest 插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!