在 Django TestCase 中调用超级方法导致 RecursionError
Calling super method in Django TestCase causes RecursionError
Warning
SimpleTestCase and its subclasses (e.g. TestCase, ...) rely on setUpClass() and tearDownClass() to perform some class-wide initialization (e.g. overriding settings). If you need to override
those methods, don’t forget to call the super implementation:
class MyTestCase(TestCase):
@classmethod
def setUpClass(cls):
super(MyTestCase, cls).setUpClass()
...
@classmethod
def tearDownClass(cls):
...
super(MyTestCase, cls).tearDownClass()
......
我决定在编写测试时遵循这种做法:
class AuthorListViewTest(TestCase):
@classmethod
def setUpTestData(cls):
number_of_authors = 13
for author_num in range(number_of_authors):
Author.objects.create(first_name='Christian %s' % author_num, last_name='Surname %s' % author_num,)
super(AuthorListViewTest, cls).setUpTestData()
# testing functions
但是当 运行 测试时我得到一个 RecursionError
:
<hundreds of identical lines omitted>
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 9, in setUpTestData
Author.objects.create(first_name='Big', last_name='Bob')
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/query.py", line 399, in create
obj.save(force_insert=True, using=self.db)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 796, in save
force_update=force_update, update_fields=update_fields)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 824, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 908, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 947, in _do_insert
using=using, raw=raw)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/query.py", line 1043, in _insert
query = sql.InsertQuery(self.model)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/sql/subqueries.py", line 177, in __init__
super(InsertQuery, self).__init__(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 155, in __init__
self.where = where()
RecursionError: maximum recursion depth exceeded
此错误在删除 super
行后得到修复。
这是为什么?我应该停止调用文档建议的超级实现吗?
从回溯来看,setUpTestData
似乎在父 class 中调用了 setUpClass
。但是您的代码片段调用了 setUpTestData
,这是正确的。
Warning
SimpleTestCase and its subclasses (e.g. TestCase, ...) rely on setUpClass() and tearDownClass() to perform some class-wide initialization (e.g. overriding settings). If you need to override those methods, don’t forget to call the super implementation:
class MyTestCase(TestCase): @classmethod def setUpClass(cls): super(MyTestCase, cls).setUpClass() ... @classmethod def tearDownClass(cls): ... super(MyTestCase, cls).tearDownClass()
......
我决定在编写测试时遵循这种做法:
class AuthorListViewTest(TestCase):
@classmethod
def setUpTestData(cls):
number_of_authors = 13
for author_num in range(number_of_authors):
Author.objects.create(first_name='Christian %s' % author_num, last_name='Surname %s' % author_num,)
super(AuthorListViewTest, cls).setUpTestData()
# testing functions
但是当 运行 测试时我得到一个 RecursionError
:
<hundreds of identical lines omitted>
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 10, in setUpTestData
super(AuthorModelTest, cls).setUpClass()
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/test/testcases.py", line 1025, in setUpClass
cls.setUpTestData()
File "/Users/sunqingyao/Documents/Projects/locallibrary/catalog/tests/test_models.py", line 9, in setUpTestData
Author.objects.create(first_name='Big', last_name='Bob')
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/query.py", line 399, in create
obj.save(force_insert=True, using=self.db)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 796, in save
force_update=force_update, update_fields=update_fields)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 824, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 908, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/base.py", line 947, in _do_insert
using=using, raw=raw)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/query.py", line 1043, in _insert
query = sql.InsertQuery(self.model)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/sql/subqueries.py", line 177, in __init__
super(InsertQuery, self).__init__(*args, **kwargs)
File "/Users/sunqingyao/Envs/django_test/lib/python3.6/site-packages/django/db/models/sql/query.py", line 155, in __init__
self.where = where()
RecursionError: maximum recursion depth exceeded
此错误在删除 super
行后得到修复。
这是为什么?我应该停止调用文档建议的超级实现吗?
从回溯来看,setUpTestData
似乎在父 class 中调用了 setUpClass
。但是您的代码片段调用了 setUpTestData
,这是正确的。