4

次の(ナンセンスな)Pythonモジュールのdoctestは失敗します:

"""
>>> L = []
>>> if True:
...    append_to(L) # XXX
>>> L
[1]
"""

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

import doctest; doctest.testmod()

これは、XXXとマークされた行の後の出力が<__main__.A object at ...>(によって返されるappend_to)であるためです。もちろん、この出力をXXXとマークされた行の直後に置くこともできますが、私の場合、これは実際にテストされるもの、つまり関数の副作用から読者の注意をそらしますappend_to。では、どうすればその出力を抑制できますか、またはどうすれば無視できますか。私はそれを試しました:

"""
>>> L = []
>>> if True:
...    append_to(L) # doctest: +ELLIPSIS
    ...
>>> L
[1]
"""

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

import doctest; doctest.testmod()

ただし、これによりValueError: line 4 of the docstring for __main__ has inconsistent leading whitespace: ' ...'

doctestは文書化を目的としており、モジュールがどのように使用されるかを読者に示すため、私がしたくないのは、出力を抑制するappend_to(L)ような行に変更することです。_ = append_to(L)(文書化されている場合はappend_to、関数のようではなく、ステートメントのように使用する必要があります。書く_ = append_to(L)と、読者はこれから逸脱します。)

4

3 に答える 3

7

書き換え:これは実際に機能します。以前書いた "doctest" が実際にはモジュールの docstring として解析されていないことに気付きました。

私はこれを再確認するようにしました。

__doc__ = """
>>> L = []
>>> if True:
...    append_to(L) # doctest: +IGNORE_RESULT
>>> L
[1]
""".replace('+IGNORE_RESULT', '+ELLIPSIS\n<...>')

def append_to(L):
    L.append(1)
    class A(object):
        pass
    return A()

これが読みやすいかどうかはわかりません。について特別なことは何もないことに注意してください<...>: この場合のように、実際の戻り値がその形式を持っている場合にのみ機能します (つまり、それは<module.A object at 0x...>です)。ELLIPSIS オプションを使用すると、 「実際の出力の任意の部分文字列...に一致」 ¹します。したがって、出力全体と一致させる方法はないと思います。

更新:これを「適切な」方法で行うには、 、 subclass を呼び出しdoctest.register_optionflag('IGNORE_RESULT')doctest.OptionCheckerそのサブクラスのインスタンスが doctest で使用されるように手配する必要があるようです。おそらく、これは doctest を実行$ python -m doctest your_module.pyするオプションがないことを意味します。

于 2010-10-05T10:35:54.407 に答える
-2

完全に自己完結型の実行可能なコードを提供するようにしてください。問題をデモンストレーションしている場合でも、コードを単独で実行して問題を再現する必要があります。これにより、ソリューションはコードを直接コピーして、答えをデモンストレーションできます。

私はこれに対するきれいな解決策を知りません、そして私は前にそれを打ちました。doctestsが提供するあいまいな(より率直に言って:ずさんな)テスト定義の副作用のようです。回避策は、doctest内で関数を定義できることを覚えておくことです。これにより、テスト全体を、個々のステートメントとしてではなく、単一の関数として含めることができます。

def append_to(l):
    """
    >>> L = []
    >>> def test():
    ...     if True:
    ...         append_to(L) # XXX
    >>> test()
    >>> L
    [1]

    >>> def test():
    ...     L = []
    ...     if True:
    ...         append_to(L) # XXX
    ...     return L
    >>> test()
    [1]

    """
    l.append(1)
    return object()

if __name__ == "__main__":
    import doctest
    doctest.testmod()
于 2010-10-05T09:47:02.740 に答える