そのようなsmthがあると仮定しましょう:
import py, pytest
ERROR1 = ' --- Error : value < 5! ---'
ERROR2 = ' --- Error : value > 10! ---'
class MyError(Exception):
def __init__(self, m):
self.m = m
def __str__(self):
return self.m
def foo(i):
if i < 5:
raise MyError(ERROR1)
Elif i > 10:
raise MyError(ERROR2)
return i
# ---------------------- TESTS -------------------------
def test_foo1():
with pytest.raises(MyError) as e:
foo(3)
assert ERROR1 in str(e)
def test_foo2():
with pytest.raises(MyError) as e:
foo(11)
assert ERROR2 in str(e)
def test_foo3():
....
foo(7)
....
Q:どうすればtest_foo3()をテストしてMyErrorが発生しないようにできますか?私がただテストできることは明らかです:
def test_foo3():
assert foo(7) == 7
しかし、私はpytest.raises()を介してそれをテストしたいです。とにかく可能ですか?たとえば、ある場合、その関数 "foo"には戻り値がまったくありません。
def foo(i):
if i < 5:
raise MyError(ERROR1)
Elif i > 10:
raise MyError(ERROR2)
このようにテストするのは理にかなっていると思います。
予期しない例外が発生した場合、テストは失敗します。 foo(7)を呼び出すだけで、MyErrorが発生しないことをテストできます。したがって、以下で十分です。
def test_foo3():
foo(7)
明示的になり、このためにアサートステートメントを記述したい場合は、次のことができます。
def test_foo3():
try:
foo(7)
except MyError:
pytest.fail("Unexpected MyError ..")
オイシンが述べたことの上に構築.
Pytestのraises
と同様に機能する簡単なnot_raises
関数を作成できます。
from contextlib import contextmanager
@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE {0}".format(exception))
これは、対応するraises
を持ち続けてテストを読みやすくしたい場合に適しています。ただし、本質的には、テストするコードのブロックを独自の行で実行する以外に、実際には何も必要ありません。pytestは、そのブロックでエラーが発生するとすぐに失敗します。
Not_raisesが機能するかどうかを知りたいと思いました。これの簡単なテストは(test_notraises.py)です:
from contextlib import contextmanager
@contextmanager
def not_raises(ExpectedException):
try:
yield
except ExpectedException, err:
raise AssertionError(
"Did raise exception {0} when it should not!".format(
repr(ExpectedException)
)
)
except Exception, err:
raise AssertionError(
"An unexpected exception {0} raised.".format(repr(err))
)
def good_func():
print "hello"
def bad_func():
raise ValueError("BOOM!")
def ugly_func():
raise IndexError("UNEXPECTED BOOM!")
def test_ok():
with not_raises(ValueError):
good_func()
def test_bad():
with not_raises(ValueError):
bad_func()
def test_ugly():
with not_raises(ValueError):
ugly_func()
うまくいくようです。しかし、テストで本当にうまく読めるかどうかはわかりません。