为django的内置测试工具填充db数据

时间:2016-12-27 14:47:44

标签: django unit-testing

我正在使用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我可以看到几个选项:

  1. 以某种方式强制TestCase将数据提交到db。
  2. 用其他方法填充数据(但是哪些?)。
  3. 使用不同的测试库。
  4. 你能帮忙吗?

2 个答案:

答案 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...'

最重要的是,该文档详细解释了如何执行GETPOST请求以及如何测试视图的响应等。希望这是有道理的。

答案 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堆栈执行。