Pytest-功能级别的灯具自省 [英] Pytest - Fixture introspect on function level

查看:69
本文介绍了Pytest-功能级别的灯具自省的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要从测试功能中获取变量的灯具.如果在功能级别上进行自省,则使用自省功能并在函数名称空间/上下文中声明变量应该起作用,就像在模块级上一样,但是每次运行代码时,我都以None结束,而不是字符串"Fancy Table". /p>

在灯具中,我将范围设置为功能",然后通过getattr和request.function进行内省:

#conftest.py
@pytest.fixture(scope='function')
def table(request):
    from data_setup import create_table
    table_name = getattr(request.function, "table_name", None)
    create_table(request, table_name)

我在测试函数中声明了变量table_name:

#test_file.py
class TestTable():

    @pytest.mark.tags("table")
    def test_create_table(self, test_db):
        table_name = "Fancy Table"
        current_page = TablePage(self.test_driver, test_db)
        current_page.go_to_kitchen("Eva", "Evas Kitchen")
        current_page.create_first_table(expected_table_name)
        Validation.assert_equal(expected_table_name, current_page.get_name(), "Table had the wrong name!")

在模块级别上执行此操作就像在类上一样有效,但是一旦我尝试在功能级别上执行此操作,灯具就会再次退出None.我在功能级别使用夹具自检是否错误?如果不是这样,怎么使用?

解决方案

函数变量是局部变量,在函数返回后销毁,它们不以任何方式绑定到函数对象...这是Python的工作方式,与之无关到py.test.

如果您将table_name局部变量显式绑定到测试函数,则可以使您的示例正常工作,从而有效地使其寿命超过了正常寿命:

@pytest.mark.tags("table")
def test_create_table(self, test_db):
    test_create_table.table_name = "Fancy Table"

另一方面,将table_name显式传递给TablePage会不会更简单?这将是更简单,直接且明确的. :)

I've got a fixture that requires a variable from the test function. Using introspection and declaring the variable in the function namespace/context should work if introspection on function level works, as it does for module level, but each time I run the code I end up with None instead of the string "Fancy Table".

In the fixture I set the scope to 'function' and then introspect via getattr and request.function:

#conftest.py
@pytest.fixture(scope='function')
def table(request):
    from data_setup import create_table
    table_name = getattr(request.function, "table_name", None)
    create_table(request, table_name)

I declare the variable table_name in the test function:

#test_file.py
class TestTable():

    @pytest.mark.tags("table")
    def test_create_table(self, test_db):
        table_name = "Fancy Table"
        current_page = TablePage(self.test_driver, test_db)
        current_page.go_to_kitchen("Eva", "Evas Kitchen")
        current_page.create_first_table(expected_table_name)
        Validation.assert_equal(expected_table_name, current_page.get_name(), "Table had the wrong name!")

Doing this on a module level has worked, as has class but as soon as I attempt to do so on a function level the fixture spits out None again. Am I using fixture introspection on a function level wrong? How is it used if not like this?

解决方案

Function variables are local and are destroyed after the function returns, they are not bound the function object in any way... this is how Python works and not related to py.test.

Your example will work if you bind the table_name local variable explicitly to the test function, effectively letting it outlive its usual life-time:

@pytest.mark.tags("table")
def test_create_table(self, test_db):
    test_create_table.table_name = "Fancy Table"

On the other hand, wouldn't be simpler to just pass the table_name to TablePage explicitly? It would be simpler, straightforward and, well, explicit. :)

这篇关于Pytest-功能级别的灯具自省的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆