Python Doctests optionflags在Python2下工作,但不在Python3下工作

时间:2014-11-25 00:25:49

标签: python python-3.x python-2.x doctest

我有一个特殊的Doctest在python 2.7中正常工作,但在python 3.4中没有。

"""
Trying to build a cyclic network (should fail):

    >>> buildCyclicNetwork(False)
    Traceback (most recent call last):
        ...
    NetworkConstructionException: Loop in network graph.
"""

if __name__ == "__main__":
    runModuleTestSuite(__import__('__main__'))

此处编译了测试套件,其中包含选项

def runModuleTestSuite(module):
    """Runs a test suite for all local tests."""
    suite = TestSuite([TestLoader().loadTestsFromModule(module)])

    # Add local doctests
    optionflags = ELLIPSIS | NORMALIZE_WHITESPACE | REPORT_ONLY_FIRST_FAILURE 

    try:
        suite.addTest(DocTestSuite(module, optionflags=optionflags))
    except ValueError:
        # No tests have been found in that module.
        pass

    TextTestRunner().run(suite)

我尝试在docstring本身使用#doctest:+ ELLIPSIS,但这并没有解决任何问题。我很疑惑为什么它在2.x但不是3.x下工作。这里的特殊问题是在回溯中消除路径的省略号。当测试失败时,输出:

Expected:
   Traceback (most recent call last):
      ...
   NetworkConstructionException: Loop in network graph.
Got:
   Traceback (most recent call last):
   File "/usr......complete trace path"
   networks.network.NetworkConstructionException: Loop in network graph.

2 个答案:

答案 0 :(得分:0)

您需要启用IGNORE_EXCEPTION_DETAIL标志。现在,由于异常名称前面的networks.network.垃圾,异常无法匹配。

答案 1 :(得分:0)

文档中对此进行了介绍。虽然ELLIPSIS文档没有直接解释,但IGNORE_EXCEPTION_DETAIL的下一部分说:

  

它还将忽略Python 3 doctest报告中使用的模块名称。因此,无论测试是在Python 2.7还是Python 3.2(或更高版本)下运行,这两种变体都可以使用指定的标志...

     

请注意,ELLIPSIS也可用于忽略异常消息的详细信息,但根据模块详细信息是否作为异常名称的一部分打印,此类测试可能仍会失败。使用IGNORE_EXCEPTION_DETAIL和Python 2.3中的详细信息也是编写doctest的唯一明确方法,该doctest不关心异常细节但仍在Python 2.3或更早版本下传递(这些版本不支持doctest指令并忽略他们作为无关的评论)。

换句话说,问题是...不会跳过3.x追溯打印出的networks.network.部分,这是doctest中的已知限制,并且&# 39;如果没有使用IGNORE_EXCEPTION_DETAIL而没有办法解决问题。

如果要检查的只是类型,这实际上更好 - 它更简单,更易读,更难出错。但是,如果要检查异常值,而不仅仅是类型,该怎么办?有一些hacky变通方法可以做到这一点(例如,用一个调用builtins.isinstance的函数替换__instancehook__,这样你就可以定义一个仅当值匹配时才是超类的类,但是我不知道认为这些值得做。如果你真的需要区分一个特定的例外,它首先应该是一个独特的子类型。