如何在django的单元测试中禁用翻译?

时间:2012-05-31 18:44:28

标签: python django unit-testing

我使用Django Internationalization工具从我的应用程序中翻译某些字符串。代码如下所示:

from django.utils.translation import ugettext as _
def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

然后,我使用Django test client编写单元测试。这些测试向视图发出请求并比较返回的内容。

如何在运行单元测试时禁用翻译?我打算这样做:

class FoobarTestCase(unittest.TestCase):
    def setUp(self):
        # Do something here to disable the string translation. But what?
        # I've already tried this, but it didn't work:
        django.utils.translation.deactivate_all()
    def testFoobar(self):
        c = Client()
        response = c.get("/foobar")
        # I want to compare to the original string without translations.
        self.assertEquals(response.content.strip(), "Welcome to my site.")

3 个答案:

答案 0 :(得分:11)

在测试客户端上调用.get().post()将运行所有已配置的中间件。这意味着它还会运行LocaleMiddleware,它会调用translation.get_language_from_request(),然后调用translation.activate(language)

这意味着当使用测试客户端编写测试时,将忽略当前活动的语言并将其丢弃。换句话说,以下代码不起作用:

def testFoobar(self):
    c = Client()
    # This will not work.
    translation.deactivate_all()
    # This will not work either.
    translation.activate('en-us')
    # The next call will override the earlier activate/deactivate calls.
    response = c.get("/foobar")

有几个解决方案:

  1. 在会话对象中设置所需的语言。
  2. 在Cookie中设置所需的语言。
  3. 发送HTTP_ACCEPT_LANGUAGE标题。
  4. 设置settings.LANGUAGE_CODE
  5. 来源(来自Django 1.4,但自1.1或更早以来它基本没有变化):

答案 1 :(得分:5)

我从@DenilsonSá的回答中用第4号方法解决了同样的问题。事实证明,这不需要任何特定于测试的设置文件,并且可以使用django提供的装饰器或上下文管理器在每个测试的基础上进行定义(参见overriding settings)。

可以像这样使用:

from django.test import TestCase, override_settings

class MyTest(TestCase):
    @override_settings(LANGUAGE_CODE='en-US', LANGUAGES=(('en', 'English'),))
    def test_mypage(self):
        // ...

装饰器也可以应用于整个TestCase子类,或者对于更细粒度的控制,还有一个上下文管理器(参见上面链接的文档)。

这对我来说相当普遍,我也定义了:

english = override_settings(
    LANGUAGE_CODE='en-US',
    LANGUAGES=(('en', 'English'),),
)

现在我可以在需要它的测试用例上使用@english

答案 2 :(得分:1)

我认为将语言强制为单元测试的已知设置会更有意义。这意味着您正在测试更接近真实实现的内容。

要激活特定语言,您可以在设置中执行此操作:

from django.utils.translation import activate
...
activate('en-en')