【问题标题】:Multi version support for Python doctests对 Python 文档测试的多版本支持
【发布时间】:2012-11-20 13:12:53
【问题描述】:

我正在这样写我的文档测试:

>>> some_function(a=1, b=2)
{u'id': u'123', u'name': u'abc'}

这适用于 Python 版本 2.5、2.6 和 2.7,但对于 Python 3 失败并出现以下错误:

Expected:
    {u'id': u'123', u'name': u'abc'}
Got:
    {'id': '123', 'name': 'abc'}

问题是如果我这样写我的文档测试:

>>> some_function(a=1, b=2)
{'id': '123', 'name': 'abc'}

它们仅适用于 Python3,在 Python2 版本上失败。我的问题是如何让它跨版本兼容?

【问题讨论】:

  • 您必须使用与使您的代码在 Python 2.x 和 3.x 中都能工作的相同技术。那会变得丑陋,快速。就个人而言,我会坚持使用 unittests 而不是 doctests,并使用 Sphinx 作为 API 文档。
  • 我确实使用 unittest 进行测试,这只是为了验证示例。
  • 你试过 Python 3.3 吗? 3.3 重新引入了 u"" 语法 (docs.python.org/3/whatsnew/3.3.html)。不知道这个改动会不会影响到doctest,但是值得一试。
  • @codeape:您可以使用u''指定文字,但repr(somestring) 不会使用它们,因此测试仍然会失败。将其与使用 r'' 原始 python 文字进行比较; r 也将从表示中删除。
  • 好的,我明白了。我想用 doctests 做到这一点的唯一方法就是重写测试。例如>>> result = some_function(a=1, b=2) >>> print(result["id"])

标签: python python-3.x doctest


【解决方案1】:

我在 IPython 中遇到了与 doctests 相同的问题。没有简洁的解决方案,但我将所有 u' 前缀包装在 {} 中,即 {u}',并制作了一个小函数,可以根据需要包含或排除它们。

你可以看到the u_format() functiona doctest using it

但这相当混乱,所以我将许多测试从 doctest 中移出。

或者,您可以像这样测试它:

>>> some_function(a=1, b=2) == {'id': '123', 'name': 'abc'}
True

如果你需要一些 unicode 字符串,你可以使用u'abþ',并使用distribute 在doctests 上运行2to3。但这仅适用于输入代码,不适用于输出 reprs。

【讨论】:

    【解决方案2】:

    如果你使用 pytest,你可以这样做:

    >>> some_function(a=1, b=2) # doctest: +ALLOW_UNICODE
    {u'id': u'123', u'name': u'abc'}
    

    如果您运行的是 Python 3,u 将被剥离,并保留在 Python 2 中。

    【讨论】:

    【解决方案3】:

    我在 NLTK 中遇到了与 doctests 相同的问题;它是通过使用由自定义鼻子插件安装的自定义 doctest 输出检查器(将 u'foo' 和 'foo' 视为相同)解决的:https://github.com/nltk/nltk/blob/develop/nltk/test/doctest_nose_plugin.py

    这个解决方案并不漂亮,但效果很好(NLTK 中有大约 0.5 兆字节的文档测试),并且不会降低文档测试的可读性。

    编辑:找到了这个鼻子插件的简化独立版本:https://github.com/gnublade/doctest-ignore-unicode

    【讨论】:

    • 鼻子插件链接现在是404。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 2019-02-06
    • 1970-01-01
    • 2015-01-22
    相关资源
    最近更新 更多