gpt4 book ai didi

python - Py.test - 从 csv 将变量应用于装饰器?

转载 作者:太空宇宙 更新时间:2023-11-03 14:43:32 24 4
gpt4 key购买 nike

请耐心等待我解释我的困境,我仍然是 Python 新手,所以我的术语可能不正确。另外,对于这篇文章不可避免的冗长,我深表歉意,但我会尝试尽可能多地解释相关细节。

快速总结:

我目前正在使用 py.test 为一组功能基本相同的网站开发一套 Selenium 测试

  • 使用 pytest 插件将测试结果上传到 TestRail pytest-testrail.

  • 测试用带有唯一案例 ID 的装饰器 @pytestrail.case(id) 标记

我的一个典型测试如下所示:

@pytestrail.case('C100123')  # associates the function with the relevant TR case
@pytest.mark.usefixtures()
def test_login():
# test code goes here

正如我之前提到的,我的目标是创建一组代码来处理我们的许多具有(几乎)相同功能的网站,因此上面示例中的硬编码装饰器将不起作用。

我在 TestRail 中尝试了一种使用 csv 和测试列表及其案例 ID 的数据驱动方法。

例子:

website1.csv:
Case ID | Test name
C100123 | test_login


website2.csv:
Case ID | Test name
C222123 | test_login

我编写的代码将使用检查模块来查找正在运行的测试的名称,找到相关的测试 ID 并将其放入名为 test_id 的变量中:

import csv
import inspect
class trp(object):
def __init__(self):
pass


with open(testcsv) as f: # testcsv could be website1.csv or website2.csv
reader = csv.reader(f)
next(reader) # skip header
tests = [r for r in reader]


def gettestcase(self):
self.current_test = inspect.stack()[3][3]
for row in trp.tests:
if self.current_test == row[2]:
self.test_id = (row[0])
print(self.test_id)
return self.test_id, self.current_test


def gettestid(self):
self.gettestcase()

当时的想法是装饰器会根据我当时使用的 csv 动态变化。

@pytestrail.case(test_id)  # now a variable
@pytest.mark.usefixtures()
def test_login():
trp.gettestid()
# test code goes here

因此,如果我为 website1 运行 test_login,装饰器将如下所示:

@pytestrail.case('C100123')

如果我为 website2 运行 test_login 装饰器将是:

@pytestrail.case('C222123')

我为自己想出这个解决方案而感到无比自豪,并进行了尝试……它没有用。虽然代码本身确实有效,但我会得到一个异常,因为 test_id 未定义(我理解为什么 - gettestcase 在装饰器之后执行,所以它当然会崩溃。

我可以处理此问题的唯一其他方法是在执行任何测试代码之前应用 csv 和 testID。我的问题是——我怎么知道如何将测试与其测试 ID 相关联?什么是优雅的、最小的解决方案?

抱歉这个冗长的问题。如果您需要更多解释,我会密切关注并回答任何问题。

最佳答案

pytest 非常擅长为测试做各种元编程。如果我正确理解你的问题,下面的代码将使用 pytestrail.case 标记进行动态测试标记。在项目根目录中,创建一个名为 conftest.py 的文件并将此代码放入其中:

import csv
from pytest_testrail.plugin import pytestrail


with open('website1.csv') as f:
reader = csv.reader(f)
next(reader)
tests = [r for r in reader]


def pytest_collection_modifyitems(items):
for item in items:
for testid, testname in tests:
if item.name == testname:
item.add_marker(pytestrail.case(testid))

现在您根本不需要使用 @pytestrail.case() 标记测试 - 只需编写其余代码,pytest 将处理标记:

def test_login():
assert True

pytest 启动时,上面的代码将读取 website1.csv 并存储测试 ID 和名称,就像您在代码中所做的那样。在测试运行开始之前,pytest_collection_modifyitems Hook 将执行,分析收集的测试 - 如果测试与 csv 文件中的名称相同,pytest 将添加 pytestrail .case 带有测试 ID 的标记。

关于python - Py.test - 从 csv 将变量应用于装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51365267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com