Функция ORM SQLAlchemy работает в основном скрипте, но не работает в Pytest

#sqlalchemy #pytest #python-3.7

Вопрос:

Используя Postgres, SQLAlchemy 1.4 ORM, Python 3.7, Pytest.

У меня есть сценарий, myproject/src/db.py и тесты для него находятся внутри myproject/tests/ .

У db.py меня есть функция для удаления любой заданной таблицы, она работает так, как ожидалось:

 async def delete_table(self, table_name):  table = self.meta.tables[table_name]  async with self.engine.begin() as conn:  await conn.run_sync(Base.metadata.drop_all(sync_engine, [table], checkfirst=True))  

Это называется так: asyncio.run(db.delete_table('user'))

Во conftest.py мне есть такое приспособление, как это:

 @pytest.fixture(scope='function') def test_drop_table():  def get_delete_tables(table_name):  return asyncio.run(DB.delete_table(table_name))  return get_delete_tables  

В test.py я провожу тест вот так:

 @pytest.mark.parametrize('function_input, expected',  [('user', 'user'),  pytest.param('intentional failure', 'intentional failure',  marks=pytest.mark.xfail(reason='testing incorrect table name fails'))]) def test_drop_table(test_drop_table, function_input, expected):  # Drop the table  test_drop_table(function_input)    # Check that it no longer exists  with pytest.raises(KeyError) as error_info:  test_table_commits(function_input, expected)  raise KeyError  assert error_info.type is KeyError  

Когда я запускаю этот тест, я получаю эту ошибку:

 self = lt;postgresdb.PostgresDb object at 0x7f4bbd87cc18gt;, table_name = 'user'   async def delete_table(self, table_name): gt; table = self.meta.tables[table_name] E KeyError: 'user'  

Я проверил, что эту таблицу можно удалить в основном сценарии. Затем я повторно заполняю таблицу, проверяю ее наличие, а затем пытаюсь удалить ее с помощью теста, но постоянно получаю KeyError сообщение о том, что таблицы нет, даже если при проверке базы данных эта таблица действительно присутствует.

Я не уверен, что нужно протестировать или настроить в коде, чтобы заставить Pytest работать с этой функцией. Я ценю любую помощь!

Ответ №1:

Я думаю , что в первый раз он удаляет таблицу с именем user , но второй ввод pytest.mark.parametrize также является именем user , так что это может быть ошибка. Если вам нужно протестировать 2 разных сценария, лучше иметь 2 разные тестовые функции. Сделав это, вы сможете использовать весь свой код with pytest.raises(KeyError) as error_info во 2-й тестовой функции.