I'm using Django Internationalization tools to translate some strings from my application. The code looks like this:
from django.utils.translation import ugettext as _
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
Then, I'm writing unit tests using the Django test client. These tests make a request to the view and compare the returned contents.
How can I disable the translations while running the unit tests? I'm aiming to do this:
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.")
Calling .get()
or .post()
on the test client will run all the configured middlewares. This means it will also run LocaleMiddleware
, which will call translation.get_language_from_request()
followed by translation.activate(language)
.
What this means is that the currently active language is ignored and thrown away when writing tests using the test client. In other words, the following code does not work:
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")
There a few solutions:
HTTP_ACCEPT_LANGUAGE
header.settings.LANGUAGE_CODE
Source (from Django 1.4, but it is mostly unchanged since 1.1 or earlier):
django.utils.translation.get_language_from_request()
django.middleware.locale.LocaleMiddleware.process_request()
I solved this same issue with approach number 4. from @Denilson Sá's answer. It turns out this does not require any test-specific settings file and can be defined on a per-test basis with a decorator or context manager provided by django (see overriding settings).
It can be used like this:
from django.test import TestCase, override_settings
class MyTest(TestCase):
@override_settings(LANGUAGE_CODE='en-US', LANGUAGES=(('en', 'English'),))
def test_mypage(self):
// ...
The decorator can also be applied to the entire TestCase subclass, or for even more fine-grained control there is also a context manager (see the docs linked above).
Being this rather common for me, I also defined:
english = override_settings(
LANGUAGE_CODE='en-US',
LANGUAGES=(('en', 'English'),),
)
So that now I can simply use @english
on the test cases requiring it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With