微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

在尝试解释我的困境时,请多多包涵,我仍然是Python新手,因此我的术语可能不正确.我也为这篇文章不可避免地冗长而感到抱歉,但是我将尽力说明尽可能多的相关细节.

快速总结:

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

>使用pytest插件pytest-testrail.将测试结果上传到TestRail
>测试用装饰器@ pytestrail.case(id)标记,并具有唯一的案例ID

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

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

如前所述,我的目标是创建一组代码来处理我们的许多具有(几乎)相同功能的网站,因此上面示例中的硬编码装饰器将无法工作.

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

例:

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


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

我编写的代码将使用inspect模块查找正在运行的测试的名称,找到相关的测试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')

如果我为网站2运行了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钩子,分析收集的测试-如果测试的名称与csv文件中的名称相同,则pytest将向其添加带有测试ID的pytestrail.case标记.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐