2011-11-14 2 views
3

Doctestで実行されているかどうかを(Python 2.7)コードで認識させるにはどうすればよいですか?doctestでコードが実行されているかどうかを調べる方法は?

次のようなシナリオがある:私は、print()のいくつかの出力引数として渡されたファイル記述子にすることを、このような機能を持っている:

from __future__ import print_function 

def printing_func(inarg, file=sys.stdout): 
    # (do some stuff...) 
    print(result, file=file) 

をしかし、私はdoctestの中でprinting_func()を使用しようとすると、 、テストは失敗します。 print()を呼び出すときにキーワード引数fileが指定されているため、doctestモジュールによってデフォルトの出力リダイレクトが設定されているのではなく、実際に出力はsys.stdoutになります。

それはprint()を呼び出すときfileキーワード引数を渡すことがない知っているように、どのように私は、それはdoctestの内部で実行されているかどうかprinting_func()に認識させることができますか?

答えて

1

私はdoctest.pyを読んだ後に答えを見つけました。後継のためにここに投稿します...

Doctestは、新しいファイル記述子をsys.stdoutに割り当てて標準出力をリダイレクトします。問題は、私の関数の記述がdoctestの再定義の前に元のsys.stdoutファイル記述子の値をクローズしていたことでした。

代わりに、私は次の操作を実行した場合:

def printing_func(inarg, file=None): 
    # (do some stuff...) 

    if file is None: 
     file = sys.stdout 

    print(result, file=file) 

はその後printing_func()ではなくsys.stdoutよりsysモジュールをキャプチャし、それが実行されるときには、テスト内で実行している場合のdoctestのはsysからstdout属性を再定義取得します。

EDIT:これはまた、我々はdoctestの内部で実行されているかどうかをチェックするための簡単な方法が得られます。

def inside_doctest(original_stdout=sys.stdout): 
    return original_stdout != sys.stdout 
+0

これは、あなたがdoctestの中にいるかどうかを判断しようとするよりはるかに良い計画です。 –

+0

私はRaymondに同意します。システムにコードを追加してテストされているかどうかをチェックし、それが異なる動作をするという考えは、テスト方法には絶対に理想的ではありません。 – Ben

+0

私は一般的に同意しますが、テストインフラストラクチャをサポートするためにのみ行うのであれば有害ではないと思います。 – mshroyer

0

私があなたに伝えるためにどのような方法を知らないのdoctestのの短いにしていますスタックフレームの検査。

0

FWIW(と遅くて重複していると申し訳ありませんが)多くの開発者は、 "if test"を反パターンとみなしています。

I.e.テスト中のコードが「実際に」実行されているときとは異なるテストをしている場合は、問題を尋ねています。あなたが正当な理由でそれをやっていると信じても。したがって、上記のコメントはあなたの解決策を賞賛しますが、それはそうしません。 "if test"パターンを使用するように誘惑されたとき、私は物をリファクタリングするようにしますので、必要ありません。

1

ニテンのバージョンinside_doctestは広すぎます。ログのために、あるいはdoctest以外のフレームワークでテストするときにsys.stdoutを再定義するのは珍しいことではありませんので、誤検出が起こります。

狭いテストでは、次のようになります。_SpoofOutクラスdoctestのため

import sys 

def in_doctest(): 
    return hasattr(sys.modules['__main__'], '_SpoofOut') 

def test(): 
    """ 
    >>> print 'inside comments, running in doctest?', in_doctest() 
    inside comments, running in doctest? True 
    """ 
    print 'outside comments, running in doctest?', in_doctest() 

if __name__ == '__main__': 
    test() 

in_doctestテストがsys.stdoutを交換するために使用しています。同じ方法で検証できるdoctestモジュールの他の属性があります。別のモジュールが名前を再利用するのを防ぐことはできませんが、この名前は一般的ではないので、これはまあまあのテストです。

上記をtest.pyに入れてください。非doctestのモードでそれを実行して、python test.py利回り:

doctestの冗長モードで実行されている

python -m doctest test.py -v利回り:doctestのに気づいてコードを作ることは一般的に悪い私は他の人のコメントに同意

Trying: 
    print 'inside comments, running in doctest?', in_doctest() 
Expecting: 
    inside comments, running in doctest? True 
ok 

であることアイディア。コードジェネレータを使用してテストケースを作成する必要があるとき、効率的に手作業を行うには余りにも多くのものがあったので、私は幾分異国的な状況でしか行っていませんでした。しかし、あなたがそれを行う必要がある場合、上記はそれのためのまともなテストです。

関連する問題