使用Django TestCase网址的py.test -n

时间:2012-06-11 12:01:33

标签: django unit-testing pytest

要在Django测试中使用特定的url-config,您只需指定它:

class MyTests(TestCase):
    urls = 'myproj.myapp.urls'

    def test_myurl(self):
        r = self.client.get('/foo/')  # looks up /foo/ in myproj/myapp/urls.py

然而,实现看起来并不是线程安全的:

def _urlconf_setup(self):
    if hasattr(self, 'urls'):
        self._old_root_urlconf = settings.ROOT_URLCONF
        settings.ROOT_URLCONF = self.urls
        clear_url_caches()

我在使用py.test -n8(使用全部8个cpus)运行测试套件后,在测试日志中看到404错误。

还有其他人看到/解决了这个问题吗?

3 个答案:

答案 0 :(得分:2)

py.test -n8调用将启动8个子进程。是否可能存在启动8个django服务器并通过self.client(...)访问它们的问题,即每个服务器使用的固定默认端口?

更新:此外,您可能需要安装pytest-django plugin,看看它是否有助于您使用-n 8运行测试。

答案 1 :(得分:1)

我想知道您使用的默认测试数据库是否可以保存,以便同时使用N个测试进程

答案 2 :(得分:1)

简短回答:在urls子类上设置TestCase在调用from py.test -n时不是线程安全的,可能是因为不同的线程正在破坏settings.ROOT_URLCONF

django/core/handlers/base.py:get_response()中有代码(我刚刚检查了最新版本),它会从请求对象中获取urlconf(如果存在),而不是使用settings.ROOT_URLCONF

然后,解决方案是将self.urls的值附加到request传递给视图函数的Client.py对象。实施此修复程序后,我们没有看到任何问题,使用-n8运行1100多个测试。

(如果您已拥有自己的client.pytestcases.py副本,则从_pre_setup移除当前的urlconf机制相对容易(~14 loc),而是通过{{ 1}}通过客户端,以便ClientHandler可以在调用self.urls之前将其附加到request。)