pytest用例間參數(shù)傳遞的兩種實(shí)現(xiàn)方式示例
前言
我們?cè)谧鼋涌谧詣?dòng)化測(cè)試的時(shí)候,會(huì)經(jīng)常遇到這種場(chǎng)景:接口A的返回結(jié)果中的某個(gè)字段,是接口B的某個(gè)字段的入?yún)?。如果是使用postman,那我們可以通過(guò)設(shè)置后置變量,然后在需要使用的地方通過(guò){{}}的方式來(lái)進(jìn)行調(diào)用。但是如果是使用自己寫(xiě)的測(cè)試框架中要如何實(shí)現(xiàn)呢?我想到的是如下三種方法。
首先說(shuō)明一下,以下三種方式均是通過(guò)python + pytest來(lái)實(shí)現(xiàn)的
一、通過(guò)conftest創(chuàng)建全局變量
conftest.py文件是pytest框架中很有用的一個(gè)東西,首先看下官方文檔中的解釋?zhuān)?/p>

大概意思就是說(shuō),conftest.py文件供整個(gè)用例目錄(conftest.py文件可以有多個(gè),并且只在當(dāng)前package下生效)使用而無(wú)需導(dǎo)入,也就是說(shuō)在用例目錄是conftest中的信息是公用的,例如:
a/conftest.py:
def pytest_runtest_setup(item):
# called for running each test in 'a' directory
print("setting up", item)
a/test_sub.py:
def test_sub():
pass
test_flat.py:
def test_flat():
pass
運(yùn)行后的結(jié)果:
pytest test_flat.py --capture=no? # will not show "setting up"
pytest a/test_sub.py --capture=no? # will show "setting up"
而我們就可以通過(guò)conftest + fixture函數(shù)來(lái)實(shí)現(xiàn)我們想要的效果了,具體代碼如下:
# conftest.py
# 定義一個(gè)全局變量,用于存儲(chǔ)內(nèi)容
global_data = {}
@pytest.fixture
def set_global_data():
"""
設(shè)置全局變量,用于關(guān)聯(lián)參數(shù)
:return:
"""
def _set_global_data(key, value):
global_data[key] = value
return _set_global_data
@pytest.fixture
def get_global_data():
"""
從全局變量global_data中取值
:return:
"""
def _get_global_data(key):
return global_data.get(key)
return _get_global_data
簡(jiǎn)單說(shuō)一下實(shí)現(xiàn)邏輯:
- 首先定義一個(gè)變量global_data用于接收存儲(chǔ)用例返回的結(jié)果
- set_global_data和get_global_data兩個(gè)fixture方法顧名思義,set方法是往global_data中存數(shù)據(jù),get方法是從global_data中取數(shù)據(jù)
方法實(shí)現(xiàn)了,具體應(yīng)該怎么使用呢?如下:
# test_get_set.py
import requests
import pytest
def test_set(set_global_data):
res = requests.get("http://www.baidu.com")
status_code = res.status_code
logger.info(f"請(qǐng)求返回狀態(tài)碼:{status_code}")
set_global_data("status_code", status_code)
def test_get(get_global_data):
data = get_global_data("status_code")
logger.info(f'通過(guò)get_global_data方法獲取的值:{data}')
if __name__ == '__main__':
pytest.main(['-sv', 'test_get_set.py'])
返回結(jié)果:
test_get_set.py::test_set PASSED
2021-12-24 17:58:37.642 | INFO? ? ?| cases.test_get_set:test_set:19 - 請(qǐng)求返回狀態(tài)碼:200
2021-12-24 17:58:37.643 | INFO? ? ?| cases.test_get_set:test_get:25 - 通過(guò)get_global_data方法獲取的值:200
test_get_set.py::test_get PASSED
============================== 2 passed in 0.06s ===============================
通過(guò)這種方式,便實(shí)現(xiàn)了用例間的參數(shù)傳遞問(wèn)題。
在實(shí)際工作中,因?yàn)樯婕暗降慕涌?、用例?huì)很多,所以可以根據(jù)需要使用不同的conftest進(jìn)行管理。并且存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)也需要進(jìn)行規(guī)范區(qū)分,如使用方法名作為字典的key。
二、使用tmpdir_factory方法
第二種方法,是使用pytest的tmpdir和tmpdir_factory兩個(gè)夾具函數(shù),同樣是通過(guò)conftest文件來(lái)實(shí)現(xiàn)。仍然是先來(lái)看下官方文檔針對(duì)這兩個(gè)方法的說(shuō)明:

簡(jiǎn)單來(lái)說(shuō),這兩個(gè)方法的作用就是為每個(gè)測(cè)試方法創(chuàng)建一個(gè)臨時(shí)目錄用于存儲(chǔ)自定義的文件,這個(gè)臨時(shí)目錄會(huì)默認(rèn)保存3個(gè)sessions,之后就會(huì)按照創(chuàng)建的順序刪除舊的目錄。看下官方的例子:
# content of test_tmpdir.py
def test_create_file(tmpdir):
p = tmpdir.mkdir("sub").join("hello.txt")
p.write("content")
assert p.read() == "content"
assert len(tmpdir.listdir()) == 1
assert 0
# contents of conftest.py
import pytest
@pytest.fixture(scope="session")
def image_file(tmpdir_factory):
img = compute_expensive_image()
fn = tmpdir_factory.mktemp("data").join("img.png")
img.save(str(fn))
return fn
# contents of test_image.py
def test_histogram(image_file):
img = load_image(image_file)
# compute and test histogram
我在實(shí)際項(xiàng)目中的使用:
仍是在conftest.py文件中自定義一個(gè)夾具函數(shù),返回結(jié)果是一個(gè)元組,p是tmpdir_factory方法返回的對(duì)象,轉(zhuǎn)為字符串之后就是文件存儲(chǔ)的路徑。
自定義一個(gè)名為“apitest-tmp-dir”的文件夾用于存儲(chǔ)文件
# conftest.py
@pytest.fixture
def tmp_factory(tmpdir_factory):
"""
生成臨時(shí)目錄
"""
p = tmpdir_factory.mktemp('apitest-tmp-dir')
logger.info("當(dāng)前臨時(shí)文件的目錄為:" + str(p))
return p, str(p)
在測(cè)試方法中的使用
# test_get_set.py
import requests
import pytest
import json
def test_set(tmp_factory):
res = requests.get("http://www.baidu.com")
status_code = res.status_code
logger.info(f"返回狀態(tài)碼:{status_code}")
logger.debug(tmp_factory)
# 創(chuàng)建test_set.txt文件
a = tmp_factory[0].join("test_set.txt")
# 將需要的內(nèi)容寫(xiě)入到文件中
a.write({"status_code": status_code})
# 使用read()方法獲取文件中的內(nèi)容
logger.debug(a.read())
if __name__ == '__main__':
pytest.main(['-sv', 'test_get_set.py'])
返回結(jié)果:?
test_get_set.py::test_set 2021-12-24 18:24:39.292 | INFO? ? ?| cases.conftest:tmp_factory:150 - 當(dāng)前臨時(shí)文件的目錄為:/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0
2021-12-24 18:24:39.347 | INFO? ? ?| cases.test_get_set:test_set:32 - 返回狀態(tài)碼:200
2021-12-24 18:24:39.347 | DEBUG? ? | cases.test_get_set:test_set:34 - (local('/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0'), '/private/var/folders/_f/1d0lt83x1599bf6mcfppbwp40000gn/T/pytest-of-j/pytest-19/apitest-tmp-dir0')
2021-12-24 18:24:39.348 | DEBUG? ? | cases.test_get_set:test_set:38 - {'status_code': 200}
PASSED
============================== 1 passed in 0.07s ===============================
創(chuàng)建的文件:

可以看到,tmpdir_factory會(huì)自動(dòng)為我們創(chuàng)建一個(gè)目錄,名字是`tmp_factory`方法中自定義的名稱后面加0,同時(shí)它的上級(jí)目錄會(huì)自動(dòng)從pytest-0遞增
說(shuō)下這個(gè)辦法的優(yōu)缺點(diǎn):
- 先說(shuō)優(yōu)點(diǎn),這種數(shù)據(jù)存儲(chǔ)是直接寫(xiě)入到文件,因此即使運(yùn)行結(jié)束后也可以訪問(wèn),而不像第一種方法存儲(chǔ)的內(nèi)容會(huì)隨著用例運(yùn)行的結(jié)束而消失
- 再說(shuō)缺點(diǎn),因?yàn)檫@個(gè)臨時(shí)目錄最多只能保存3個(gè),因此如果用例很多時(shí),那么就可能存在文件被自動(dòng)刪除的風(fēng)險(xiǎn)。不過(guò)這個(gè)貌似可以通過(guò)修改默認(rèn)配置來(lái)解決,可以繼續(xù)研究下。
- 缺點(diǎn)二,上面的例子中,直接通過(guò)a.read()就訪問(wèn)到了文件中的內(nèi)容,這是因?yàn)閮?nèi)容的存儲(chǔ)與讀取全是在一個(gè)方法內(nèi),因此可以直接調(diào)用。如果是A方法存結(jié)果,在B中需要讀取,那么便不能直接使用read()方法了(因?yàn)槊總€(gè)方法都會(huì)創(chuàng)建一個(gè)目錄,并且默認(rèn)的讀取地址都是這個(gè)方法自己創(chuàng)建的目錄)。就需要我們自己去單獨(dú)封裝一個(gè)讀取文件的方法了,實(shí)現(xiàn)起來(lái)也不難而且tmpdir本身的這些方法也是對(duì)os.path一些方法的二次封裝。
話說(shuō)回來(lái),都需要我自己去封裝一個(gè)讀取文件的方法了,為啥不干脆把讀、寫(xiě)都自己來(lái)做呢?這樣是否刪除文件、刪除幾個(gè)、什么時(shí)候刪除就完全由自己定義了啊,貌似會(huì)更方便。。。。。三、總結(jié)
綜上所述,大家應(yīng)該對(duì)這兩種方法都有了一些了解,核心都是通過(guò)pytest的conftes.py文件來(lái)實(shí)現(xiàn)的。
總結(jié)
到此這篇關(guān)于pytest用例間參數(shù)傳遞的兩種實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)pytest例間參數(shù)傳遞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 怎樣將dataframe中的字符串日期轉(zhuǎn)化為日期的方法
這篇文章主要介紹了python 怎樣將dataframe中的字符串日期轉(zhuǎn)化為日期的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Ubuntu?Server?20.04?LTS?環(huán)境下搭建vim?編輯器Python?IDE的詳細(xì)步驟
這篇文章主要介紹了Ubuntu?Server?20.04?LTS?環(huán)境下搭建vim?編輯器Python?IDE,首先是安裝配置vim-plug及安裝coc.nvim插件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
python 類(lèi)中函數(shù)名前后加下劃線的具體使用
在Python編程語(yǔ)言中,函數(shù)名前后有下劃線是一種常見(jiàn)的命名約定,,被廣泛應(yīng)用于類(lèi)中的函數(shù),本文將介紹下劃線命名風(fēng)格的由來(lái)、使用場(chǎng)景以及如何正確應(yīng)用它,感興趣的可以了解一下2024-01-01
利用Python中的pandas庫(kù)對(duì)cdn日志進(jìn)行分析詳解
這篇文章主要介紹了利用Python中的pandas庫(kù)進(jìn)行cdn日志分析的相關(guān)資料,文中分享了pandas對(duì)cdn日志分析的完整示例代碼,然后詳細(xì)介紹了關(guān)于pandas庫(kù)的相關(guān)內(nèi)容,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-03-03
基于telepath庫(kù)實(shí)現(xiàn)Python和JavaScript之間交換數(shù)據(jù)
telepath是一個(gè)Django庫(kù),用于在Python和JavaScript之間交換數(shù)據(jù),使您可以構(gòu)建具有豐富客戶端接口的應(yīng)用程序,同時(shí)將業(yè)務(wù)邏輯保留在服務(wù)器端代碼中。2021-05-05
Python3實(shí)現(xiàn)的爬蟲(chóng)爬取數(shù)據(jù)并存入mysql數(shù)據(jù)庫(kù)操作示例
這篇文章主要介紹了Python3實(shí)現(xiàn)的爬蟲(chóng)爬取數(shù)據(jù)并存入mysql數(shù)據(jù)庫(kù)操作,涉及Python正則爬取數(shù)據(jù)及針對(duì)mysql數(shù)據(jù)庫(kù)的存儲(chǔ)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-06-06
Python可變對(duì)象與不可變對(duì)象原理解析
這篇文章主要介紹了Python可變對(duì)象與不可變對(duì)象原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警
這篇文章主要介紹了基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
python PyAutoGUI 模擬鼠標(biāo)鍵盤(pán)操作和截屏功能
一款跨平臺(tái)/無(wú)依賴的自動(dòng)化測(cè)試工具,目測(cè)只能控制鼠標(biāo)/鍵盤(pán)/獲取屏幕尺寸/彈出消息框/截屏。這篇文章主要介紹了python PyAutoGUI 模擬鼠標(biāo)鍵盤(pán)操作和截屏功能,需要的朋友可以參考下2019-08-08
Python+Pygame實(shí)現(xiàn)簡(jiǎn)單的單詞小游戲
語(yǔ)言是一種藝術(shù),但是作為語(yǔ)言的基礎(chǔ)——詞匯,卻不像藝術(shù)那樣賞心悅目。不斷的記憶與復(fù)習(xí),讓詞匯成為很多孩子在學(xué)習(xí)英語(yǔ)時(shí),最難完全攻克的關(guān)卡。本文就來(lái)用Python制作一個(gè)簡(jiǎn)單的英語(yǔ)單詞游戲吧2023-03-03

