我正在使用Django(1.8)+ DRF + uwsgi + nginx并尝试对我所做的单元测试API。要运行测试,我需要填充db(例如,创建用户)并在所有测试中使用此数据。所以我尝试了两种方法:
直接在TestCase.setUp中创建:
class ApiTests(TestCase):
def setUp(self):
Account.objects.create_user(username='username', password='password')
或使用灯具:
class ApiTests(TestCase):
fixtures = ['dump.json']
接下来,我通过主管运行我的项目:
system("service supervisord startall")
一切准备就绪后,我尝试在测试中访问我的API以使用:
登录login_data = {"username": "username", "password": "password"}
rslt = client.post(HOST_NAME + '/login/', data=login_data)
...但我无法授权,因为用户以某种方式不存在于db!
正如我在Django测试的文档中发现的那样,TestCase不会将数据写入db,而是将其存储在事务中,并在测试后回滚。正如我所看到的,我只能在测试端获取此数据(使用显示用户的User.objects.all()),但不能在我的nginx-server端获取(User.objects.all()在这一边显示0项)。
ATM我可以看到几个选项:
你能帮忙吗?
答案 0 :(得分:2)
您不应该使用Web服务器来测试django视图,即使实际上视图确实需要由Web服务器驱动。为了测试请求/响应行为,您应该使用 django测试客户端。 Django doc有很好的例子,引用:
>>> from django.test import Client >>> c = Client() >>> response = c.post('/login/', {'username': 'john', 'password': 'smith'}) >>> response.status_code 200 >>> response = c.get('/customer/details/') >>> response.content b'<!DOCTYPE html...'
最重要的是,该文档详细解释了如何执行GET
,POST
请求以及如何测试视图的响应等。希望这是有道理的。
答案 1 :(得分:1)
是的!您已经确定了问题所在。 Django TestCase
在自己的绝缘环境中执行。它将在每个套件运行开始时创建前缀为test_
的测试数据库,并将在事务中执行每个测试,因此即使您启动测试套件,在初始化后暂停它,也可以设置django配置为supervisord指向测试数据库,继续测试执行,你仍然看不到任何数据。
您在上述示例中看不到任何数据的原因是因为测试有自己的事务,然后当您向Web服务器发出请求时,Web服务器将打开一个不同的事务,并且将无法看到来自测试的未提交数据。
测试你的观点(根据我的经验)django TestCases和测试客户,通常会在那里得到95%。它们非常快,因为每个测试都在事务中执行,它们公开了一个模拟请求的测试客户端(URL路由,中间件,视图加载,模板处理等)。
使用TestCase
应该忠实地测试所有逻辑和数据库交互,但是如果supervisor,nginx,uwsgi,django app正常运行,它仍然存在差距。当您使用TestCase进行广泛覆盖时,简单的集成/冒烟测试应足以验证上述服务是否可以正确通信。即提起堆栈,点击将测试的状态页面 - &gt;主管 - &gt; Nginx - &gt; uwsgi - &gt; django - &gt; DB - &gt;退出。
纯功能测试有很多选项,但是为什么在django为您提供以可靠,快速,易用的方式验证应用程序的工具时,可以在片状,及时维护级别进行测试?
如果您需要服务器可供浏览器用于基于浏览器的测试,则django提供LiveServerTestCase
如果您需要编写广泛的功能测试,我已经在将fixutre创建方法公开为API方法方面取得了巨大成功。这样你的测试就会被执行一个堆栈,一个任意的堆栈,在这种情况下,它将针对你在本地启动的测试堆栈,但由于测试是独立的,它们可以针对QA或staging或甚至prod堆栈执行。