基于参数化fixture的Pytest参数化

2024-02-07

我有一个类范围的参数化装置,它获取 3 个数据库的参数并返回每个数据库的连接。

类中的测试使用此装置来测试每个数据库连接属性。

现在我有一个带有数据库表测试的新类,我想使用上面的固定装置,但要在每个连接表上进行参数化。

关于 pytest 实现这一点的方法有什么建议吗?我找不到基于已参数化元素进行参数化的方法。

Thanks


测试类用于:

  • 为测试用例提供设置和拆卸功能
  • 在测试期间分享一些共同的价值观

With pytest这不是必需的,因为设置和拆卸可以在夹具级别完成。

因此,我的解决方案不使用类(但它可能可以与它们一起使用)。

为了表明,(假)连接已创建,然后关闭,观察标准输出上的输出。诀窍是 使用@pytest.yield_fixture,没有使用return but yield提供使用的值 注入测试用例的参数。无论先在后的是什么yield语句被执行 作为拆解代码。

“矩形”样式:通过两个参数化夹具进行 M x N 测试运行

第一种情况很自然py.test,其中组合了所有夹具变体。

由于它运行了 M x N 测试用例,因此我将其称为“矩形”。

我的测试是在tests/test_it.py:

import pytest


@pytest.yield_fixture(scope="class", params=["mysql", "pgsql", "firebird"])
def db_connect(request):
    print("\nopening db")
    yield request.param
    print("closing db")


@pytest.fixture(scope="class", params=["user", "groups"])
def table_name(request):
    return request.param


def test_it(db_connect, table_name):
    print("Testing: {} + {}".format(db_connect, table_name))

如果您需要更多测试用例,例如test_it,只需用另一个名称创建它们即可。

运行我的测试用例::

$ py.test -sv tests
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9 -- py-1.4.30 -- pytest-2.7.2 -- /home/javl/.virtualenvs/stack/bin/python2
rootdir: /home/javl/sandbox/stack/tests, inifile: 
collected 6 items 

tests/test_it.py::test_it[mysql-user] 
opening db
Testing: mysql + user
PASSEDclosing db

tests/test_it.py::test_it[pgsql-user] 
opening db
Testing: pgsql + user
PASSEDclosing db

tests/test_it.py::test_it[pgsql-groups] 
opening db
Testing: pgsql + groups
PASSEDclosing db

tests/test_it.py::test_it[mysql-groups] 
opening db
Testing: mysql + groups
PASSEDclosing db

tests/test_it.py::test_it[firebird-groups] 
opening db
Testing: firebird + groups
PASSEDclosing db

tests/test_it.py::test_it[firebird-user] 
opening db
Testing: firebird + user
PASSEDclosing db


====================================== 6 passed in 0.01 seconds =======================================

从一个灯具到 N 个从属灯具的“爆炸三角形”

想法如下:

  • 生成几个db_connect夹具,使用参数化夹具
  • 对于每个 db_connect 生成 N 个变体table_name固定装置
  • have test_it(db_connect, table_name)仅通过适当的组合来调用db_connect and table_name.

这根本行不通

唯一的解决方案是使用某种场景,明确定义哪些组合是 正确的。

“场景”:测试功能级别的间接参数化

我们必须参数化测试功能,而不是参数化夹具。

通常,参数值按原样直接传递给测试函数。如果我们想要一个固定装置(名为 作为参数名称)为了创建要使用的值,我们必须指定参数 作为indirect。如果我们说indirect=True,如果我们提供,所有参数都将以这种方式处理 参数名称列表,只有指定的参数将被传递到固定装置中,其余的将被传递 因为他们正在进入测试功能。这里我使用显式的间接参数列表。

import pytest

DBCFG = {"pgsql": "postgresql://scott:tiger@localhost:5432/mydatabaser",
         "mysql": "mysql://scott:tiger@localhost/foo",
         "oracle": "oracle://scott:[email protected] /cdn-cgi/l/email-protection:1521/sidname"
}


@pytest.yield_fixture(scope="session")
def db_connect(request):
    connect_name = request.param
    print("\nopening db {connect_name}".format(connect_name=connect_name))
    assert connect_name in DBCFG
    yield DBCFG[connect_name]
    print("\nclosing db {connect_name}".format(connect_name=connect_name))


@pytest.fixture(scope="session")
def table_name(request):
    return "tabname-by-fixture {request.param}".format(request=request)


scenarios = [
    ("mysql", "myslq-user"),
    ("mysql", "myslq-groups"),
    ("pgsql", "pgsql-user"),
    ("pgsql", "pgsql-groups"),
    ("oracle", "oracle-user"),
    ("oracle", "oracle-groups"),
]
@pytest.mark.parametrize("db_connect,table_name",
                         scenarios,
                         indirect=["db_connect", "table_name"])
def test_it(db_connect, table_name):
    print("Testing: {} + {}".format(db_connect, table_name))

运行测试套件:

$ py.test -sv tests/test_indirect.py
py.test========================================= test session starts ==================================
=======
platform linux2 -- Python 2.7.9, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- /home/javl/.virtualenvs/stack
/bin/python2
cachedir: tests/.cache
rootdir: /home/javl/sandbox/stack/tests, inifile:
collected 6 items

tests/test_indirect.py::test_it[mysql-myslq-user]
opening db mysql
Testing: mysql://scott:tiger@localhost/foo + tabname-by-fixture myslq-user
PASSED
closing db mysql

tests/test_indirect.py::test_it[mysql-myslq-groups]
opening db mysql
Testing: mysql://scott:tiger@localhost/foo + tabname-by-fixture myslq-groups
PASSED
closing db mysql

tests/test_indirect.py::test_it[pgsql-pgsql-user]
opening db pgsql
Testing: postgresql://scott:tiger@localhost:5432/mydatabaser + tabname-by-fixture pgsql-user
PASSED
closing db pgsql

tests/test_indirect.py::test_it[pgsql-pgsql-groups]
opening db pgsql
Testing: postgresql://scott:tiger@localhost:5432/mydatabaser + tabname-by-fixture pgsql-groups
PASSED
closing db pgsql

tests/test_indirect.py::test_it[oracle-oracle-user]
opening db oracle
Testing: oracle://scott:[email protected] /cdn-cgi/l/email-protection:1521/sidname + tabname-by-fixture oracle-user
PASSED
closing db oracle

tests/test_indirect.py::test_it[oracle-oracle-groups]
opening db oracle
Testing: oracle://scott:[email protected] /cdn-cgi/l/email-protection:1521/sidname + tabname-by-fixture oracle-groups
PASSED
closing db oracle


====================================== 6 passed in 0.01 seconds =======================================

我们看到它有效。

无论如何,有一个小问题——db_connect范围“会话”不被尊重,它是 在函数级别实例化和销毁。这是已知问题 https://github.com/pytest-dev/pytest/issues/570.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于参数化fixture的Pytest参数化 的相关文章

  • 为什么 Python 在导入脚本时只保存脚本的字节码?

    既然执行Python字节码会比运行原始源代码更快 因为Python不需要重新编译 为什么Python在导入脚本时只保存编译后的字节码呢 为每个执行的脚本保存 pyc 文件不是更好吗 无论如何 Python 解释器的启动时间都需要时间 即使您
  • scipy.optimize on pandas dataframe

    我试图搜索它 但结果很差 有人可以向我解释一下如何在 Pandas DataFrame 上执行 optimize minimize 以便最小化 DataFrame 中的类别和结果列之间的错误 考虑这个例子 import pandas as
  • Python 转换矩阵

    我有一个如下所示的列表 2 1 3 1 2 3 1 2 2 2 我想要的是一个转换矩阵 它向我显示如下序列 1 后跟 1 的频率是多少 1 后面跟着 2 的频率是多少 1 后跟 3 的频率是多少 2 后跟 1 的频率是多少 2 后跟 2 的
  • 通过 python 中的另外两个修改数组[重复]

    这个问题在这里已经有答案了 假设我们有三个一维数组 A 长度为 5 B 长度相同 示例中为5 C 更长 比如长度为 100 C最初用零填充 A给出索引C应更改的元素 它们可能会重复 以及B给出应添加到初始零的值C 例如 如果A 1 3 3
  • 来自 pandas 数据帧的烛台图,用日期替换索引

    此代码给出了带有移动平均线的烛台图 但 x 轴位于索引中 我需要 x 轴位于日期中 需要做什么改变 import numpy as np import pandas as pd import matplotlib pyplot as plt
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 雅虎财务请求功能出现 404 客户端错误

    yahoo Financials的请求功能出现404 Client Error 直接点击以下网址没有问题 https finance yahoo com quote AAPL financials p AAPL https finance
  • 类型错误:“datetime.datetime”和“str”的实例之间不支持“>”

    我是 python 日期和时间类型的新手 我有一个日期值 date 2018 11 10 10 55 31 00 00 我需要检查该日期值是否超过 90 天 我试过 from datetime import datetime from da
  • 使用 NumPy 编写一个函数来计算具有特定公差的积分

    我想编写一个自定义函数来以特定容差对表达式 python 或 lambda 函数 进行数字积分 我知道与scipy integrate quad人们可以简单地改变epsabs但我想使用 numpy 自己编写该函数 From 这篇博文 htt
  • 无法在 virtualenv 中安装 libxml2

    我有一个问题libxml2蟒蛇模块 我正在尝试将其安装在python3 虚拟环境使用以下命令 pip install libxml2 python3 但它显示以下错误 Collecting libxml2 python3 Using cac
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • ValueError:数据必须为正(boxcox scipy)

    我正在尝试将我的数据集转换为正态分布 0 8 298511e 03 1 3 055319e 01 2 6 938647e 02 3 2 904091e 02 4 7 422441e 02 5 6 074046e 02 6 9 265747e
  • 正在使用 PIL 保存损坏的图像

    我遇到一个问题 操作图像像素导致保存损坏的图像 因此 我使用 PIL 打开图像 然后将其转换为 NumPy 数组 image Image open myimage png np image np asarray image 然后 我转置图像
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 使用 subprocess.Popen() 或 subprocess.check_call() 时程序卡住

    我想从 python 运行一个程序并找到它的内存使用情况 为此 我正在使用 l a out lt in txt gt out txt p subprocess Popen l shell False stdout subprocess PI
  • 通过 Python 循环浏览网络上的目录并显示其内容(文件和其他目录)

    同样的道理在Python中处理从源目录到目标目录的一组文件 https stackoverflow com questions 2593399 process a set of files from a source directory t
  • 更改 Matplotlib 投影轴的背景颜色

    我正在尝试使用 Cartopy 创建一个图形 该图形需要在未投影的轴上绘制投影轴 这是一个尽可能简单的代码版本 它将轴上的内容替换为背景颜色 import matplotlib pyplot as plt import cartopy cr
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • 如何按 pandas 中的值对系列进行分组?

    我现在有一只熊猫Series与数据类型Timestamp 我想按日期对其进行分组 并且每组中有许多行具有不同的时间 看似显而易见的方法类似于 grouped s groupby lambda x x date 然而 熊猫的groupby按索
  • MoviePY 无法在 Windows 上检测 ImageMagick 二进制文件

    我刚买了一台新笔记本电脑 想要设置MoviePY在那新的Windows 64x Python3 7 0 机器 我对所有内容都进行了三次检查 但是当涉及到我的代码的文本部分时 它向我抛出了这个错误 OSError MoviePy Error

随机推荐