【问题标题】:How to disable translations during unit tests in django?如何在 django 的单元测试期间禁用翻译?
【发布时间】:2012-06-06 01:16:29
【问题描述】:

我正在使用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.")

【问题讨论】:

    标签: python django unit-testing


    【解决方案1】:

    在测试客户端调用.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 或更早版本以来几乎没有变化):

    【讨论】:

      【解决方案2】:

      我用方法 4 解决了同样的问题。来自@Denilson Sá 的回答。事实证明,这不需要任何特定于测试的设置文件,并且可以使用 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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • 这可能是个好主意,您对如何实现这一点有什么建议吗?
        • 仅供参考,您的回答不起作用,原因我在自己的回答中已经解释过了。不错的尝试,但它根本不起作用。
        • 谢谢,帮我测试了我的观点,我刚刚将本地化设置为“en”,一切顺利:)
        猜你喜欢
        • 2014-02-24
        • 1970-01-01
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        • 2013-08-04
        • 2018-04-21
        • 1970-01-01
        • 2011-12-01
        相关资源
        最近更新 更多