特定の状況で例外が発生しないことを確認するテストを作成します。
例外isが発生したかどうかをテストするのは簡単です...
sInvalidPath=AlwaysSuppliesAnInvalidPath()
self.assertRaises(PathIsNotAValidOne, MyObject, sInvalidPath)
...しかし、どうすればoppositeを実行できますか。
このような私は私が何を求めているのか...
sValidPath=AlwaysSuppliesAValidPath()
self.assertNotRaises(PathIsNotAValidOne, MyObject, sValidPath)
def run_test(self):
try:
myFunc()
except ExceptionType:
self.fail("myFunc() raised ExceptionType unexpectedly!")
こんにちは-特定の状況で例外が発生しないことを確認するテストを作成したいと思います。
これがデフォルトの前提です。例外は発生しません。
他に何も言わない場合、それはすべてのテストで想定されています。
実際にアサーションを書く必要はありません。
関数を呼び出すだけです。例外が発生した場合、単体テストフレームワークはこれにエラーのフラグを付けます。コメントを追加したい場合があります、例えば:
sValidPath=AlwaysSuppliesAValidPath()
# Check PathIsNotAValidOne not thrown
MyObject(sValidPath)
私は元のポスターであり、コードで最初に使用したことなく、DGHによる上記の回答を受け入れました。
一度使用すると、実際に必要なことを実際に行うには少し調整が必要であることに気付きました(DGHに公平にするために、彼/彼女は「または類似の何か」と言っていました!)。
他の人のために、ここにTweakを投稿する価値があると思いました。
try:
a = Application("abcdef", "")
except pySourceAidExceptions.PathIsNotAValidOne:
pass
except:
self.assertTrue(False)
ここでやろうとしていたことは、スペースの2番目の引数でApplicationオブジェクトをインスタンス化しようとした場合に、pySourceAidExceptions.PathIsNotAValidOneが発生することを確認することでした。
上記のコード(DGHの回答に大きく基づいている)を使用すると、それができると信じています。
assertNotRaises
モジュールの元のassertRaises
の実装の約90%を再利用することで、unittest
を定義できます。このアプローチでは、assertNotRaises
メソッドになります。このメソッドは、失敗した状態を逆にすると、assertRaises
と同じように動作します。
assertNotRaises
メソッドをunittest.TestCase
に追加するのは驚くほど簡単であることがわかりました(この答えを書くのにコードを書くのに比べて約4倍の時間がかかりました)。 実行中のassertNotRaises
メソッドのライブデモ です。 assertRaises
と同様 の場合、呼び出し可能変数と引数をassertNotRaises
に渡すか、with
ステートメントで使用できます。ライブデモには、assertNotRaises
が意図したとおりに機能することを示すテストケースが含まれています。
assertRaises
でのunittest
の実装はかなり複雑ですが、少し巧妙なサブクラスを使用することで、その障害状態をオーバーライドして元に戻すことができます。
assertRaises
は、基本的にunittest.case._AssertRaisesContext
クラスのインスタンスを作成して返す短いメソッドです(unittest.case
モジュールの定義を参照)。 _AssertNotRaisesContext
をサブクラス化し、その_AssertRaisesContext
メソッドをオーバーライドすることにより、独自の__exit__
クラスを定義できます。
import traceback
from unittest.case import _AssertRaisesContext
class _AssertNotRaisesContext(_AssertRaisesContext):
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
self.exception = exc_value.with_traceback(None)
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} raised".format(exc_name))
else:
traceback.clear_frames(tb)
return True
通常、テストケースクラスは、TestCase
から継承することで定義します。代わりにサブクラスMyTestCase
から継承する場合:
class MyTestCase(unittest.TestCase):
def assertNotRaises(self, expected_exception, *args, **kwargs):
context = _AssertNotRaisesContext(expected_exception, self)
try:
return context.handle('assertNotRaises', args, kwargs)
finally:
context = None
これで、すべてのテストケースでassertNotRaises
メソッドを使用できるようになります。
例外クラスをassertRaises()
に渡すと、コンテキストマネージャーが提供されます。これにより、テストの読みやすさが向上します。
# raise exception if Application created with bad data
with self.assertRaises(pySourceAidExceptions.PathIsNotAValidOne):
application = Application("abcdef", "")
これにより、コード内のエラーケースをテストできます。
この場合、無効なパラメーターをApplicationコンストラクターに渡すときにPathIsNotAValidOne
が発生することをテストしています。
次のようにunittest
をモンキーパッチすると便利だとわかりました。
def assertMayRaise(self, exception, expr):
if exception is None:
try:
expr()
except:
info = sys.exc_info()
self.fail('%s raised' % repr(info[0]))
else:
self.assertRaises(exception, expr)
unittest.TestCase.assertMayRaise = assertMayRaise
これにより、例外がないかどうかをテストする際の意図が明確になります。
self.assertMayRaise(None, does_not_raise)
これにより、ループでのテストも簡単になります。
# ValueError is raised only for op(x,x), op(y,y) and op(z,z).
for i,(a,b) in enumerate(itertools.product([x,y,z], [x,y,z])):
self.assertMayRaise(None if i%4 else ValueError, lambda: op(a, b))
def _assertNotRaises(self, exception, obj, attr):
try:
result = getattr(obj, attr)
if hasattr(result, '__call__'):
result()
except Exception as e:
if isinstance(e, exception):
raise AssertionError('{}.{} raises {}.'.format(obj, attr, exception))
パラメータを受け入れる必要がある場合は変更できます。
のように呼び出す
self._assertNotRaises(IndexError, array, 'sort')
あなたはそのように試すことができます。 try:self.assertRaises(None、function、arg1、arg2)例外:tryブロック内にコードを配置しない場合は、例外 'AssertionError:None not raised "を通過し、テストケースは失敗します。テストケースは合格です予期される動作であるtryブロック内に配置した場合。