gettext 中断 pytest 测试

gettext breaks pytest tests

我正在努力使 Python 工具国际化。

根据 Python 的文档,我在启动时将 gettext 初始化为:

trans = gettext.translation(domain, 'locale', fallback=True)
trans.install('gettext')

并更改了记录调用:

logger.debug('message')

至:

logger.debug(gettext('message'))

问题如下。由于我的单元测试 运行 针对个人 methods/functions,gettext 尚未安装,并且 gettext() 不可用。我们收到这样的错误:

>       logger.debug(gettext('message'))
E       NameError: name 'gettext' is not defined

一个测试代码如何使用 Python 的 gettext 模块国际化?

您可以编写一个自定义装置来模拟测试套件中的 l10n 安装。

例子

我已尝试在名为 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()

运行 程序按预期产生:

$ python spam.py
INFO:__main__:message

下面是 spam.eggs 的测试:

# test_spam.py

import spam

def test_eggs(caplog):
    spam.eggs()
    assert len(caplog.records) == 1

测试如期失败:

$ 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/Whosebug/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 =============================

解决方案

在根目录中,创建一个conftest.py。在那里,实现一个在测试会话开始时自动 运行 一次的夹具:

# 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')

测试即将通过:

$ 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/Whosebug/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 =============================