代码之家  ›  专栏  ›  技术社区  ›  kjo

如何用doctest测试嵌套/重新引发的异常?

  •  1
  • kjo  · 技术社区  · 7 年前

    以下玩具脚本说明了问题:

    #!/usr/bin/env python3
    
    def bomb():
        """
        >>> bomb()
        Traceback (most recent call last):
          File "<string>", line 18, in bomb
        ZeroDivisionError: division by zero
        <BLANKLINE>
        During handling of the above exception, another exception occurred:
        <BLANKLINE>
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "<string>", line 20, in bomb
        Exception: re-raised
        """
        try:
            1/0
        except Exception as exception:
            raise Exception('re-raised')
    
    if __name__ == '__main__' and '__file__' in globals():
        import sys
        if len(sys.argv) > 1 and sys.argv[1] == '-t':
            import doctest
            doctest.testmod()
        else:
            bomb()
    

    bomb() 在python解释器中,我得到docstring指定的输出:

    % python3
    Python 3.5.1 (default, May 24 2016, 20:04:39)
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> exec(open('demo.py').read())
    >>> bomb()
    Traceback (most recent call last):
      File "<string>", line 18, in bomb
    ZeroDivisionError: division by zero
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 20, in bomb
    Exception: re-raised
    >>>
    

    doctest 但是,错误地报告故障:

    **********************************************************************
    File "./demo.py", line 5, in __main__.bomb
    Failed example:
        bomb()
    Expected:
        Traceback (most recent call last):
          File "<string>", line 16, in bomb
        ZeroDivisionError: division by zero
        <BLANKLINE>
        During handling of the above exception, another exception occurred:
        <BLANKLINE>
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "<string>", line 18, in bomb
        Exception: re-raised
    Got:
        Traceback (most recent call last):
          File "./demo.py", line 18, in bomb
            1/0
        ZeroDivisionError: division by zero
        <BLANKLINE>
        During handling of the above exception, another exception occurred:
        <BLANKLINE>
        Traceback (most recent call last):
          File "/usr/lib/python3.5/doctest.py", line 1320, in __run
            compileflags, 1), test.globs)
          File "<doctest __main__.bomb[0]>", line 1, in <module>
            bomb()
          File "./demo.py", line 20, in bomb
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   eldipa    7 年前

    问题是医生如何在内部工作。基本上,它在同一个python解释器中加载、编译和评估python片段。

    # Don't blink!  This is where the user's code gets run.
    exec(compile(example.source, filename, "single",
         compileflags, 1), test.globs)
    

    当执行的代码引发和异常时,回溯包含doctest引擎的堆栈框架的一部分,使其不同于预期。

    doctest documentation

    回溯头后面跟着一个可选的回溯堆栈,其

    仅适用于单一例外情况 thread .

    byexample . 它有一个 compatibility mode with doctest 所以你不必重写所有的东西。

    免责声明: 我是 以身作则 . 正如我在这篇文章中所解释的 以身作则 可以填补空白,对其他人有用。

    推荐文章