我有一个 Django 应用程序,我正在尝试使用 pytest
和 pytest-django
来测试它。但是,很多时候,当测试运行完成时,我会收到数据库无法删除的错误:详细信息:还有 1 个其他 session 正在使用该数据库。
基本上,我可以缩小范围的最小测试代码是:
@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。
最佳答案
我将其发布为答案,因为我需要发布一大块代码并且因为这有效。然而,这对我来说看起来像是一个肮脏的黑客,如果它更好的话,我会非常乐意接受其他人的答案。
这是我的解决方案:基本上,将从给定数据库中踢出所有用户的原始sql添加到销毁数据库的方法中。并通过猴子补丁来做到这一点。为了确保猴子补丁在测试之前发生,请将其添加到根 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
请注意,踢出代码可能取决于您的数据库引擎,并且需要monkeypatching的方法在不同的Django版本中可能有所不同。
关于python - Pytest-django:测试后无法删除数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53922902/