Pytest - Fixture introspect на функциональном уровне
У меня есть прибор, который требует переменную из тестовой функции. Использование самоанализа и объявление переменной в пространстве имен / контексте функции должно работать, если интроспекция на уровне функций работает, как и для уровня модуля, но каждый раз, когда я запускаю код, я получаю None вместо строки "Fancy Table".
В приспособлении я установил область видимости '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)
Я объявляю переменную 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. Я неправильно использую интроспекцию прибора на функциональном уровне? Как это используется, если не так?
2 ответа
Переменные функции являются локальными и уничтожаются после возврата из функции, они никак не связаны с объектом функции... это то, как работает 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
явно? Это было бы проще, прямолинейнее и, ну, явно.:)
По какой-то причине решение, предоставленное Бруно, у меня не сработало. это то, что я сделал
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']}):
...
Явная привязка локальной переменной к тестовой функции привела к тому, что моя IDE пожаловалась на неразрешенную ссылку. Что еще нам нужно знать, чтобы сделать эту работу?
В приведенном примере, когда я пишу test_create_table.table_name = "Fancy Table"
, test_create_table
часть, часть, на которую жалуется моя IDE, имеет неразрешенную ссылку. Итак, учитывая, что я получаю Неразрешенную ошибку ссылки, как я могу успешно явно связать локальную переменную?