pytest 参数化的一个问题,求大佬指点

2019-01-31 08:53:38 +08:00
 90928yao

有个不太正经的问题,俩个测试函数有依赖( test_equals )( test_zerodivision ), 我想在执行 test_equals 后修改 test_zerodivision 的入参,但是 pytest_generate_tests 已经根据 param 把这个入参给生成好了。有什么办法在执行了 test_equal 后然后修改 param 重新执行 pytest_generate_tests,或者直接修改 pytest_generate_tests 生成的入参(但是我实在找不到这个东西在哪里修改,他这个黑魔法方法,太玄幻)。

(我有办法避免这个问题,就是拆开来,但是我还是想知道下,能不能直接修改这个值,或者执行的过程中 reload 这个 class 的 param,重新生成参数)

# doc 地址 https://docs.pytest.org/en/latest/example/parametrize.html#paramexamples
import pytest

def pytest_generate_tests(metafunc):
    # called once per each test function
    funcarglist = metafunc.cls.params[metafunc.function.__name__]
    argnames = sorted(funcarglist[0])
    metafunc.parametrize(argnames, [[funcargs[name] for name in argnames]
            for funcargs in funcarglist])

class TestClass(object):
    # a map specifying multiple argument sets for a test method
    params = {
        'test_equals': [dict(a=1, b=2), dict(a=3, b=3), ],
        'test_zerodivision': [dict(a=1, b=0), ],
    }
    #现在我想执行了这个函数把 'test_zerodivision': [dict(a=1, b=0), ]改成 'test_zerodivision': [dict(a=1, b=1), ]
    def test_equals(self, a, b):
        assert a == b

    def test_zerodivision(self, a, b):
        with pytest.raises(ZeroDivisionError):
            a / b
3184 次点击
所在节点    Python
8 条回复
Valkyrie0
2019-01-31 09:45:08 +08:00
只是写业务代码弄这些黑魔法目的是啥?是用例函数参数的话,可以用 @pytest.mark.parametrize 或者 @pytest.fixture(scope="", params=[""]) ,话说要重用代码最简单的不是写个公共方法吗?
Valkyrie0
2019-01-31 09:46:01 +08:00
逛 V2EX 第一次遇到测试相关的话题
90928yao
2019-01-31 09:49:02 +08:00
@Valkyrie0 是 pytest 这个框架的黑魔法啊,他执行每个测试函数的时候 都会先执行一大堆 hook 函数,然后把参数用**kwarg 的方法传给测试函数,我现在就是想知道 怎么拿到内存中的那一堆生成的参数 ,然后偷偷修改掉
Valkyrie0
2019-01-31 09:57:19 +08:00
代理拦截的黑魔法我就不懂了,pytest 支持插件,我看很多插件轮子里面都用上钩子了,可以看看它的插件机制支持不
zjb861107
2019-01-31 11:13:13 +08:00
按我的理解`pytest_generate_tests`是重新收集测试用例了,这个应该是不推荐或者不允许的。
换个角度看,正常开始测试之前我收集了 2 条 case,但是代码里再动态添加了 1 个,那最终的测试结果该是 2 个还是 3 个呢?
如果是两个 case 之间共享数据,应该自定义一个 fixture 就可以了。
willder
2019-01-31 11:20:36 +08:00
我试着更新了 metafunc 这个对象,比如在 test_equals 中更新一下,
TestClass.params.update(test_zerodivision=[dict(a=1, b=2), ]),但没有成功,看来在 pytest_generate_tests 中做不到根据前面 case 的结果动态设置后面 case 的参数
willder
2019-01-31 11:27:40 +08:00
自己设置一个全局变量应该可以做到
ityoung
2019-01-31 14:22:58 +08:00
测试用例之间不要相互依赖.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/532031

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX