V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
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
90928yao
V2EX  ›  Python

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

  •  
  •   90928yao · 2019-01-31 08:53:38 +08:00 · 3367 次点击
    这是一个创建于 2126 天前的主题,其中的信息可能已经有所发展或是发生改变。

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