私はPython assertステートメントを使用して、実際の動作と予想される動作を一致させています。エラーテストケースが中断するかのようにこれらを制御することはできません。アサーションエラーを制御し、失敗のアサートでテストケースを中止するかどうかを定義したい。
また、アサーションエラーが発生した場合など、テストケースを一時停止してユーザーがいつでも再開できるようにすることもできます。
私はこれを行う方法がわかりません
コード例、ここではpytestを使用しています
import pytest
def test_abc():
a = 10
assert a == 10, "some error message"
Below is my expectation
AssertがassertionErrorをスローする場合、テストケースを一時停止するオプションが必要で、デバッグして後で再開できます。一時停止と再開には、tkinter
モジュールを使用します。以下のようにアサート機能を作成します
import tkinter
import tkinter.messagebox
top = tkinter.Tk()
def _assertCustom(assert_statement, pause_on_fail = 0):
#assert_statement will be something like: assert a == 10, "Some error"
#pause_on_fail will be derived from global file where I can change it on runtime
if pause_on_fail == 1:
try:
eval(assert_statement)
except AssertionError as e:
tkinter.messagebox.showinfo(e)
eval (assert_statement)
#Above is to raise the assertion error again to fail the testcase
else:
eval (assert_statement)
今後は、この関数を使用してすべてのassertステートメントを変更する必要があります
import pytest
def test_abc():
a = 10
# Suppose some code and below is the assert statement
_assertCustom("assert a == 10, 'error message'")
アサートを使用した何千もの場所で変更を行わなければならないので、これは私にとってあまりにも多くの努力です。 pytest
でそれを行う簡単な方法はありますか
Summary:
失敗時にテストケースを一時停止し、デバッグ後に再開できるものが必要です。私はtkinter
について知っており、それが私がそれを使用した理由です。他のアイデアは歓迎されます
Note
:上記のコードはまだテストされていません。小さな構文エラーもあるかもしれません
編集:回答をありがとう。この質問を少し先に拡張します。アサートの動作を変更したい場合はどうすればよいですか。現在、アサーションエラーがある場合、テストケースが終了します。特定のアサートエラーでテストケースの終了が必要かどうかを選択したい場合はどうすればよいですか。上記のようにカスタムアサート関数を記述したくないのは、この方法で多くの場所で変更する必要があるためです。
pytest --pdb を使用すると、コードをまったく変更しなくても、希望どおりの結果を得ることができます。
あなたの例で:
import pytest
def test_abc():
a = 9
assert a == 10, "some error message"
--pdbで実行:
py.test --pdb
collected 1 item
test_abc.py F
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
def test_abc():
a = 9
> assert a == 10, "some error message"
E AssertionError: some error message
E assert 9 == 10
test_abc.py:4: AssertionError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> /private/tmp/a/test_abc.py(4)test_abc()
-> assert a == 10, "some error message"
(Pdb) p a
9
(Pdb)
テストが失敗するとすぐに、組み込みのpythonデバッガーでデバッグできます。デバッグが完了したら、残りのテストでcontinue
できます。
PyCharmを使用している場合は、例外ブレークポイントを追加して、アサートが失敗したときに実行を一時停止できます。ブレークポイントの表示(CTRL-SHIFT-F8)を選択し、AssertionErrorのオンレイズ例外ハンドラーを追加します。これにより、テストの実行が遅くなる場合があることに注意してください。
それ以外の場合、アサーションが失敗した時点ではなく、失敗した各テストの(エラーが発生する直前に)endで一時停止してもかまいません。いくつかのオプションがあります。ただし、この時点で、テストで開かれたファイルを閉じるなど、さまざまなクリーンアップコードが既に実行されている可能性があることに注意してください。可能なオプションは次のとおりです。
-pdbオプション を使用して、エラー時にデバッガーにドロップするようにpytestに指示できます。
次のデコレータを定義して、関連する各テスト関数をそれでデコレートできます。 (メッセージのロギングとは別に、この時点で pdb.post_mortem を開始することもできます。または、例外が発生したフレームのローカルでインタラクティブな code.interact を開始することもできます、 この答え で説明されているように)
from functools import wraps
def pause_on_assert(test_func):
@wraps(test_func)
def test_wrapper(*args, **kwargs):
try:
test_func(*args, **kwargs)
except AssertionError as e:
tkinter.messagebox.showinfo(e)
# re-raise exception to make the test fail
raise
return test_wrapper
@pause_on_assert
def test_abc()
a = 10
assert a == 2, "some error message"
import sys
@pytest.fixture(scope="function", autouse=True)
def pause_on_assert():
yield
if hasattr(sys, 'last_value') and isinstance(sys.last_value, AssertionError):
tkinter.messagebox.showinfo(sys.last_value)
簡単な解決策の1つは、Visual Studio Codeを使用する場合、 条件付きブレークポイント を使用することです。
これにより、たとえば次のようにアサーションを設定できます。
import pytest
def test_abc():
a = 10
assert a == 10, "some error message"
次に、アサーション行に条件付きブレークポイントを追加して、アサーションが失敗した場合にのみブレークするようにします。