Django Rest Framework测试失败并通过,取决于功能的数量

问题描述 投票:1回答:2

我在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

django django-rest-framework django-testing
2个回答
2
投票

您多次使用'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)

0
投票

[此后我在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之类的东西在测试用例中生成我自己的测试数据。

© www.soinside.com 2019 - 2024. All rights reserved.