我有一个Django应用程序,我正在尝试使用pytest
和pytest-django
对其进行测试。但是,很多时候,当测试完成运行时,我收到错误的消息,指出数据库删除失败:DETAIL: There is 1 other session using the database.
基本上,我可以将其缩小到的最小测试代码是:
@pytest.fixture
def make_bundle():
a = MyUser.objects.create(key_id=uuid.uuid4())
return a
class TestThings:
def test_it(self, make_bundle):
all_users = list(MyUser.objects.all())
assert_that(all_users, has_length(1))
每一次测试都会因上述错误而失败。我做错什么了吗?或者我该如何解决?
我正在使用的数据库是PostgreSQL 9.6。
答案 0 :(得分:0)
我将其发布为答案,因为我需要发布大量代码并且因为此功能有效。但是,对我来说,这似乎是一个肮脏的技巧,如果更好,我将非常乐意接受其他人的回答。
这是我的解决方案:基本上,将可将所有用户从给定db中踢出的原始sql添加到销毁db的方法中。并通过monkeypatching做到这一点。为了确保在测试之前进行猴子修补,请将其作为自动使用的夹具添加到根conftest.py
文件中:
def _destroy_test_db(self, test_database_name, verbosity):
"""
Internal implementation - remove the test db tables.
"""
# Remove the test database to clean up after
# ourselves. Connect to the previous database (not the test database)
# to do so, because it's not allowed to delete a database while being
# connected to it.
with self.connection._nodb_connection.cursor() as cursor:
cursor.execute(
"SELECT pg_terminate_backend(pg_stat_activity.pid) "
"FROM pg_stat_activity "
"WHERE pg_stat_activity.datname = '{}' "
"AND pid <> pg_backend_pid();".format(test_database_name)
)
cursor.execute("DROP DATABASE %s"
% self.connection.ops.quote_name(test_database_name))
@pytest.fixture(autouse=True)
def patch_db_cleanup():
creation.BaseDatabaseCreation._destroy_test_db = _destroy_test_db
请注意,启动代码可能取决于您的数据库引擎,并且在不同的Django版本中,需要进行猴子修补的方法可能有所不同。