According to the docs:
根据文件:
A TestCase, on the other hand, does not truncate tables and reload initial data at the beginning of a test. Instead, it encloses the test code in a database transaction that is rolled back at the end of the test. It also prevents the code under test from issuing any commit or rollback operations on the database, to ensure that the rollback at the end of the test restores the database to its initial state. In order to guarantee that all TestCase code starts with a clean database, the Django test runner runs all TestCase tests first, before any other tests (e.g. doctests) that may alter the database without restoring it to its original state.
另一方面,TestCase不会在测试开始时截断表并重新加载初始数据。相反,它将测试代码包含在数据库事务中,该事务在测试结束时回滚。它还可以防止被测代码对数据库发出任何提交或回滚操作,以确保测试结束时的回滚将数据库恢复到其初始状态。为了保证所有TestCase代码都以干净的数据库开始,Django测试运行器首先运行所有TestCase测试,然后再进行任何其他测试(例如doctests),这些测试可能会改变数据库而不将其恢复到原始状态。
So if I have a test that looks like this:
所以如果我有一个看起来像这样的测试:
class GeneralUserCreateTest(TestCase):
def setUp(self):
create_roletypes()
create_permissiontypes()
self.client = Client()
self.event = create_event()
def test_create(self):
create_url = reverse('event_user_signup', args=[self.event.slug])
post_data = {
'signup-account-email': 'foo@bar.com',
'signup-account-password': 'foobar',
'signup-account-password2': 'foobar',
'signup-account-first_name': 'Foo',
'signup-account-last_name': 'Bar',
}
response = self.client.post(create_url, data=post_data)
self.assertEqual(response.status_code, 302)
# check creation of user object
self.assertEqual(User.objects.filter(email=post_data['signup-account-email']).count(), 1)
user = User.objects.get(username=post_data['signup-account-email'])
# user and profile objects created
self.assertEqual(User.objects.all().count(), 1)
self.assertEqual(Profile.objects.all().count(), 1)
# get the first user and profile object to test against submitted field
user = User.objects.all()[0]
profile = Profile.objects.all()[0]
role = Role.objects.filter(event=self.event, profiles=profile)[0]
self.assertEqual(role.roletype.name, 'General')
self.assertEqual(user.username, post_data['signup-account-email'])
self.assertEqual(user.email, post_data['signup-account-email'])
self.assertEqual(profile.first_name, post_data['signup-account-first_name'])
self.assertEqual(profile.last_name, post_data['signup-account-last_name'])
Is it still necessary to run a teardown
method or does the TestCase
class take care of it? If so, when should one use the teardown
method given the availability of the TestCase
class?
是否仍然需要运行拆解方法或者TestCase类是否需要处理它?如果是这样的话,考虑到TestCase类的可用性,何时应该使用拆解方法?
3 个解决方案
#1
23
For the purposes of the database, tearDown
is pretty pointless, because each test is run in a transaction. However, not everything in a test involves the database. You might test file creation/reading, spin off processes, open network connections, etc. These types of things usually require you to "close" them after you're done. This is what tearDown
is for, i.e. cleaning up stuff from your setUp
method, not related to the database. (Though, if you were actually directly connecting to a database, i.e. as the actual Django tests must do to make sure all the DBAPI stuff works properly, you'd need to do clean up there too.)
出于数据库的目的,tearDown是毫无意义的,因为每个测试都在事务中运行。但是,并非测试中的所有内容都涉及数据库。您可以测试文件创建/读取,分离进程,打开网络连接等。这些类型的事情通常需要您在完成后“关闭”它们。这就是tearDown的用途,即清理setUp方法中的东西,与数据库无关。 (但是,如果您实际上直接连接到数据库,即实际的Django测试必须确保所有DBAPI工作正常,您也需要在那里进行清理。)
#2
8
I was working on a project that handled some file uploads, and i needed to delete the files that were created by the test and the tearDown
method was very useful in that situation.
我正在处理一个处理一些文件上传的项目,我需要删除测试创建的文件,而tearDown方法在这种情况下非常有用。
import shutil
#....
#....
def tearDown(self):
shutil.rmtree(settings.UPLOAD_ROOT)
#3
5
If you are using an alternative database like MongoDB or Redis and you need to load in a set of initial data (a "collection"), you will need to override the tearDown
method too.
如果您使用的是MongoDB或Redis等替代数据库,并且需要加载一组初始数据(“集合”),则还需要覆盖tearDown方法。
See http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/
见http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/
In general, django.test.TestCase
does a full database flush at the start of each new test. This means that we do not need to manually delete objects in our tearDown as Chris Pratt has mentioned above. The next test setUp will make sure the database is clean.
通常,django.test.TestCase在每个新测试开始时执行完整的数据库刷新。这意味着我们不需要像Chris Pratt上面提到的那样在我们的tearDown中手动删除对象。下一个测试setUp将确保数据库是干净的。
However, if we are using doctests and unittest.TestCase
, there will be no database flush before tests are run again. At the start of a test, the database will be in whatever state the previous test left. This means that any stray data left by a previous run would cause conflict. So if we are using doctests or unittest.TestCase for our django tests, a cleanup might be good practice.
但是,如果我们使用doctests和unittest.TestCase,则在再次运行测试之前不会有数据库刷新。在测试开始时,数据库将处于上一次测试离开的任何状态。这意味着前一次运行留下的任何杂散数据都会导致冲突。因此,如果我们使用doctests或unittest.TestCase进行django测试,清理可能是一种很好的做法。
Finally, in more complicated scenarios, it might also make sense to deliberately persist the test database to hunt down specific unit test bugs.
最后,在更复杂的场景中,故意坚持测试数据库来寻找特定的单元测试错误也是有意义的。
#1
23
For the purposes of the database, tearDown
is pretty pointless, because each test is run in a transaction. However, not everything in a test involves the database. You might test file creation/reading, spin off processes, open network connections, etc. These types of things usually require you to "close" them after you're done. This is what tearDown
is for, i.e. cleaning up stuff from your setUp
method, not related to the database. (Though, if you were actually directly connecting to a database, i.e. as the actual Django tests must do to make sure all the DBAPI stuff works properly, you'd need to do clean up there too.)
出于数据库的目的,tearDown是毫无意义的,因为每个测试都在事务中运行。但是,并非测试中的所有内容都涉及数据库。您可以测试文件创建/读取,分离进程,打开网络连接等。这些类型的事情通常需要您在完成后“关闭”它们。这就是tearDown的用途,即清理setUp方法中的东西,与数据库无关。 (但是,如果您实际上直接连接到数据库,即实际的Django测试必须确保所有DBAPI工作正常,您也需要在那里进行清理。)
#2
8
I was working on a project that handled some file uploads, and i needed to delete the files that were created by the test and the tearDown
method was very useful in that situation.
我正在处理一个处理一些文件上传的项目,我需要删除测试创建的文件,而tearDown方法在这种情况下非常有用。
import shutil
#....
#....
def tearDown(self):
shutil.rmtree(settings.UPLOAD_ROOT)
#3
5
If you are using an alternative database like MongoDB or Redis and you need to load in a set of initial data (a "collection"), you will need to override the tearDown
method too.
如果您使用的是MongoDB或Redis等替代数据库,并且需要加载一组初始数据(“集合”),则还需要覆盖tearDown方法。
See http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/
见http://www.belchak.com/2011/02/07/unit-testing-django-with-a-nosql-backend/
In general, django.test.TestCase
does a full database flush at the start of each new test. This means that we do not need to manually delete objects in our tearDown as Chris Pratt has mentioned above. The next test setUp will make sure the database is clean.
通常,django.test.TestCase在每个新测试开始时执行完整的数据库刷新。这意味着我们不需要像Chris Pratt上面提到的那样在我们的tearDown中手动删除对象。下一个测试setUp将确保数据库是干净的。
However, if we are using doctests and unittest.TestCase
, there will be no database flush before tests are run again. At the start of a test, the database will be in whatever state the previous test left. This means that any stray data left by a previous run would cause conflict. So if we are using doctests or unittest.TestCase for our django tests, a cleanup might be good practice.
但是,如果我们使用doctests和unittest.TestCase,则在再次运行测试之前不会有数据库刷新。在测试开始时,数据库将处于上一次测试离开的任何状态。这意味着前一次运行留下的任何杂散数据都会导致冲突。因此,如果我们使用doctests或unittest.TestCase进行django测试,清理可能是一种很好的做法。
Finally, in more complicated scenarios, it might also make sense to deliberately persist the test database to hunt down specific unit test bugs.
最后,在更复杂的场景中,故意坚持测试数据库来寻找特定的单元测试错误也是有意义的。