I'm working on internationalizing a Python tool.
Following Python's docs, I initialize gettext at startup as such:
trans = gettext.translation(domain, 'locale', fallback=True)
trans.install('gettext')
And changed logging calls from:
logger.debug('message')
to:
logger.debug(gettext('message'))
The issue is as follows. Since my unit tests run against individual methods/functions, gettext hasn't been installed, and gettext() isn't available. We get an error like this:
> logger.debug(gettext('message'))
E NameError: name 'gettext' is not defined
How does one test code internationalized with Python's gettext module?
You could write a custom fixture that will mimic the l10n installation in the test suite.
I have tried to recreate your issue in a module named spam.py:
# spam.py
import logging
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger(__name__)
def eggs():
LOGGER.info(gettext('message'))
if __name__ == '__main__':
import gettext as g
trans = g.translation('spam', 'locale', fallback=True)
trans.install('gettext')
eggs()
Running the program yields as expected:
$ python spam.py
INFO:__main__:message
Now here's a test for spam.eggs:
# test_spam.py
import spam
def test_eggs(caplog):
spam.eggs()
assert len(caplog.records) == 1
The test fails as expected:
$ pytest test_spam.py
================================ test session starts ==============================
platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0
rootdir: /Users/hoefling/projects/private/stackoverflow/so-48195889, inifile:
plugins: forked-0.2, xdist-1.20.1, mock-1.6.3, hypothesis-3.44.4
collected 1 item
test_spam.py F [100%]
==================================== FAILURES =====================================
____________________________________ test_eggs ____________________________________
caplog = <_pytest.logging.LogCaptureFixture object at 0x1056ba0b8>
def test_eggs(caplog):
> spam.eggs()
test_spam.py:4:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def eggs():
> LOGGER.info(gettext('message'))
E NameError: name 'gettext' is not defined
spam.py:9: NameError
============================ 1 failed in 0.07 seconds =============================
In the root dir, create a conftest.py. In there, implement a fixture that will automatically run once when a test session starts:
# conftest.py
import pytest
@pytest.fixture(scope='session', autouse=True)
def install_l10n():
import gettext as g
trans = g.translation('spam', 'locale', fallback=True)
trans.install('gettext')
The test will pass now:
$ pytest test_spam.py
================================ test session starts ==============================
platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0
rootdir: /Users/hoefling/projects/private/stackoverflow/so-48195889, inifile:
plugins: forked-0.2, xdist-1.20.1, mock-1.6.3, hypothesis-3.44.4
collected 1 item
test_spam.py . [100%]
============================ 1 passed in 0.01 seconds =============================
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