我正在使用Django应用程序,该应用程序在Django REST Framework(DRF)的帮助下公开API。我已经到了需要创建测试框架并且一直在研究DRF和Django测试文档的地步。
我已经定义了一个BaseTestCase
类,用于设置所有其他测试用例所需的基本必需数据,以及从ModelTestCase
继承的BaseTestCase
类,以便按顺序使用所执行的设置。以下是这些看法:
BaseTestCase
class BaseTestCase(APITestCase):
'''
This class does basic data setup required to test API endpoints
Creates 1+ users, sets the client to use that user for auth
'''
@classmethod
def create_data(cls):
'''
Create the users needed by automated tests
'''
# creates some data used by child test cases
@classmethod
def setUpClass(cls):
client = APIClient()
cls.client = client
# call the method to create necessary base data
cls.create_data()
# get a user and set the client to use their auth
user = get_user_model().objects.get(email='auto-test@test.com')
client.force_authenticate(user=user)
# cls.client = client
super(BaseTestCase, cls).setUpClass()
def test_base_data(self):
'''
This test ensures base data has been created
'''
# tests basic data to ensure it's created properly
def test_get_users(self):
'''
This test attempts to get the list of users via the API
It depends on the class setup being complete and correct
'''
url = '/api/users/'
response = BaseTestCase.client.get(url, format='json')
print(json.loads(response.content))
self.assertEqual(response.status_code, status.HTTP_200_OK)
ModelTestCase
class ModelTestCase(BaseTestCase):
@classmethod
def setUpClass(cls):
super(ModelTestCase, cls).setUpClass()
client = APIClient()
user = get_user_model().objects.all()[0]
client.force_authenticate(user=user)
cls.client = client
def test_create_model(self):
'''
Make sure we can create a new model with the API
'''
url = '/api/model/'
# set the request payload
response = ModelTestCase.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
当我运行所有测试时,我得到一个失败,因为BaseTestCase
数据验证断言中的一个(基于存在多少个对象的计数)由于存在太多而失败(因为{{1}已经设置了两次 - 一次是自己的,一次是BaseTestCase
setUpClass
当我只运行 ModelTestCase
时,我收到以下错误:
ModelTestCase
我不明白 - ======================================================================
ERROR: test_get_users (app.tests.ModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/tests.py", line 125, in test_get_users
response = BaseTestCase.client.get(url, format='json')
AttributeError: type object 'BaseTestCase' has no attribute 'client'
----------------------------------------------------------------------
的{{1}}是否应该正常运行?
我还尝试将setUpClass()
定义为继承自BaseTestCase
- 使用此配置,运行所有测试成功,但(我相信)仅因为测试按字母顺序运行,因此{ {1}}运行,设置数据,然后ModelTestCase
可以使用该数据。
我希望测试本身是独立的 - 我相信APITestCase
可以用于此。但是,我还希望客户端设置(用于身份验证)以及数据设置(我认为最终会相对昂贵)在测试用例之间共享,这样就不需要每个案例重复一次这就是为什么我认为创建一个继承的基类是要走的路。
有没有办法完成我所概述的内容?我应该使用BaseTestCase
代替ModelTestCase
吗?或者有没有办法创建我的setUpData()
类并在执行测试时让不运行?
答案 0 :(得分:0)
根据Django Rest Framework Testing部分,您应使用setUp()
方法保留默认架构。这就是我找到合理解决方案的方式:
from django.urls import reverse
from rest_framework.test import APITestCase
import pytest
from core.factories import UserFactory, ClientFactory, AdministratorFactory, FacilitatorFactory, ParticipantFactory
class BaseAPITestCase(APITestCase):
def setUp(self):
self.user = UserFactory()
self.client.force_authenticate(user=self.user)
class UserTestCase(BaseAPITestCase):
def setUp(self):
# Call Parent's constructor.
super(self.__class__, self).setUp()
self.clients = ClientFactory(user=self.user)
self.administrator = AdministratorFactory(user=self.user)
self.facilitator = FacilitatorFactory(user=self.user)
self.participant = ParticipantFactory(user=self.user)
def test_get_users(self):
url = reverse("api_v1:user-list")
response = self.client.get(url)
self.assertEquals(response.data["count"], 1)
self.assertEquals(response.data["results"][0]["username"], self.user.username)
self.assertEquals(response.status_code, 200)
结果:
============================================================================== test session starts ===============================================================================
platform linux -- Python 3.7.6, pytest-5.3.0, py-1.8.1, pluggy-0.13.1 --
cachedir: .pytest_cache
Django settings: tests.settings (from ini file)
Using --randomly-seed=1589794116
plugins: django-3.7.0, django-test-migrations-0.1.0, randomly-3.1.0, hypothesis-4.53.0, timeout-1.3.0, testmon-1.0.0, cov-2.8.0, deadfixtures-2.1.0
collected 1 items
tests/api/test_basics.py::UserTestCase::test_get_users PASSED