简体   繁体   English

Pytest - 功能级别的夹具内省

[英]Pytest - Fixture introspect on function level

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".如果函数级别的自省有效,则使用自省并在函数命名空间/上下文中声明变量应该有效,就像模块级别一样,但每次运行代码时,我最终都会得到 None 而不是字符串“Fancy Table”。

In the fixture I set the scope to 'function' and then introspect via getattr and request.function:在夹具中,我将范围设置为“函数”,然后通过 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)

I declare the variable table_name in the test function:我在测试函数中声明了变量 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!")

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.在模块级别这样做已经奏效了,类也是如此,但是一旦我尝试在函数级别这样做,夹具就会再次吐出 None 。 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 .函数变量是局部的,在函数返回后被销毁,它们不以任何方式绑定函数对象......这就是 Python 的工作方式,与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:如果您将table_name局部变量显式绑定到测试函数,则您的示例将起作用,有效地让它超过其通常的生命周期:

@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?另一方面,将table_name显式传递给TablePage不是更简单吗? It would be simpler, straightforward and, well, explicit.它会更简单、直接而且明确。 :) :)

Explicitly binding the local variable to the test function resulted in my IDE complaining about an Unresolved reference.将局部变量显式绑定到测试函数导致我的 IDE 抱怨未解析的引用。 What else do we need to know to make this work?我们还需要知道什么才能使这项工作发挥作用?

In the example given, when I write test_create_table.table_name = "Fancy Table" , the test_create_table part is the part my IDE complains has an Unresolved reference.在给出的示例中,当我编写test_create_table.table_name = "Fancy Table"test_create_table部分是我的 IDE 抱怨的部分具有未解析的引用。 So given I am receiving the Unresolved reference error, how can I successfully explicitly bind the local variable?因此,鉴于我收到 Unresolved 引用错误,如何成功显式绑定局部变量?

for some reason solution provided by Bruno didn't work for me.出于某种原因,布鲁诺提供的解决方案对我不起作用。 this is what i did这就是我所做的

import inspect

@pytest.fixture(scope='function')
def custom_fixture(request):
    sig = inspect.signature(request.function)

    my_fixture_obj = None

    if 'fixture_data' in sig.parameters:
        fixture_data = sig.parameters['fixture_data'].default

        my_fixture_obj = MyFixtureObject(fixture_data['data'])

    yield my_fixture_obj

    # cleanup my_fixture_obj


def test_sample1(custom_fixture, fixture_data = {'data': ['s1', 's2', 's3']}):
    ...

def test_sample2(custom_fixture, fixture_data = {'data': ['a1', 'a2', 'a3']}):
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM