在 Django 单元测试期间,数据库保持为空
During django unittests, database remains empty
我运行一些需要手动调试的单元测试。
在这些测试期间,不知何故没有任何内容写入数据库。
有什么方法可以强制 Django(或 pytest?)在执行时直接提交更改,这样我就可以在遇到断点时实际看到数据库中的内容吗?
my_object = SomeDefaultDjangoModel()
my_object.some_random_text = 'Just adding some data'
my_object.save()
foo = 'bar' <= Hitting breakpoint here.
正在对我的数据库 return 0 行进行手动 SQL 查询。
我怎样才能完成这项工作?
*更新*
问题是 Django 不允许您在每个请求结束之前保存对数据库的更改,这在大多数情况下不是问题。
但是,当您想绕过 ORM 并使用原始连接执行查询时,它似乎为此启动了一个单独的数据库连接。由于所有事务在请求结束之前都处于挂起状态,因此无法从其他数据库连接访问这些更改。 return 的无效结果使我的单元测试失败。
我还没有找到提交挂起事务的方法(还),所以我想我会开始为我的模型编写 save_raw() 方法,这些方法只是将数据直接保存到数据库中。
从 TransactionTestCase
而不是 TestCase
对测试进行子类化,然后数据将如预期的那样 saved/committed,因此您可以直接检查数据库中的数据。
根据 the docs:
Django’s TestCase
class is a more commonly used subclass of
TransactionTestCase
that makes use of database transaction
facilities to speed up the process of resetting the database to a
known state at the beginning of each test. A consequence of this,
however, is that some database behaviors cannot be tested within a
Django TestCase
class. For instance, you cannot test that a block of
code is executing within a transaction, as is required when using
select_for_update()
. In those cases, you should use
TransactionTestCase
.
TransactionTestCase
and TestCase
are identical except for the manner
in which the database is reset to a known state and the ability for
test code to test the effects of commit and rollback:
- A
TransactionTestCase
resets the database after the test runs by
truncating all tables. A TransactionTestCase
may call commit and
rollback and observe the effects of these calls on the database.
- A
TestCase
, on the other hand, does not truncate tables after a test.
Instead, it encloses the test code in a database transaction that is
rolled back at the end of the test. This guarantees that the rollback
at the end of the test restores the database to its initial state.
我运行一些需要手动调试的单元测试。 在这些测试期间,不知何故没有任何内容写入数据库。
有什么方法可以强制 Django(或 pytest?)在执行时直接提交更改,这样我就可以在遇到断点时实际看到数据库中的内容吗?
my_object = SomeDefaultDjangoModel()
my_object.some_random_text = 'Just adding some data'
my_object.save()
foo = 'bar' <= Hitting breakpoint here.
正在对我的数据库 return 0 行进行手动 SQL 查询。 我怎样才能完成这项工作?
*更新*
问题是 Django 不允许您在每个请求结束之前保存对数据库的更改,这在大多数情况下不是问题。 但是,当您想绕过 ORM 并使用原始连接执行查询时,它似乎为此启动了一个单独的数据库连接。由于所有事务在请求结束之前都处于挂起状态,因此无法从其他数据库连接访问这些更改。 return 的无效结果使我的单元测试失败。
我还没有找到提交挂起事务的方法(还),所以我想我会开始为我的模型编写 save_raw() 方法,这些方法只是将数据直接保存到数据库中。
从 TransactionTestCase
而不是 TestCase
对测试进行子类化,然后数据将如预期的那样 saved/committed,因此您可以直接检查数据库中的数据。
根据 the docs:
Django’s
TestCase
class is a more commonly used subclass ofTransactionTestCase
that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a DjangoTestCase
class. For instance, you cannot test that a block of code is executing within a transaction, as is required when usingselect_for_update()
. In those cases, you should useTransactionTestCase
.
TransactionTestCase
andTestCase
are identical except for the manner in which the database is reset to a known state and the ability for test code to test the effects of commit and rollback:
- A
TransactionTestCase
resets the database after the test runs by truncating all tables. ATransactionTestCase
may call commit and rollback and observe the effects of these calls on the database.- A
TestCase
, on the other hand, does not truncate tables after a test. Instead, it encloses the test code in a database transaction that is rolled back at the end of the test. This guarantees that the rollback at the end of the test restores the database to its initial state.