我在Django Rest Framework中有一个测试类,它包含一个函数,如果该函数是该类中的唯一函数,则该函数通过测试;如果它是两个或多个函数之一,则该函数失败。
如果我按原样运行以下代码,即def test_audio_list(self)
函数仍被注释掉,则测试将按照两个assert语句通过。
如果我取消注释def test_audio_list(self)
功能并运行测试,def test_audio_retrieve(self)
功能将失败并显示404,而def test_audio_list(self)
将通过。
这是我完整的测试用例(def test_audio_list(self):
注释了。
class AudioTests(APITestCase):
# setup a test user and a factory
# factory = APIRequestFactory()
test_user = None
def setUp(self):
importer()
self.test_user = User(username='jim', password='monkey123', email='[email protected]')
self.test_user.save()
# def test_audio_list(self):
# """
# Check that audo returns a 200 OK
# """
# factory = APIRequestFactory()
# view = AudioViewSet.as_view(actions={'get': 'list'})
#
# # Make an authenticated request to the view...
# request = factory.get('/api/v1/audio/')
# force_authenticate(request, user=self.test_user)
# response = view(request, pk="1")
#
# self.assertContains(response, 'audio/c1ha')
# self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_audio_retrieve(self):
"""
Check that audo returns a 200 OK
"""
factory = APIRequestFactory()
view = AudioViewSet.as_view(actions={'get': 'retrieve'})
# Make an authenticated request to the view...
request = factory.get('/api/v1/audio/')
force_authenticate(request, user=self.test_user)
response = view(request, pk="1")
self.assertContains(response, 'audio/c1ha')
self.assertEqual(response.status_code, status.HTTP_200_OK)
在上面运行python manage.py test
不会产生任何错误。但是,如果我取消注释def test_audio_list(self)
函数,则def test_audio_retrieve(self)
将失败,并显示以下内容:
======================================================================
FAIL: test_audio_retrieve (api.tests.AudioTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/code/api/tests.py", line 96, in test_audio_retrieve
self.assertContains(response, 'audio/c1ha')
File "/usr/local/lib/python3.7/site-packages/django/test/testcases.py", line 446, in assertContains
response, text, status_code, msg_prefix, html)
File "/usr/local/lib/python3.7/site-packages/django/test/testcases.py", line 418, in _assert_contains
" (expected %d)" % (response.status_code, status_code)
AssertionError: 404 != 200 : Couldn't retrieve content: Response code was 404 (expected 200)
注。如果我更改类中函数的顺序,即将def test_audio_retrieve(self)
放在def test_audio_list(self)
之前,结果仍然相同。
我以为我在这里一定做错了什么,但我无法将手指放在上面。
非常感谢您的帮助。
干杯,
C
您多次使用'force_authenticate',也许您可以在setUp中对用户进行身份验证或使用refresh_from_db
请检查:注意:force_authenticate直接将request.user设置为内存中的用户实例。如果要在多个测试中重用同一用户实例以更新保存的用户状态,则可能需要在测试之间调用refresh_from_db()。
https://www.django-rest-framework.org/api-guide/testing/
...
您可以尝试合并功能吗,像这样,
def test_audio(self):
"""
Check that audio returns a 200 OK
"""
factory = APIRequestFactory()
view_retrieve = AudioViewSet.as_view(actions={'get': 'retrieve'})
view_list = AudioViewSet.as_view(actions={'get': ‘list’})
# Make an authenticated request to the view...
request = factory.get('/api/v1/audio/')
force_authenticate(request, user=self.test_user)
# Retrieve
response = view_retrieve(request, pk="1")
self.assertContains(response, 'audio/c1ha')
self.assertEqual(response.status_code, status.HTTP_200_OK)
# List
response = view_list(request, pk="1")
self.assertContains(response, 'audio/c1ha')
self.assertEqual(response.status_code, status.HTTP_200_OK)
[此后我在Django论坛上非常有帮助的用户向我解释的问题非常简单。
https://forum.djangoproject.com/t/apitestcase-with-apirequestfactory/420
我在对象ID上使用自动递增字段,并且在Django执行每次测试时,它首先通过importer()
setUp()def setUp(). After the each test function is run, Django then deletes the data and will again run
importer()中的which in turn run
调用导入数据。 ``。
这将导致我的对象的ID随所运行的类中的每个测试函数而变化。
我在测试用例中静态定义了ID,以为对象ID在整个测试用例中都将保持不变。
所以代替
# hardcoded PK
response = self.detail_view(request, pk="1")
我现在有
# dynamically assigned PK
pk = Audio.objects.first().id
response = self.detail_view(request, pk=pk)
长话短说,我将需要动态获取要测试的对象的ID,或者更好的是,创建一个不依赖数据导入的测试用例。建议我使用Factory Boy之类的东西在测试用例中生成我自己的测试数据。