我正在Django==1.11
和python==2.7.12
进行一些简单的单元测试。所有类似测试的测试执行时间都在0.0040 seconds
左右,例如自定义suspend
操作,该操作包含在帖子底部的test中。所有使用的类,表单,称为函数都在所有测试中被模拟。但是,unsuspend
操作的测试耗时是执行时间的10倍,平均值为0.0400 seconds
我不明白为什么,因为它甚至比suspend
操作稍微简单一些
# The custom unsuspend DRF action being tested
@action(methods=['get'], detail=True, permission_classes=[OrganizationBasePermissions])
def unsuspend(self, request, uuid):
organization = self.get_object()
start = datetime.datetime.now()
mc_organization.services.organization.unsuspend(organization=organization)
end = datetime.datetime.now()
print('service call duration:', end - start)
# ('service call duration:', datetime.timedelta(0, 0, 143))
serializer = self.get_serializer(instance=organization)
return Response(data=serializer.data, status=status.HTTP_200_OK)
# The unittest of the unsuspend action above
@mock.patch('mc_organization.api.viewsets.organization.Response')
@mock.patch('mc_organization.api.viewsets.organization.ModelViewSet.get_serializer')
@mock.patch('mc_organization.api.viewsets.organization.'
'mc_organization.services.organization.unsuspend')
@mock.patch('mc_organization.api.viewsets.organization.ModelViewSet.get_object')
def test_viewset_unsuspend_action(self, get_object_mock, unsuspend_service_mock, get_serializer_mock,
response_mock):
get_object_mock.return_value = self.organization
get_serializer_mock.return_value = self.serialized_organization
self.viewset.unsuspend(request=self.request, uuid=self.organization.uuid)
self.assertEqual(get_object_mock.call_count, 1)
unsuspend_service_mock.assert_called_once_with(organization=self.organization)
get_serializer_mock.assert_called_once_with(instance=self.organization)
response_mock.assert_called_once_with(data=self.serialized_organization.data, status=status.HTTP_200_OK)
当打印被调用的方法以查看它们是否被正确模拟时,结果显示 预期的模拟值:
print('mocked get object?:', self.get_object())
print('mocked service?:', mc_organization.services.organization.unsuspend)
print('mocked get_serializer?:', self.get_serializer())
print('mocked Response?:', Response())
# ('mocked get object?:', <MagicMock name='mock.user.organization' id='139678650884304'>)
# ('mocked service?:', <MagicMock name='unsuspend' id='139678651183504'>)
# ('mocked get_serializer?:', <MagicMock name='get_serializer()' id='139678650905808'>)
# ('mocked Response?:', <MagicMock name='Response()' id='139678651836496'>)
我正在使用django-slowtests
来跟踪我最慢的测试,结果如下:
5 slowest tests:
0.0427s test_viewset_unsuspend_action (mc_organization.tests.api.viewsets.organization.test_u_viewset.OrganizationViewSetUnitTestCase)
0.0051s test_viewset_suspend_action_with_valid_request_data (mc_organization.tests.api.viewsets.organization.test_u_viewset.OrganizationViewSetUnitTestCase)
...
下面的暂停动作测试稍微(非常轻微)更复杂,执行时间减少了近10倍:
# The custom DRF action suspend, which is more complex but takes less time to execute
@action(methods=['post'], detail=True, permission_classes=[OrganizationBasePermissions])
def suspend(self, request, uuid):
organization = self.get_object()
form = OrganizationSuspendForm(data=request.data, organization=organization)
if not form.is_valid():
return Response(data=form.errors, status=status.HTTP_400_BAD_REQUEST)
mc_organization.services.organization.suspend(
organization=organization,
reason=form.cleaned_data.get('suspended_reason')
)
serializer = self.get_serializer(instance=organization)
return Response(data=serializer.data, status=status.HTTP_200_OK)
@mock.patch('mc_organization.api.viewsets.organization.Response')
@mock.patch('mc_organization.api.viewsets.organization.'
'mc_organization.services.organization.suspend')
@mock.patch('mc_organization.api.viewsets.organization.ModelViewSet.get_serializer')
@mock.patch('mc_organization.api.viewsets.organization.OrganizationSuspendForm')
@mock.patch('mc_organization.api.viewsets.organization.ModelViewSet.get_object')
def test_viewset_suspend_action_with_valid_request_data(self, get_object_mock, form_mock, get_serializer_mock,
suspend_service_mock, response_mock):
get_object_mock.return_value = self.organization
form_mock.return_value.is_valid.return_value = True
form_mock.return_value.cleaned_data.get.return_value = "suspend reason"
get_serializer_mock.return_value = self.serialized_organization
self.viewset.suspend(request=self.request, uuid=self.organization.uuid)
self.assertEqual(get_object_mock.call_count, 1)
form_mock.assert_called_once_with(data=self.request.data, organization=self.organization)
suspend_service_mock.assert_called_once_with(
organization=self.organization,
reason=form_mock.return_value.cleaned_data.get.return_value
)
get_serializer_mock.assert_called_once_with(instance=self.organization)
response_mock.assert_called_once_with(data=self.serialized_organization.data, status=status.HTTP_200_OK)
如果unsuspend
动作单元测试花费的时间比更复杂的suspend
动作单元测试长10倍,
我怎么能解决这个问题?
次要更新:
删除最慢的测试,作为unsuspend
单元测试将使suspend
单元测试成为最慢的测试:
0.0539s test_viewset_unsuspend_action (mc_organization.tests.api.viewsets.organization.test_u_viewset.OrganizationViewSetUnitTestCase)
0.0040s test_viewset_suspend_action_with_valid_request_data (mc_organization.tests.api.viewsets.organization.test_u_viewset.OrganizationViewSetUnitTestCase)
删除后:
0.0546s test_viewset_update_action_with_invalid_request_data (mc_organization.tests.api.viewsets.organization.test_u_viewset.OrganizationViewSetUnitTestCase)
什么可能导致这种情况并且是预期的行为?