11

我正在使用Django 国际化工具从我的应用程序中翻译一些字符串。代码如下所示:

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

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

如何在运行单元测试时禁用翻译?我的目标是这样做:

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.")
4

3 回答 3

13

在测试客户端上调用.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

来源(来自 Django 1.4,但自 1.1 或更早版本以来几乎没有变化):

于 2012-06-04T16:37:20.143 回答
8

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

它可以这样使用:

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在需要它的测试用例上使用。

于 2016-01-10T06:58:08.137 回答
1

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

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

from django.utils.translation import activate
...
activate('en-en')
于 2012-05-31T18:51:29.737 回答