【问题标题】:Test exception chaining and traceback output with doctest使用 doctest 测试异常链接和回溯输出
【发布时间】:2018-11-23 15:30:21
【问题描述】:

如何使用 doctest 测试“多重回溯”? 似乎使用多个ELLIPSIS<BLANKLINE> 并不能解决问题:

def myfunc():
    """

    >>> myfunc()
    Traceback (most recent call last):
     ...
    ValueError: this is
    <BLANKLINE>
    The above exception was the direct cause of the following exception:
    <BLANKLINE>
    Traceback (most recent call last):
     ...
    TypeError: it

    """
    try:
        raise ValueError('this is')
    except ValueError as err:
        raise TypeError('it') from err


import doctest
doctest.testmod(optionflags=doctest.REPORT_NDIFF|doctest.ELLIPSIS)

结果:

"test.py" 23L, 490C written
**********************************************************************
File "test.py", line 4, in __main__.myfunc
Failed example:
    myfunc()
Differences (ndiff with -expected +actual):
      Traceback (most recent call last):
    -  ...
    +   File "test.py", line 17, in myfunc
    +     raise ValueError('this is')
      ValueError: this is
      <BLANKLINE>
      The above exception was the direct cause of the following exception:
      <BLANKLINE>
      Traceback (most recent call last):
    -  ...
    +   File "/usr/lib/python3.7/doctest.py", line 1329, in __run
    +     compileflags, 1), test.globs)
    +   File "<doctest __main__.myfunc[0]>", line 1, in <module>
    +     myfunc()
    +   File "test.py", line 19, in myfunc
    +     raise TypeError('it') from err
      TypeError: it
**********************************************************************
1 items had failures:
   1 of   1 in __main__.myfunc
***Test Failed*** 1 failures.

但如果我把所有东西都压扁了,它会过去的:

>>> myfunc()
Traceback (most recent call last):
 ...
TypeError: it

【问题讨论】:

    标签: python doctest


    【解决方案1】:

    恐怕不能以这种方式检查“多追溯”。

    问题在于 doctest 忽略了除异常类及其消息之外的所有内容。

    在您的示例中,它将是:

    TypeError: it
    

    如果您对它的工作原理感兴趣,请查看 doctest.py 并搜索

    exc_msg = traceback.format_exception_only(*exception[:2])[-1]
    

    “exc_msg”将只包含引发异常的详细信息:

    TypeError: it
    

    替代方案

    如果可能,您可以将测试更改为不引发任何异常,而是打印想要的消息。

    另一种可能性是使用另一个“doctest 引擎”,例如byexample。它的工作方式与 doctest 相同,但更灵活 (quick overview here)。

    如果您有很多测试,您可能想尝试its compatibility mode with doctest 以避免重写所有内容。

    对于你的例子,这应该是:

    """                                                                                                                            
    >>> from your_module import myfunc                                                                                             
    """                                                                                                                            
    
    def myfunc():                                                                                                                  
        """                                                                                                                        
    
        >>> myfunc()                                                                                                               
        Traceback (most recent call last):                                                                                         
         ...                                                                                                                       
        ValueError: this is                                                                                                        
        <BLANKLINE>                                                                                                                
        The above exception was the direct cause of the following exception:                                                       
        <BLANKLINE>                                                                                                                
        Traceback (most recent call last):                                                                                         
         ...                                                                                                                       
        TypeError: it                                                                                                              
    
        """                                                                                                                        
        try:                                                                                                                       
            raise ValueError('this is')                                                                                            
        except ValueError as err:                                                                                                  
            raise TypeError('it') from err
    

    要从 shell 运行它:

    byexample -l python -o '+py-doctest -py-pretty-print +ELLIPSIS' your_module.py
    

    免责声明:我是byexample 的作者。我是 doctest 的真正粉丝,但我知道它有其局限性,检查异常就是其中之一(特别是如果您在双 Python 2.x / 3.x 项目中工作)。

    出于这个原因,我创建了byexample:它对我非常有用,我真的希望它对其他人有用。

    如有任何问题,请在此处或githubgithub

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      相关资源
      最近更新 更多