首先祝你們國慶節日快樂,這個假期由於我老婆要考注會,我也跟着每天去圖書館學了幾天,學習的感受仍是很是不錯的,這是一篇總結。html
這篇博客準備講解一下pytest測試框架,這個框架是當前最流行的python語言最流行的單測框架,不掌握可不行,首先這個框架屬於第三方模塊,須要經過pip安裝便可python
pip install pytest
下面咱們進入正題框架
一、測試文件的名稱必需要以test_*.py的格式,或者*_test.py的格式函數
二、測試類的名稱必需要以Test開頭,且這個類還不能有構造方法(__init__)單元測試
三、測試函數的名稱必需要以test開頭學習
pytest默認的就按照上面的三條規則來執行案例,固然咱們能夠自定義運行規則,這個咱們後面在講,這個不重要,看一個最簡單的例子測試
import os import pytest # pytest是python的單元測試框架 def func(x): return x + 1 def test_a(): print("____test_a____") assert func(2) == 5 def test_b(): print("____test_b____") assert func(2) == 3 if __name__ == '__main__': pytest.main(["-s","pytest1.py"])
若是同窗們以前用過unittest測試框架,對測試固件這個這個名詞就不會陌生了,若是不清楚,能夠看下以前我寫的unittest測試框架的博客(https://www.cnblogs.com/bainianminguo/p/11616526.html)ui
pytest框架的測試固件有兩種,一種函數級別的,一種是類級別,執行的順序以下插件
a、執行類的前置條件3d
b、執行函數的前置條件
c、執行函數的後置條件
d、執行類的後置條件
使用也很是簡單,當時函數的命名必定要和我下面的備註保持徹底一致
# pytest的前置和後置條件 # 一、函數級別 setup teardown # 運行於測試方法的開始和結束 # 運行一個測試用例,會運行一次setup和teardown # 二、類級 setup_class teardown_class # 運行於測試類的開始和結束 # 一個測試類只運行一次setup_class teardown_class
import os import pytest def func(x): return x + 1 def test_a(): print("____test_a____") assert func(2) == 5 def test_b(): print("____test_b____") assert func(2) == 3 def setup(): print("函數級別的前置") def teardown(): print("函數級別的後置")
執行結果以下
class Testclass: def test_a(self): print("____test_a____") assert func(2) == 5 def test_b(self): print("____test_b____") assert func(2) == 3 def setup(self): print("函數級別的前置") def teardown(self): print("函數級別的後置") if __name__ == '__main__': pytest.main(["-s","pytest2.py"])
執行結果以下
import pytest def func(x): return x + 1 class Testclass: def test_a(self): print("____test_a____") assert func(2) == 5 def test_b(self): print("____test_b____") assert func(2) == 3 def setup(self): print("函數級別的前置") def teardown(self): print("函數級別的後置") def setup_class(self): print("類級別的前置") def teardown_class(self): print("類級別的後置") if __name__ == '__main__': pytest.main(["-s","pytest3.py"])
結果以下
咱們在博客的第一部分介紹了pytest框架的運行規則,這裏咱們能夠修改pytest的配置文件,改變框架運行規則
首先咱們要在案例的目錄下建立一個pytest.ini的配置文件
內容以下
# 建立pytest.ini文件 # [pytest] # addopts=-s #這個先這樣寫,這個主要是執行參數 # testpaths = testcase # 只執行這個目錄下的文件 # # python_files = test_*.py #執行的文件的名字 # python_classes = Test_* #執行類的名字 # python_functions = test_* # 執行函數的名字
配置文件截圖
經過上面的步驟,咱們就能夠改變pytest的運行規則
pytest的斷言是用python的斷言,他不像unittest框架,他本身實現了斷言
# -*- coding:utf-8 -*- # pytest是使用python自帶的斷言 import pytest def func(x): return x + 1 def test_a(): print("____test_a____") assert func(2) == 5 def test_b(): print("____test_b____") assert not func(2) == 3 def test_c(): print("____test_b____") assert func(2) in ["a","b","c"] def test_d(): print("____test_b____") assert func(2) not in ["a","b","c"] if __name__ == '__main__': pytest.main(["-s","pytest5.py"])
一個函數能夠打多個標記,一個標記同時能夠給多個函數打標記。只須要讓這個標記的裝飾器函數裝飾咱們的測試類或者測試函數
class Test_mark(): @pytest.mark.test01 def test_a(self): print("mark test a") @pytest.mark.test02 def test_b(self): print("mark test b") if __name__ == '__main__': pytest.main(['-s',"pytest6.py"])
還有其它的執行方式
# pytest -m test01 # pytest -n "test01 or test02" # pytest -m "not test01"
# -*- coding:utf-8 -*- import pytest # skip跳過執行某個案例 @pytest.mark.skip(reson="只是這個函數用例不執行") def test_a(): print("testa") def test_b(): print("testb") @pytest.mark.skip(reson="整個類下的案例都不會執行") class Test_skip(): def test_a(self): print("testa") def test_b(self): print("testb") # 能夠根據條件判斷,爲真,則不執行 @pytest.mark.skipif(1 > 2,reson="整個類下的案例知足條件都不會執行") class Test_skipif(): def test_a(self): print("testa") def test_b(self): print("testb")
# pytest的數據參數化 # 一、傳入單個參數 # # pytest.mark.parametrize(argnames,argvalues) # argnames 參數的名稱 # # argvalues 參數對應的值,類型必須是可迭代的類型,通常使用list @pytest.mark.skip(reson="只是這個函數用例不執行") def test_a(): print("testa") @pytest.mark.parametrize("name",["cui1","cui2","cui3","cui4"]) def test_b(name): print("testb----->{name}".format(name = name)) if __name__ == '__main__': pytest.main(["-s", "pytest8.py"])
實現的效果name做爲參數的名稱,這個案例會執行4次,參數分別是name=「cui1」\name="cui2"\....
import pytest # pytest的數據參數化 # 一、傳入多個參數 # # pytest.mark.parametrize((argnames1,argnames2),[(argvalues1,argvalues1),(argvalues1,argvalues1)],(argvalues1,argvalues1)]]) @pytest.mark.skip(reson="只是這個函數用例不執行") def test_a(): print("testa") @pytest.mark.parametrize(("name","age"),[("cui1",12),("cui2",13),("cui3",14)]) def test_b(name,age): print("testb----->{name}----->{age}".format(name = name,age = age)) if __name__ == '__main__': pytest.main(["-s", "pytest9.py"])
實現的效果以下
# pip install pytest-html # 用來美化輸出報告的插件 # 只須要在配置文件中加這個配置便可 # # addopts=-s --html=report.html
效果
# pip install pytest-rerunfailures # 失敗重試的第三方插件 # 只須要在配置文件中加這個配置即 # --reruns 3 --reruns-delay 2
至此,pytest的框架基本使用已經講解清楚,小夥伴們還有不清楚的嗎?歡迎你們來溝通!!!