Проблема: Очистить тестовые артефакты, созданные из теста. В приведенном ниже примере, как можно удалить одну строку, созданную во время теста, из базы данных с помощью прибора pytest? (Не все следует удалять из таблицы после каждого запуска. В противном случае можно использовать Удалить все строки или удалить таблицу). Идентификатор созданной строки во время теста сохраняется в функциональной переменной.
Можно ли передать переменную, созданную в ходе теста, в качестве параметра в осветитель в pytest? Приспособление должно всегда запускаться независимо от того, завершен ли тест, если он провалился или завершился успешно. Идентификатор строки не будет известен до запуска теста.
Проблема проиллюстрирована с помощью приспособления
@pytest.fixture()
def clean_up_db_row(row_id):
yield
delete_from_db(self.row_id). # code to delete the row based on the id
def test_something_added_to_database(clean_up_db_row):
row_id = create_db_row() # function under test
...
assert row_id in db # test that information added to the database
# the clean_up_db_row fixture will always run but how will it know about the id variable defined in the function?
Если проверка не выполняется в середине теста, строка, добавленная во время теста, не удаляется при добавлении очистки до конца. Потому что тест перестает выполняться.
Пример проблемы без использования приспособления pytest:
def clean_up_db_row(row_id):
yield
delete_from_db(row_id). # code to delete the row based on the id
def test_something_added_to_database():
row_id = create_db_row() # function under test
...
assert row_id in db # test that information added to the database
clean_up_db_row(row_id) # this won’t run if there is a failure
Решение без приспособления pytest
def clean_up_db_row(row_id):
yield
delete_from_db(row_id). # code to delete the row based on the id
def test_something_added_to_database():
row_id = create_db_row() # function under test
...
try:
assert row_id in db # test that information added to the database
except Exception as e:
raise e
finally:
clean_up_db_row(row_id) # this will always run but doesn’t use a fixture
Потенциальное решение с использованием переменной экземпляра класса
class TestCaseCleanUp:
@pytest.fixture(autouse=True)
def clean_up_db_row(self):
yield
delete_from_db(self.row_id). # code to delete the row based on the id
def test_something_added_to_database(self):
self.row_id = create_db_row() # function under test
...
assert self.row_id in db # test that information added to the database
# the autouse fixture can use the self.row_id assigned