五,第三方插件
1,調(diào)整測試用例的執(zhí)行順序
場景:未考慮按自然順序執(zhí)行時,或想變更執(zhí)行順序,比如增加 數(shù)據(jù)的用例要先執(zhí)行,再執(zhí)行刪除的用例。測試用例默認(rèn)是按名 稱順序執(zhí)行的。
? 解決:
? 安裝:pip install pytest-ordering
? 在測試方法上加下面裝飾器
?@pytest.mark.last —最后一個執(zhí)行
? @pytest.mark.run(order=1)—第幾個執(zhí)行
pytest默認(rèn)按字母順序去執(zhí)行的
import pytest
@pytest.mark.run(order=1)
def test_01():
print('test01')
@pytest.mark.run(order=2)
def test_02():
print('test01')
@pytest.mark.last
def test_06():
print('test01')
def test_04():
print('test01')
def test_05():
print('test01')
@pytest.mark.run(order=3)
def test_03():
print('test01')
pytest_order.py::test_01 PASSED [ 16%]test01
pytest_order.py::test_02 PASSED [ 33%]test01
pytest_order.py::test_03 PASSED [ 50%]test01
pytest_order.py::test_04 PASSED [ 66%]test01
pytest_order.py::test_05 PASSED [ 83%]test01
pytest_order.py::test_06 PASSED [100%]test01
2, 執(zhí)行用例遇到錯誤停止
? 正常全部執(zhí)行完成后才能停止,如果想遇到錯誤時停止測試: -x;也可以當(dāng)用例錯誤個數(shù)n達(dá)到指定數(shù)量時,停止測試:- - maxfail=n
? 執(zhí)行:
? pytest -x -v -s 文件名.py ------- -x是遇到錯誤就停止
? pytest -x -v -s 文件名.py —maxfail=2 ------- --maxfail=2 是遇到兩個錯誤就停止
3,執(zhí)行用例失敗后重新運(yùn)行
**場景:
? 測試失敗后要重新運(yùn)行n次,要在重新運(yùn)行之間添加延遲時 間,間隔n秒再運(yùn)行。
? 執(zhí)行:
? 安裝:pip install pytest-rerunfailures
? pytest -v - -reruns 5 --reruns-delay 1 —每次等1秒 重試5次
4,多條斷言前面報錯后面依然執(zhí)行
pip3 install pytest-assume 斷言后繼續(xù)執(zhí)行,但要修改斷言**
@pytest.mark.parametrize(('x', 'y'), [(1, 1), (1, 0), (0, 1)])
def test_assume(x, y):
pytest.assume(x == y)
pytest.assume(3 == 4)
pytest.assume(5 == 9)
5,多線程并行與分布式執(zhí)行
場景:測試用例1000條,一個用例執(zhí)行1鐘,一個測試人員執(zhí)行需要1000分 鐘。通常我們會用人力成本換取時間成本,加幾個人一起執(zhí)行,時間就會縮
短。如果10人一起執(zhí)行只需要100分鐘,這就是一種并行測試,分布式場景。
解決:pytest分布式執(zhí)行插件:pytest-xdist,多個CPU或主機(jī)執(zhí)行
前提:用例之間都是獨(dú)立的,沒有先后順序,隨機(jī)都能執(zhí)行,可重復(fù)運(yùn)行不 影響其他用例。
安裝:Pip3 install pytest-xdist
? 多個CPU并行執(zhí)行用例,直接加-n 3是并行數(shù)量:pytest -n 3 ? 在多個終端下一起執(zhí)行
import pytest
import time
@pytest.mark.parametrize('x',list(range(10)))
def test_somethins(x):
time.sleep(1)
pytest -v -s -n 5 test_xsdist.py ----一次執(zhí)行5個
運(yùn)行以下代碼,項(xiàng)目結(jié)構(gòu)如下
web_conf_py是項(xiàng)目工程名稱
│ conftest.py
│ __init__.py
│
├─baidu
│ │ conftest.py
│ │ test_1_baidu.py
│ │ test_2.py
│ │ __init__.py
│
├─blog
│ │ conftest.py
│ │ test_2_blog.py
│ │ __init__.py
代碼參考:
# web_conf_py/conftest.py
import pytest
@pytest.fixture(scope="session")
def start():
print("\n打開首頁")
return "yoyo"
# web_conf_py/baidu/conftest.py
import pytest
@pytest.fixture(scope="session")
def open_baidu():
print("打開百度頁面_session")
# web_conf_py/baidu/test_1_baidu.py
import pytest
import time
def test_01(start, open_baidu):
print("測試用例test_01")
time.sleep(1)
assert start == "yoyo"
def test_02(start, open_baidu):
print("測試用例test_02")
time.sleep(1)
assert start == "yoyo"
if __name__ == "__main__":
pytest.main(["-s", "test_1_baidu.py"])
# web_conf_py/baidu/test_2.py
import pytest
import time
def test_06(start, open_baidu):
print("測試用例test_01")
time.sleep(1)
assert start == "yoyo"
def test_07(start, open_baidu):
print("測試用例test_02")
time.sleep(1)
assert start == "yoyo"
if __name__ == "__main__":
pytest.main(["-s", "test_2.py"])
# web_conf_py/blog/conftest.py
import pytest
@pytest.fixture(scope="function")
def open_blog():
print("打開blog頁面_function")
# web_conf_py/blog/test_2_blog.py
import pytest
import time
def test_03(start, open_blog):
print("測試用例test_03")
time.sleep(1)
assert start == "yoyo"
def test_04(start, open_blog):
print("測試用例test_04")
time.sleep(1)
assert start == "yoyo"
def test_05(start, open_blog):
'''跨模塊調(diào)用baidu模塊下的conftest'''
print("測試用例test_05,跨模塊調(diào)用baidu")
time.sleep(1)
assert start == "yoyo"
if __name__ == "__main__":
pytest.main(["-s", "test_2_blog.py"])
正常運(yùn)行需要消耗時間:7.12 seconds
E:\YOYO\web_conf_py>pytest
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, metadata-1.7.0, html-1.19.0, forked-0.2
collected 7 items
baidu\test_1_baidu.py .. [ 28%]
baidu\test_2.py .. [ 57%]
blog\test_2_blog.py ... [100%]
========================== 7 passed in 7.12 seconds ===========================
設(shè)置并行運(yùn)行數(shù)量為3,消耗時間:3.64 seconds,大大的縮短了用例時間
E:\YOYO\web_conf_py>pytest -n 3
============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO\web_conf_py, inifile:
plugins: xdist-1.23.2, metadata-1.7.0, html-1.19.0, forked-0.2
gw0 [7] / gw1 [7] / gw2 [7]
scheduling tests via LoadScheduling
....... [100%]
========================== 7 passed in 3.64 seconds ==========================
6,其他有意思的插件
這里就不多說了,喜歡的可以自己研究下
7,使用pytest執(zhí)行unittest的測試用例
執(zhí)行unitest就和原來一樣,盡量不要混合使用搞那些花里胡哨的,用哪個就哪個,就不多說了
8,pytest-html生成報告
pytest-HTML是一個插件,pytest用于生成測試結(jié)果的HTML報告。兼容Python 2.7,3.6
pytest-html
1.github上源碼地址【https://github.com/pytest-dev/pytest-html】
2.pip安裝
pytest --html=report.html
html報告
1.打開cmd,cd到需要執(zhí)行pytest用例的目錄,執(zhí)行指令:pytest --html=report.html
2.執(zhí)行完之后,在當(dāng)前目錄會生成一個report.html的報告文件,顯示效果如下

指定報告路徑
1.直接執(zhí)行"pytest --html=report.html"生成的報告會在當(dāng)前腳本的同一路徑,如果想指定報告的存放位置,放到當(dāng)前腳本的同一目錄下的report文件夾里
2.如果想指定執(zhí)行某個.py文件用例或者某個文件夾里面的所有用例,需加個參數(shù)。具體規(guī)則參考【pytest文檔2-用例運(yùn)行規(guī)則】
報告獨(dú)立顯示
1.上面方法生成的報告,css是獨(dú)立的,分享報告的時候樣式會丟失,為了更好的分享發(fā)郵件展示報告,可以把css樣式合并到html里
$ pytest --html=report.html --self-contained-html
顯示選項(xiàng)
默認(rèn)情況下,“ 結(jié)果”表中的所有行都將被展開,但具測試通過的行除外Passed。
可以使用查詢參數(shù)自定義此行為:?collapsed=Passed,XFailed,Skipped。
更多功能
1.更多功能查看官方文檔【https://github.com/pytest-dev/pytest-html】
參考鏈接
https://blog.csdn.net/qq_42610167/article/details/101204066