目錄
一、前言
二、pytest安裝
2.1、安裝
2.2、驗證安裝
2.3、pytest文檔
三、pytest框架的約束
3.1、 python的命名規則
3.2、 pytest的命名規則
四、pytest的運行方式
4.1、主函數運行
4.2、命令行運行
五、pytest配置文件pytest.ini文件
六、前置和后置
七、assert斷言
八、pytest中conftest.py文件
8.1、conftest.py的特點
九、pytest中fixtrue裝飾器
9.1、基本使用
9.2、yield(后置)
9.3、帶參數fixtrue
9.3.1、scope
9.3.2、autouse
9.3.3、params
9.3.4、ids
9.3.5、name
十、logging日志模塊
10.1、介紹
10.2、使用
十一、測試報告allur
11.1、介紹
11.2、安裝
10.3、使用
一、前言
pytest是一個非常成熟的全功能的Python測試框架,主要有以下幾個特點:
1、簡單靈活,非常方便的組織自動化測試用例;
?2、支持參數化,可以細粒度地控制要測試的測試用例;
?3、能夠支持簡單的單元測試和復雜的功能測試,比如web端selenium/移動端appnium等自動化測試、request接口自動化測試
?4、pytest具有很多第三方插件,并且可以自定義擴展,比如測試報告生成,失敗重運行機制
?5、測試用例的skip和fail處理;
?6、結合業界最美的測試報告allure+Jenkins,持續集成
二、pytest安裝
2.1、安裝
pip install -U pytest
2.2、驗證安裝
pytest --version # 會展示當前已安裝版本
2.3、pytest文檔
官方文檔:https://docs.pytest.org/en/latest/contents.html
三、pytest框架的約束
3.1、 python的命名規則
1)py文件全部小寫,多個英文用_隔開
2)class名首字母大寫,駝峰
3)函數和方法名小寫,多個英文用_隔開
4)全局變量,前面要加global
5)常量字母必須全大寫,如:AGE_OF_NICK
3.2、 pytest的命名規則
1)模塊名(py文件)必須是以test_開頭或者_test結尾
2)測試類(class)必須以Test開頭,并且不能帶init方法,類里的方法必須以test_開頭
3)測試用例(函數)必須以test_開頭
四、pytest的運行方式
4.1、主函數運行
import pytestdef test_01():print("啥也沒有")if __name__=='__main__':pytest.main()
main中可使用的參數有:
參數 | 描述 | 案例 |
---|---|---|
-v | 輸出調試信息。如:打印信息 | pytest.main([‘-v’,‘testcase/test_one.py’,‘testcase/test_two.py’]) |
-s | 輸出更詳細的信息,如:文件名、用例名 | pytest.main([‘-vs’,‘testcase/test_one.py’,‘testcase/test_two.py’]) |
-x | 只要有一個用例執行失敗,就停止執行測試 | pytest.main([‘-vsx’,‘testcase/test_one.py’]) |
– maxfail | 出現N個測試用例失敗,就停止測試 | pytest.main([‘-vs’,‘-x=2’,‘testcase/test_one.py’] |
–html=report.html | 生成測試報告 | pytest.main([‘-vs’,‘–html=./report.html’,‘testcase/test_one.py’]) |
-n | 多線程或分布式運行測試用例 | |
-m | 通過標記表達式執行 | |
-k | 根據測試用例的部分字符串指定測試用例,可以使用and,or |
4.2、命令行運行
文件路徑:testcase/test_one.py
def test_a():print("啥也不是1111111111111")assert 1==1#終端輸入:pytest -vs
參數 | 描述 | 案例 |
---|---|---|
-v | 輸出調試信息。如:打印信息 | pytest -v ./testcase/test_one.py |
-q | 輸出簡單信息。 | pyets -q ./aaa/test_a.py |
-s | 輸出更詳細的信息,如:文件名、用例名 | pytest -s ./aaa/test_a.py |
-n | 多線程或分布式運行測試用例 | |
-x | 只要有一個用例執行失敗,就停止執行測試 | pytest -x ./testcase/test_one.py |
– maxfail | 出現N個測試用例失敗,就停止測試 | pytest --maxfail=2 ./testcase/test_one.py |
–html=report.html | 生成測試報告 | pytest ./testcase/test_one.py --html=./report/report.html |
–html=report.html | 生成測試報告 | pytest ./testcase/test_one.py --html=./report/report.html |
-k | 根據測試用例的部分字符串指定測試用例,可以使用and,or | pytest -k “MyClass and not method”,這條命令會匹配文件名、類名、方法名匹配表達式的用例,這里這條命令會運行 TestMyClass.test_something, 不會執行 TestMyClass.test_method_simple |
五、pytest配置文件pytest.ini文件
pytest的配置文件通常放在測試目錄下,名稱為pytest.ini,命令行運行時會使用該配置文件中的配置.
在項目的根目錄下創建pytest.ini文件,pytset.ini文件盡可能不要出現中文。
參數 | 作用 |
---|---|
[pytest] | 用于標志這個文件是pytest的配置文件 |
addopts | 命令行參數,多個參數之間用空格分隔 |
testpaths | 配置搜索參數用例的范圍 |
python_files | 改變默認的文件搜索規則 |
python_classes | 改變默認的類搜索規則 |
python_functions | 改變默認的測試用例的搜索規則 |
markers | 用例標記,自定義mark,需要先注冊標記,運行時才不會出現warnings |
六、前置和后置
遺 留問題:使?pytest框架,測試類中不可以添加init()?法,如何進?數據的初始化?
在測試框架中,前后置是指在執用測試用例前和測試用例后執行?些額外的操作,這些操作可以用于 設置測試環境、準備測試數據等,以確保測試的可靠性
pytest 框架提供三種?法做前后置的操作:
setup_method 和 teardown_method :這兩個?法?于類中的每個測試?法的前置和后置操 作。
setup_class 和 teardown_class :這兩個?法?于整個測試類的前置和后置操作。
fixture :這是 pytest 推薦的?式來實現測試?例的前置和后置操作。 靈活的控制和更強?的功能。(后面會對他進行單獨介紹)
setup_method 和 teardown_method
在每個測試用例之前都會,先執行前置函數,每個測試用例之后,執行后置函數
setup_class 和 teardown_class
只會在每個類之前或之后,才會執行前后置函數
七、assert斷言
斷?( assert )是?種調試輔助?具,?于檢查程序的狀態是否符合預期。如果斷?失敗(即條件 為假),Python解釋器將拋出?個 AssertionError 異常。斷?通常?于檢測程序中的邏輯錯誤。 pytest 允許你在Python測試中使?標準的Python assert 語句來驗證預期和值。
基本語法:
assert 條件, 錯誤信息
-
條件:必須是?個布爾表達式。
-
錯誤信息:當條件為假時顯?的錯誤信息,可選。
基本數據類型的斷?
數據結構斷?
接?返回值斷言
由于之前的網址關了,所以拿不到返回值
八、pytest中conftest.py文件
8.1、conftest.py的特點
pytest 會默認讀取 conftest.py里面的所有 fixture
conftest.py 文件名稱是固定的,不能改動
conftest.py 只對同一個 package 下的所有測試用例生效
不同目錄可以有自己的 conftest.py,一個項目中可以有多個 conftest.py
測試用例文件中不需要手動 import conftest.py,pytest 會自動查找
如果有兩個文件,其中一個文件中沒有@pytest.fixture,但是我們的執行用例中卻有前置參數,則pytest在執行時,無法在當前文件中找到@pytest.fixture時,則會報錯
如果我們將前置函數放入conftest.py中,則其他.py文件都可以執行前置函數
九、pytest中fixtrue裝飾器
雖然setup和teardown可以執行一些前置和后置操作,但是這種是針對整個腳本全局生效的
如果有以下場景:1.用例一需要執行登錄操作;2.用例二不需要執行登錄操作;3.用例三需要執行登錄操作,則setup和teardown則不滿足要求。fixture可以讓我自定義測試用例的前置條件
9.1、基本使用
-
場景一:做為參數傳入
# fixture函數(類中) 作為多個參數傳入
@pytest.fixture()
def login():print("打開瀏覽器")@pytest.fixture()
def logout():print("關閉瀏覽器")class TestLogin:# 傳入lonin fixturedef test_001(self, login):print("001傳入了loging fixture")# 傳入logout fixturedef test_002(self, logout):print("002傳入了logout fixture")def test_003(self, login, logout):print("003傳入了兩個fixture")def test_004(self):print("004未傳入仍何fixture哦")
從運行結果可以看出,fixture做為參數傳入時,會在執行函數之前執行該fixture函數。再將值傳入測試函數做為參數使用,這個場景多用于登錄
-
場景二:Fixture的相互調用
# fixtrue作為參數,互相調用傳入
@pytest.fixture()
def account():a = "account"print("第一層fixture")return a
# Fixture的相互調用一定是要在測試類里調用這層fixture才會生次,普通函數單獨調用是不生效的
@pytest.fixture()
def login(account):print("第二層fixture")class TestLogin:#若沒有返回值,則默認形參為Nonedef test_1(self, login):print("直接使用第二層fixture,返回值為{}".format(login))#如果@pytest.fixture()的函數中有返回值,則1會將返回值作為參數傳給account(形參)def test_2(self, account):print("只調用account fixture,返回值為{}".format(account))
即使fixture之間支持相互調用,但普通函數直接使用fixture是不支持的,一定是在測試函數內調用才會逐級調用生效
有多層fixture調用時,最先執行的是最后一層fixture,而不是先執行傳入測試函數的fixture
上層fixture的值不會自動return,這里就類似函數相互調用一樣的邏輯
9.2、yield(后置)
當我們運?測試時,我們希望確保它們能夠?我清理,以便它們不會?擾其他測試(同時也避免留下?量測試數據來膨脹系統)。pytest中的 個 fixture 定義具體的清理步驟。
在 pytest 中,yield是 fixture 機制的核心語法之一,用于在測試前后實現資源的初始化與清理,替代了傳統測試框架中的?
setup/teardown
?結構,且更加靈活。
-
yield之前的代碼:作為前置操作(如創建數據庫連接、啟動服務、生成測試數據等)。
-
yield之后的代碼:作為后置操作(如關閉連接、停止服務、清理臨時文件等),無論測試是否成功,都會執行。
-
yield?關鍵字本身可以返回一個值,供測試函數使用(類似?
return
)。
@pytest.fixture()
def pre():print("開始計算")yield 100print("計算完畢")def test_add(pre):a=100+preprint(a)
創建?件句柄與關閉?件
@pytest.fixture()
def file():print("打開文件句柄")fo=open("./testcase/test_b.txt","r",encoding="utf-8")yield foprint("關閉文件句柄")fo.close()def test_a(file):r=filestr=r.read(20)print(str)
9.3、帶參數fixtrue
格式:
pytest.fixture(scope='', params='', autouse='', ids='', name='')
參數詳解:
1. scope參數?于控制fixture的作?范圍,決定了fixture的?命周期。可選值有:
function (默認):每個測試函數都會調??次fixture。
class :在同?個測試類中共享這個fixture。
module :在同?個測試模塊中共享這個fixture。(?個?件?)
session :整個測試會話中共享這個fixture。
2. autouse 參數默認為False 。如果設置為True ,則每個測試函數都會?動調?該fixture,?需顯式傳?
3.?params 參數?于參數化fixture,?持列表傳?。每個參數值都會使fixture執??次,類似于for循環
4.?ids 參數與 params 配合使?,為每個參數化實例指定可讀的標識符(給參數取名字)
5.?name 參數?于為fixture顯式設置?個名稱。如果使?了 名稱來引? name ,則在測試函數中需要使?這個 fixture (給fixture取名字)
9.3.1、scope
function (默認):每個測試函數都會調??次fixture。
@pytest.fixture(scope="function")
def pre():print("前置步驟")class Test:def test_a(self,pre):print("aaaaaa")def test_b(self,pre):print("bbbbbb")
class :在同?個測試類中共享這個fixture。
當測試類內的每一個測試方法都調用了fixture,fixture只在該class下所有測試用例執行前執行一次
@pytest.fixture(scope="class")
def pre():print("前置步驟")yieldprint("后置步驟")class Test:def test_a(self,pre):print("aaaaaa")def test_b(self,pre):print("bbbbbb")def test_c(self,pre):print("cccccc")
module :在同?個測試模塊中共享這個fixture。(?個?件?)(與class相同,只從.py文件開始引用fixture的位置生效)
@pytest.fixture(scope="session")
def pre():print("前置步驟")yieldprint("后置步驟")class Test1:def test_a(self,pre):print("aaaaaa")def test_b(self,pre):print("bbbbbb")def test_c(self,pre):print("cccccc")class Test2:def test_a(self,pre):print("aaaaaa")def test_b(self,pre):print("bbbbbb")def test_c(self,pre):print("cccccc")
session :整個測試會話中共享這個fixture。
-
session的作用范圍是針對.py級別的,module是對當前.py生效,seesion是對多個.py文件生效
-
session只作用于一個.py文件時,作用相當于module
-
所以session多數與contest.py文件一起使用,做為全局Fixture
9.3.2、autouse
默認False
若為True,剛每個測試函數都會自動調用該fixture,無需傳入fixture函數名
由此我們可以總結出調用fixture的三種方式:
1.函數或類里面方法直接傳fixture的函數參數名稱
2.autouse=True自動調用,無需傳仍何參數,作用范圍跟著scope走(謹慎使用)
讓我們來看一下,當autouse=True的效果:
@pytest.fixture(autouse=True)
def pre():print("前置步驟")yieldprint("后置步驟")class Test1:def test_a(self):print("aaaaaa")def test_b(self):print("bbbbbb")def test_c(self):print("cccccc")class Test2:def test_a(self):print("aaaaaa")def test_b(self):print("bbbbbb")def test_c(self):print("cccccc")
9.3.3、params
Fixture的可選形參列表,支持列表傳入
默認None,每個param的值
fixture都會去調用執行一次,類似for循環
可與參數ids一起使用,作為每個參數的標識,詳見ids
被Fixture裝飾的函數要調用是采用:Request.param(固定寫法,如下圖)
@pytest.fixture(params=[1,2,3,4])
def pre(request):return request.paramdef test_a(pre):print(pre)
9.3.4、ids
用例標識ID與params配合使用,一對一關系
未配置ids之前,用例:
配置了ids后:
9.3.5、name
fixture的重命名
通常來說使用 fixture 的測試函數會將 fixture 的函數名作為參數傳遞,但是 pytest 也允許將fixture重命名
如果使用了name,那只能將name傳如,函數名不再生效
舉例:沒有name
有name
十、logging日志模塊
10.1、介紹
logging 是Python標準庫中的?個模塊,它提供了靈活的?志記錄功能。通過 logging ,開發者可以?便地將?志信息輸出到控制臺、?件、?絡等多種?標,同時?持不同級別的?志記錄,以 滿?不同場景下的需求。
10.2、使用
全局使用
import logginglogging.debug("This is a debug message")
logging.info("This is a info message")
logging.warning("This is a warning message")
logging.error("This is a error message")
logging.critical("This is a critical message")
自定義logger的名字并輸出到日志文件
import logging# 獲取一個日志記錄器對象,并且可以設置其名字
logger=logging.getLogger("log")# 設置日志器的輸出等級,只有大于這個等級的才會被輸出
logger.setLevel(logging.DEBUG)# 創建?個FileHandler對象,指定?志?件的名稱為"test.log"
# 這個處理器會將?志信息寫?到指定的?件中
handler=logging.FileHandler(filename="aaa.log")# 將這個處理器添加到?志記錄器中
# 這樣,?志記錄器就會使?這個處理器來處理?志信息
logger.addHandler(handler)def test():logger.debug("This is a debug message")logger.info("This is a info message")logger.warning("This is a warning message")logger.error("This is a error message")logger.critical("This is a critical message")
-
獲取?志記錄器: logging.getLogger(__name__) 獲取?個?志記錄器對象, name 是當前模塊的名稱。使?模塊名稱作為?志記錄器的名稱有助于在?型項?中區分不同模塊的?志.
-
設置?志級別: logger.setLevel(logging.DEBUG) 將?志記錄器的級別設置為 DEBUG ,這意味著所有 DEBUG 及以上級別的?志都會被記錄.?
-
創建?件處理器: logging.FileHandler(filename="aaa.log") 創建?個?件處理 器,將?志信息寫?到名為 test.log 的?件中.
-
添加處理器: logger.addHandler(handler) 將?件處理器添加到?志記錄器中,這樣?志 記錄器就會使?這個處理器來處理?志信息
設置日志格式
-
logging.Formatter 是用于定義日志輸出格式的類。在構造函數中,傳遞了?個格式字符串,用于指定日志信息的格式。格式字符串中使?了?些特殊的占位符(以 % 開頭),這些占位符會被替換 為相應的日志信息內容
-
handler.setFormatter(formatter) 將創建的格式器對象設置到處理器上。這意味著處理器 在處理?志信息時,會使用這個格式器來格式化?志信息.
格式占位符 | 說明 |
%(asctime)s | ?志記錄的時間戳,通常顯?為?期和時間。 |
%(levelname)s | ?志級別(如DEBUG、INFO、WARNING、ERROR、CRITICAL)。 |
%(name)s | ?志記錄器的名稱,通常為模塊名稱。 |
%(filename)s | ?志記錄發?的?件名。 |
%(funcName)s | ?志記錄發?的函數名。 |
%(lineno)d | ?志記錄發?的?號。 |
%(message)s | ?志消息本?。 |
十一、測試報告allur
11.1、介紹
Allure Report 由?個框架適配器和 allure 命令??具組成,是?個流?的開源?具,?于可視化 測試運?的結果。它可以以很少甚?零配置的?式添加到您的測試?作流中。它?成的報告可以在任何地?打開,并且任何?都可以閱讀,?需深厚的技術知識.
11.2、安裝
下載allure-pytest包
pip install allure-pytest==2.13.5
下載Windows版Allure報告
下載鏈接:https://github.com/allure-framework/allure2/releases/download/2.30.0/allure 2.30.0.zip
添加系統環境變量
????????????????將allure-2.29.0 對應bin?錄添加到系統環境變量中
確認結果
打 開cmd,查看allure版本
出現 a llure 版本則安裝成功。
10.3、使用
step1:運行自動化,并指定測試報告放置路徑
代碼塊pytest --alluredir=results_dir
(保存測試報告的路徑)?例:
pytest --alluredir=allure-results
生成測試報告可以在控制臺通過命令將結果保存在 pytest.ini?件中配置測試報告放置路徑 allre-results ?件夾中,也可以在 addopts = -vs --alluredir allure-results
step2:查看測試報告
?法?:啟動?個本地服務器來在瀏覽器中展?測試報告
終端執?命令: allure serve [options] <allure-results>,?動在瀏覽器打開測試 報告(options:其他的配置項,<allure-results>:存放測試報告的路徑)
-
--host :指定服務器監聽的主機地址,默認為localhost。
-
-- port :指定服務器監聽的端?號,默認為0(?動選擇空閑端?)
-
--clean-alluredir :清除上?次?成的測試報告
不指定端?號和主機地址
allure serve .\allure-results\指定端?號
allure serve --port 8787 .\allure-results\ 清除上?次?成的測試報告
allure serve .\allure-results\ --clean-alluredir
方法?:從測試結果生成測試報告
終端執?命令: allure generate [options] <allure-results>?-o <reports>
-
<reports>:存放測試結果的位置
-
<allure-results>:存放測試報告的路徑
allure generate .\results_dir\ -o .\allure_dir