unittest.main
ドキュメントによると、呼び出し時にpythonユニットテストの詳細レベルを設定できます。
unittest.main(verbosity=2)
内でこの情報にアクセスするにはどうすればよいunittest.TestCase
ですか?
unittest.main
ドキュメントによると、呼び出し時にpythonユニットテストの詳細レベルを設定できます。
unittest.main(verbosity=2)
内でこの情報にアクセスするにはどうすればよいunittest.TestCase
ですか?
パッチ適用またはサブクラス化に基づく方法の問題点は、開始unittest.TestProgram
する前にパッチを適用する必要があることですunittest.TestProgram
。しかし、テスト ケースがディスカバリーによって実行されている場合、それは不可能です。
python -m unittest discover -v
発見のケースで機能するアプローチは、モジュールを使用して、メソッドが見つかるinspect
までスタックを検索することです。unittest.TestProgram
import inspect
import unittest
def unittest_verbosity():
"""Return the verbosity setting of the currently running unittest
program, or 0 if none is running.
"""
frame = inspect.currentframe()
while frame:
self = frame.f_locals.get('self')
if isinstance(self, unittest.TestProgram):
return self.verbosity
frame = frame.f_back
return 0
これを実現する方法は、ファイルをサブクラスunittest.TestCase
化することです。ここでは、グローバルに、またはクラスまたはシングルトンとして使用できるunittest.main
変数 (例: ) を定義し、オーバーライドします。globalverb
unittest.main
def main(*args, **kwargs):
# parse arguments etc to get the verbosity number or whatever
# ...
# set this number to the defined class
globalverb = verbose_number
return unittest.main(*args, **kwargs)
後で、サブクラス化しますunittest.TestCase
:
class MyTestCase(unittest.TestCase):
def my_special_function(self):
if globalverb ...
このアプローチを使用すると、ユニットテストに渡された引数から、(派生した) TestCase で verbose、verbosity、またはその他の数値と情報を使用できます。
コメント歓迎。
Martjin Pieters のソリューションを機能させることができませんでした。結果がグローバルに割り当てられる前に、初期化時に unittest.main がテストを実行するためだと思います。
代わりに、初期化を次のように置き換えました。
def new_parseArgs (自己、argv): グローバルな old_parseArgs,verbosity old_parseArgs(self, argv) verbosity = self.verbosity __name__ == '__main__' の場合: # monkeypatch unittest.TestProgram.parseArgs() で冗長性を節約 # グローバル変数で old_parseArgs = unittest.TestProgram.parseArgs unittest.TestProgram.parseArgs = new_parseArgs unittest.main()
冗長性を知る必要があるテスト ケースでは、次のようなものを使用します。
グローバル冗長性 ... 詳細度 >= 2 の場合: print("キーの順序: %s" % dd.keys())
私の解決策はかなり異なっていました。モンキーパッチを適用する代わりに、すべてのテストが特別に細工された起動スクリプトを介してトリガーされることを利用しました。さまざまな構成変数とセットアップ環境を収集するため、エクスポートを 1 つ追加するだけで済みます。
より一般的なケースでは、テストを直接実行するのではなく、test-runner.sh (または何でも) を作成して、まったく同じシェル呼び出しを行いますが、追加のエクスポートをプレフィックスとして使用するのが賢明な解決策かもしれません。
1 枚の写真は何千もの言葉に値するからです。
これは私のテストランナーです:
#!/usr/bin/env bash
VERBOSE=false
while getopts ":vt:" opt; do
case $opt in
t)
TEST_TO_RUN=$OPTARG
;;
v)
VERBOSE=true
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
ENVS=""
ENVS+=" PYTHONPATH=$PYTHONPATH:$PWD"
PARAMS=""
PARAMS+=" -s --nologcapture --with-id"
PARAMS+=" --cov-config=.apirc --cov-report html --with-cov"
SERVER_PRIMER="coverage run --rcfile=.apirc"
if [[ ! -z "$TEST_TO_RUN" ]]; then
PARAMS+=" $TEST_TO_RUN"
fi
if [[ "$VERBOSE" = true ]]; then
PARAMS+=" -v"
ENVS+=" TEST_VERBOSITY=2"
fi
eval "$ENVS nosetests $PARAMS"
RESULT_TEST=$?
そして、私は単体テストでこのメソッドを持っています:
@property
def verbosity(self):
return int(os.environ.get('TEST_VERBOSITY', 0))
スタックを登り、unittest.main( ) によって作成された「TestProgram」インスタンスを見つけ、verbosity フィールドにアクセスします。
class MyTestCase(unittest.TestCase):
def test_verbosity(self):
"""Return current verbosity"""
for f in inspect.getouterframes(inspect.currentframe() ):
args, _,_, local_dict = inspect.getargvalues(f[0])
if args:
first_arg = args[0]
first_value = local_dict[first_arg]
if type(first_value).__name__ == "TestProgram":
return first_value.verbosity