首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
V2EX  ›  Python

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

  •  
  •   90928yao · 286 天前 · 1471 次点击
    这是一个创建于 286 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个不太正经的问题,俩个测试函数有依赖( 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
    
    8 回复  |  直到 2019-01-31 14:22:58 +08:00
        1
    Valkyrie0   286 天前
    只是写业务代码弄这些黑魔法目的是啥?是用例函数参数的话,可以用 @pytest.mark.parametrize 或者 @pytest.fixture(scope="", params=[""]) ,话说要重用代码最简单的不是写个公共方法吗?
        2
    Valkyrie0   286 天前
    逛 V2EX 第一次遇到测试相关的话题
        3
    90928yao   286 天前
    @Valkyrie0 是 pytest 这个框架的黑魔法啊,他执行每个测试函数的时候 都会先执行一大堆 hook 函数,然后把参数用**kwarg 的方法传给测试函数,我现在就是想知道 怎么拿到内存中的那一堆生成的参数 ,然后偷偷修改掉
        4
    Valkyrie0   286 天前
    代理拦截的黑魔法我就不懂了,pytest 支持插件,我看很多插件轮子里面都用上钩子了,可以看看它的插件机制支持不
        5
    zjb861107   286 天前
    按我的理解`pytest_generate_tests`是重新收集测试用例了,这个应该是不推荐或者不允许的。
    换个角度看,正常开始测试之前我收集了 2 条 case,但是代码里再动态添加了 1 个,那最终的测试结果该是 2 个还是 3 个呢?
    如果是两个 case 之间共享数据,应该自定义一个 fixture 就可以了。
        6
    willder   286 天前
    我试着更新了 metafunc 这个对象,比如在 test_equals 中更新一下,
    TestClass.params.update(test_zerodivision=[dict(a=1, b=2), ]),但没有成功,看来在 pytest_generate_tests 中做不到根据前面 case 的结果动态设置后面 case 的参数
        7
    willder   286 天前
    自己设置一个全局变量应该可以做到
        8
    ityoung   286 天前
    测试用例之间不要相互依赖.
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   932 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 21:05 · PVG 05:05 · LAX 13:05 · JFK 16:05
    ♥ Do have faith in what you're doing.