tearDown()メソッドでテストの結果(つまり、すべてのアサーションに合格したかどうか)を取得することは可能ですか?Seleniumスクリプトを実行していて、tearDown()内からレポートを作成したいのですが、これが可能かどうかはわかりません。
13 に答える
2022年3月の時点で、この回答は3.4から3.11までのPythonバージョン(最新の開発Pythonバージョンを含む)をサポートするように更新されています。エラー/障害の分類は、出力で使用されるものと同じですunittest
。以前のコードを変更しなくても機能しますtearDown()
。デコレータskipIf()
とを正しく認識しexpectedFailure
ます。pytestとも互換性があります。
コード:
import unittest
class MyTest(unittest.TestCase):
def tearDown(self):
if hasattr(self._outcome, 'errors'):
# Python 3.4 - 3.10 (These two methods have no side effects)
result = self.defaultTestResult()
self._feedErrorsToResult(result, self._outcome.errors)
else:
# Python 3.11+
result = self._outcome.result
ok = all(test != self for test, text in result.errors + result.failures)
# Demo output: (print short info immediately - not important)
if ok:
print('\nOK: %s' % (self.id(),))
for typ, errors in (('ERROR', result.errors), ('FAIL', result.failures)):
for test, text in errors:
if test is self:
msg = [x for x in text.split('\n')[1:]
if not x.startswith(' ')][0]
print("\n\n%s: %s\n %s" % (typ, self.id(), msg))
例外情報が必要ない場合は、後半を削除できます。トレースバックも必要な場合は、のtext
代わりに変数全体を使用してmsg
ください。expectedFailureブロックでの予期しない成功のみを認識できません
試験方法の例:
def test_error(self):
self.assertEqual(1 / 0, 1)
def test_fail(self):
self.assertEqual(2, 1)
def test_success(self):
self.assertEqual(1, 1)
出力例:
$ python3 -m unittest test
ERROR: q.MyTest.test_error
ZeroDivisionError: division by zero
E
FAIL: q.MyTest.test_fail
AssertionError: 2 != 1
F
OK: q.MyTest.test_success
.
======================================================================
... skipped the usual output from unittest with tracebacks ...
...
Ran 3 tests in 0.001s
FAILED (failures=1, errors=1)
expectedFailureデコレータの例を含む完全なコード
編集:このソリューションをPython 3.11に更新したとき、古いPython<3.4に関連するすべてのものと多くのマイナーノートを削除しました。
の実装をunittest.TestCase.run
見ると、すべてのテスト結果がunittest.TestResult
引数として渡された結果オブジェクト(通常はインスタンス)に収集されていることがわかります。結果ステータスはunittest.TestCase
オブジェクトに残されません。
unittest.TestCase.tearDown
したがって、テストケースとテスト結果のエレガントな分離を次のようなもので容赦なく破らない限り、この方法でできることはあまりありません。
import unittest
class MyTest(unittest.TestCase):
currentResult = None # Holds last result object passed to run method
def setUp(self):
pass
def tearDown(self):
ok = self.currentResult.wasSuccessful()
errors = self.currentResult.errors
failures = self.currentResult.failures
print ' All tests passed so far!' if ok else \
' %d errors and %d failures so far' % \
(len(errors), len(failures))
def run(self, result=None):
self.currentResult = result # Remember result for use in tearDown
unittest.TestCase.run(self, result) # call superclass run method
def test_onePlusOneEqualsTwo(self):
self.assertTrue(1 + 1 == 2) # Succeeds
def test_onePlusOneEqualsThree(self):
self.assertTrue(1 + 1 == 3) # Fails
def test_onePlusNoneIsNone(self):
self.assertTrue(1 + None is None) # Raises TypeError
if __name__ == '__main__':
unittest.main()
これはPython2.6〜3.3で機能します(以下の新しいPython用に変更されています)。
警告:現在、開発ボックスから離れているため、次の理論を再確認する方法はありません。だから、これは暗闇の中でのショットかもしれません。
sys.exc_info()
おそらく、tearDown()メソッド内の戻り値を確認できます。それが返さ(None, None, None)
れた場合は、テストケースが成功したことがわかります。それ以外の場合は、返されたタプルを使用して例外オブジェクトに問い合わせることができます。
sys.exc_infoのドキュメントを参照してください。
もう1つのより明確なアプローチは、この特別な処理を必要とするすべてのテストケースメソッドにスラップできるメソッドデコレータを作成することです。このデコレータは、アサーション例外をインターセプトし、それに基づいてself
、tearDownメソッドが何が起きているかを学習できるようにするためにいくつかの状態を変更できます。
@assertion_tracker
def test_foo(self):
# some test logic
Python 2を使用している場合は、メソッドを使用できます_resultForDoCleanups
。このメソッドはTextTestResult
オブジェクトを返します:
<unittest.runner.TextTestResult run=1 errors=0 failures=0>
このオブジェクトを使用して、テストの結果を確認できます。
def tearDown(self):
if self._resultForDoCleanups.failures:
...
elif self._resultForDoCleanups.errors:
...
else:
# Success
Python 3を使用している場合は、次を使用できます_outcomeForDoCleanups
。
def tearDown(self):
if not self._outcomeForDoCleanups.success:
...
作成するレポートの種類によって異なります。
失敗時にいくつかのアクション(スクリーンショットの生成など)を実行したい場合は、を使用する代わりに、をtearDown()
オーバーライドすることでそれを実現できますfailureException
。
例えば:
@property
def failureException(self):
class MyFailureException(AssertionError):
def __init__(self_, *args, **kwargs):
screenshot_dir = 'reports/screenshots'
if not os.path.exists(screenshot_dir):
os.makedirs(screenshot_dir)
self.driver.save_screenshot('{0}/{1}.png'.format(screenshot_dir, self.id()))
return super(MyFailureException, self_).__init__(*args, **kwargs)
MyFailureException.__name__ = AssertionError.__name__
return MyFailureException
amatellanesの回答に続いて、Python 3.4を使用している場合は、を使用できません_outcomeForDoCleanups
。これが私が一緒にハックすることに成功したものです:
def _test_has_failed(self):
for method, error in self._outcome.errors:
if error:
return True
return False
やっかいですが、うまくいくようです。
unittest
内部に依存するソリューションを使用することに不快感を覚える私たちのためのソリューションは次のとおりです。
まず、TestCase
インスタンスにフラグを設定して、テストケースが失敗したか合格したかを判断するデコレータを作成します。
import unittest
import functools
def _tag_error(func):
"""Decorates a unittest test function to add failure information to the TestCase."""
@functools.wraps(func)
def decorator(self, *args, **kwargs):
"""Add failure information to `self` when `func` raises an exception."""
self.test_failed = False
try:
func(self, *args, **kwargs)
except unittest.SkipTest:
raise
except Exception: # pylint: disable=broad-except
self.test_failed = True
raise # re-raise the error with the original traceback.
return decorator
このデコレータは実際には非常に単純です。これは、例外unittest
を介して失敗したテストを検出するという事実に依存しています。私の知る限り、処理する必要がある唯一の特別な例外は(テストの失敗を示すものではありません)です。他のすべての例外はテストの失敗を示しているので、それらが私たちにバブルしたときにそのようにマークします。unittest.SkipTest
これで、このデコレータを直接使用できます。
class MyTest(unittest.TestCase):
test_failed = False
def tearDown(self):
super(MyTest, self).tearDown()
print(self.test_failed)
@_tag_error
def test_something(self):
self.fail('Bummer')
このデコレータを書くのはいつも面倒です。単純化する方法はありますか?はいあります!* デコレータの適用を処理するメタクラスを作成できます。
class _TestFailedMeta(type):
"""Metaclass to decorate test methods to append error information to the TestCase instance."""
def __new__(cls, name, bases, dct):
for name, prop in dct.items():
# assume that TestLoader.testMethodPrefix hasn't been messed with -- otherwise, we're hosed.
if name.startswith('test') and callable(prop):
dct[name] = _tag_error(prop)
return super(_TestFailedMeta, cls).__new__(cls, name, bases, dct)
これを基本TestCase
サブクラスに適用すると、すべて設定されます。
import six # For python2.x/3.x compatibility
class BaseTestCase(six.with_metaclass(_TestFailedMeta, unittest.TestCase)):
"""Base class for all our other tests.
We don't really need this, but it demonstrates that the
metaclass gets applied to all subclasses too.
"""
class MyTest(BaseTestCase):
def tearDown(self):
super(MyTest, self).tearDown()
print(self.test_failed)
def test_something(self):
self.fail('Bummer')
これが適切に処理されない場合が多くあります。たとえば、失敗したサブテストや予想される失敗を正しく検出しません。これの他の故障モードに興味があるので、私が適切に処理していないケースを見つけた場合は、コメントで知らせてください。調査します。
*もっと簡単な方法がなかったら、私は_tag_error
プライベート関数を作成しなかったでしょう;-)
あなたの質問に対する正しい答えは、でテスト結果を取得するためのクリーンなtearDown()
方法がないということだと思います。ここでの回答のほとんどは、Pythonモジュールのいくつかのプライベート部分へのアクセスを含みunittest
、一般的には回避策のように感じます。テスト結果とテストケースは分離されており、それに逆らうべきではないため、これらを回避することを強くお勧めします。
(私のように)クリーンなコードが好きな場合は、代わりに、独自のTestResultクラスを使用してTestRunnerをインスタンス化する必要があると思います。次に、これらのメソッドをオーバーライドすることで、必要なレポートを追加できます。
addError(test, err)
Called when the test case test raises an unexpected exception. err is a tuple of the form returned by sys.exc_info(): (type, value, traceback).
The default implementation appends a tuple (test, formatted_err) to the instance’s errors attribute, where formatted_err is a formatted traceback derived from err.
addFailure(test, err)
Called when the test case test signals a failure. err is a tuple of the form returned by sys.exc_info(): (type, value, traceback).
The default implementation appends a tuple (test, formatted_err) to the instance’s failures attribute, where formatted_err is a formatted traceback derived from err.
addSuccess(test)
Called when the test case test succeeds.
The default implementation does nothing.
Python2.7。
unittest.main()の後に結果を取得することもできます。
t = unittest.main(exit=False)
print t.result
またはスイートを使用します:
suite.addTests(tests)
result = unittest.result.TestResult()
suite.run(result)
print result
scoffeyの答えに触発されて、私は慈悲深い人を次のレベルに引き上げることに決めました、そして次のことを思いつきました。
これは、バニラ単体テストとnosetestsを介して実行した場合の両方で機能し、Pythonバージョン2.7、3.2、3.3、および3.4でも機能します(3.0、3.1、または3.5はインストールされていないため、特にテストしませんでした。現時点では、ソースコードを正しく読み取れば、3.5でも機能するはずです):
#! /usr/bin/env python
from __future__ import unicode_literals
import logging
import os
import sys
import unittest
# Log file to see squawks during testing
formatter = logging.Formatter(fmt='%(levelname)-8s %(name)s: %(message)s')
log_file = os.path.splitext(os.path.abspath(__file__))[0] + '.log'
handler = logging.FileHandler(log_file)
handler.setFormatter(formatter)
logging.root.addHandler(handler)
logging.root.setLevel(logging.DEBUG)
log = logging.getLogger(__name__)
PY = tuple(sys.version_info)[:3]
class SmartTestCase(unittest.TestCase):
"""Knows its state (pass/fail/error) by the time its tearDown is called."""
def run(self, result):
# Store the result on the class so tearDown can behave appropriately
self.result = result.result if hasattr(result, 'result') else result
if PY >= (3, 4, 0):
self._feedErrorsToResultEarly = self._feedErrorsToResult
self._feedErrorsToResult = lambda *args, **kwargs: None # no-op
super(SmartTestCase, self).run(result)
@property
def errored(self):
if (3, 0, 0) <= PY < (3, 4, 0):
return bool(self._outcomeForDoCleanups.errors)
return self.id() in [case.id() for case, _ in self.result.errors]
@property
def failed(self):
if (3, 0, 0) <= PY < (3, 4, 0):
return bool(self._outcomeForDoCleanups.failures)
return self.id() in [case.id() for case, _ in self.result.failures]
@property
def passed(self):
return not (self.errored or self.failed)
def tearDown(self):
if PY >= (3, 4, 0):
self._feedErrorsToResultEarly(self.result, self._outcome.errors)
class TestClass(SmartTestCase):
def test_1(self):
self.assertTrue(True)
def test_2(self):
self.assertFalse(True)
def test_3(self):
self.assertFalse(False)
def test_4(self):
self.assertTrue(False)
def test_5(self):
self.assertHerp('Derp')
def tearDown(self):
super(TestClass, self).tearDown()
log.critical('---- RUNNING {} ... -----'.format(self.id()))
if self.errored:
log.critical('----- ERRORED -----')
elif self.failed:
log.critical('----- FAILED -----')
else:
log.critical('----- PASSED -----')
if __name__ == '__main__':
unittest.main()
で実行する場合unittest
:
$ ./test.py -v
test_1 (__main__.TestClass) ... ok
test_2 (__main__.TestClass) ... FAIL
test_3 (__main__.TestClass) ... ok
test_4 (__main__.TestClass) ... FAIL
test_5 (__main__.TestClass) ... ERROR
[…]
$ cat ./test.log
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_1 ... -----
CRITICAL __main__: ----- PASSED -----
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_2 ... -----
CRITICAL __main__: ----- FAILED -----
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_3 ... -----
CRITICAL __main__: ----- PASSED -----
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_4 ... -----
CRITICAL __main__: ----- FAILED -----
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_5 ... -----
CRITICAL __main__: ----- ERRORED -----
で実行する場合nosetests
:
$ nosetests ./test.py -v
test_1 (test.TestClass) ... ok
test_2 (test.TestClass) ... FAIL
test_3 (test.TestClass) ... ok
test_4 (test.TestClass) ... FAIL
test_5 (test.TestClass) ... ERROR
$ cat ./test.log
CRITICAL test: ---- RUNNING test.TestClass.test_1 ... -----
CRITICAL test: ----- PASSED -----
CRITICAL test: ---- RUNNING test.TestClass.test_2 ... -----
CRITICAL test: ----- FAILED -----
CRITICAL test: ---- RUNNING test.TestClass.test_3 ... -----
CRITICAL test: ----- PASSED -----
CRITICAL test: ---- RUNNING test.TestClass.test_4 ... -----
CRITICAL test: ----- FAILED -----
CRITICAL test: ---- RUNNING test.TestClass.test_5 ... -----
CRITICAL test: ----- ERRORED -----
バックグラウンド
私はこれから始めました:
class SmartTestCase(unittest.TestCase):
"""Knows its state (pass/fail/error) by the time its tearDown is called."""
def run(self, result):
# Store the result on the class so tearDown can behave appropriately
self.result = result.result if hasattr(result, 'result') else result
super(SmartTestCase, self).run(result)
@property
def errored(self):
return self.id() in [case.id() for case, _ in self.result.errors]
@property
def failed(self):
return self.id() in [case.id() for case, _ in self.result.failures]
@property
def passed(self):
return not (self.errored or self.failed)
ただし、これはPython 2でのみ機能します。Python3では、3.3まで、制御フローが少し変更されているようです。Python3のunittestパッケージは、各テストのメソッドを呼び出した後に結果を処理 します。この動作は、単に追加するだけで確認できます。テストクラスへの追加の行(または6行):tearDown()
@@ -63,6 +63,12 @@
log.critical('----- FAILED -----')
else:
log.critical('----- PASSED -----')
+ log.warning(
+ 'ERRORS THUS FAR:\n'
+ + '\n'.join(tc.id() for tc, _ in self.result.errors))
+ log.warning(
+ 'FAILURES THUS FAR:\n'
+ + '\n'.join(tc.id() for tc, _ in self.result.failures))
if __name__ == '__main__':
次に、テストを再実行します。
$ python3.3 ./test.py -v
test_1 (__main__.TestClass) ... ok
test_2 (__main__.TestClass) ... FAIL
test_3 (__main__.TestClass) ... ok
test_4 (__main__.TestClass) ... FAIL
test_5 (__main__.TestClass) ... ERROR
[…]
…そして、結果としてこれが得られることがわかります。
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_1 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_2 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_3 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_4 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_5 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
__main__.TestClass.test_4
ここで、上記をPython2の出力と比較します。
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_1 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_2 ... -----
CRITICAL __main__: ----- FAILED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_3 ... -----
CRITICAL __main__: ----- PASSED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_4 ... -----
CRITICAL __main__: ----- FAILED -----
WARNING __main__: ERRORS THUS FAR:
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
__main__.TestClass.test_4
CRITICAL __main__: ---- RUNNING __main__.TestClass.test_5 ... -----
CRITICAL __main__: ----- ERRORED -----
WARNING __main__: ERRORS THUS FAR:
__main__.TestClass.test_5
WARNING __main__: FAILURES THUS FAR:
__main__.TestClass.test_2
__main__.TestClass.test_4
Python 3は、テストが破棄された後にエラー/失敗を処理するため、result.errors
またはresult.failures
すべての場合を使用してテストの結果を簡単に推測することはできません。(テストの結果を破棄した後に処理する方がアーキテクチャ的にはおそらく理にかなっていると思いますが、テストの合格/不合格のステータスに応じて、異なるテスト終了手順に従うという完全に有効なユースケースになります。会うのが難しい…)
result
したがって、オブジェクト全体に依存する代わりに、_outcomeForDoCleanups
他の人がすでに述べたように、現在実行中のテストの結果オブジェクトを含み、時間までにテストのステータスを推測するために使用できる必要な属性を含むerrors
参照を行うことができます呼ばれています:failrues
tearDown()
@@ -3,6 +3,7 @@
from __future__ import unicode_literals
import logging
import os
+import sys
import unittest
@@ -16,6 +17,9 @@
log = logging.getLogger(__name__)
+PY = tuple(sys.version_info)[:3]
+
+
class SmartTestCase(unittest.TestCase):
"""Knows its state (pass/fail/error) by the time its tearDown is called."""
@@ -27,10 +31,14 @@
@property
def errored(self):
+ if PY >= (3, 0, 0):
+ return bool(self._outcomeForDoCleanups.errors)
return self.id() in [case.id() for case, _ in self.result.errors]
@property
def failed(self):
+ if PY >= (3, 0, 0):
+ return bool(self._outcomeForDoCleanups.failures)
return self.id() in [case.id() for case, _ in self.result.failures]
@property
これにより、Python3の初期バージョンのサポートが追加されます。
ただし、Python 3.4以降、このプライベートメンバー変数は存在しなくなり、代わりに、新しい(プライベートでもありますが)メソッドが追加されまし_feedErrorsToResult
た。
つまり、バージョン3.4(およびそれ以降)の場合、必要性が十分に大きければ、バージョン2の場合と同じように、すべてを再び機能させるために、 非常にハッキング的に強制することができます…</ p>
@@ -27,17 +27,20 @@
def run(self, result):
# Store the result on the class so tearDown can behave appropriately
self.result = result.result if hasattr(result, 'result') else result
+ if PY >= (3, 4, 0):
+ self._feedErrorsToResultEarly = self._feedErrorsToResult
+ self._feedErrorsToResult = lambda *args, **kwargs: None # no-op
super(SmartTestCase, self).run(result)
@property
def errored(self):
- if PY >= (3, 0, 0):
+ if (3, 0, 0) <= PY < (3, 4, 0):
return bool(self._outcomeForDoCleanups.errors)
return self.id() in [case.id() for case, _ in self.result.errors]
@property
def failed(self):
- if PY >= (3, 0, 0):
+ if (3, 0, 0) <= PY < (3, 4, 0):
return bool(self._outcomeForDoCleanups.failures)
return self.id() in [case.id() for case, _ in self.result.failures]
@@ -45,6 +48,10 @@
def passed(self):
return not (self.errored or self.failed)
+ def tearDown(self):
+ if PY >= (3, 4, 0):
+ self._feedErrorsToResultEarly(self.result, self._outcome.errors)
+
class TestClass(SmartTestCase):
@@ -64,6 +71,7 @@
self.assertHerp('Derp')
def tearDown(self):
+ super(TestClass, self).tearDown()
log.critical('---- RUNNING {} ... -----'.format(self.id()))
if self.errored:
log.critical('----- ERRORED -----')
…super(…, self).tearDown()
もちろん、このクラスのすべてのコンシューマーは、それぞれのメソッドで覚えている必要がありtearDown
ます…</ p>
免責事項:これは純粋に教育的なものであり、自宅などで試してはいけません。私はこのソリューションを特に誇りに思っていませんが、当面は十分に機能するようで、ハッキングできる最高のものです。土曜日の午後に1、2時間いじった後、起き上がりました…</ p>
現在のテストの名前は、unittest.TestCase.id()メソッドを使用して取得できます。したがって、tearDownでは、self.id()を確認できます。
この例は、次の方法を示しています。
- 現在のテストにエラーまたは失敗リストのエラーまたは失敗があるかどうかを確認します
- PASSまたはFAILまたはEXCEPTIONを使用してテストIDを出力します
ここでテストされた例は、scoffeyの素晴らしい例で機能します。
def tearDown(self):
result = "PASS"
#### Find and show result for current test
# I did not find any nicer/neater way of comparing self.id() with test id stored in errors or failures lists :-7
id = str(self.id()).split('.')[-1]
# id() e.g. tup[0]:<__main__.MyTest testMethod=test_onePlusNoneIsNone>
# str(tup[0]):"test_onePlusOneEqualsThree (__main__.MyTest)"
# str(self.id()) = __main__.MyTest.test_onePlusNoneIsNone
for tup in self.currentResult.failures:
if str(tup[0]).startswith(id):
print ' test %s failure:%s' % (self.id(), tup[1])
## DO TEST FAIL ACTION HERE
result = "FAIL"
for tup in self.currentResult.errors:
if str(tup[0]).startswith(id):
print ' test %s error:%s' % (self.id(), tup[1])
## DO TEST EXCEPTION ACTION HERE
result = "EXCEPTION"
print "Test:%s Result:%s" % (self.id(), result)
結果の例:
python run_scripts/tut2.py 2>&1
E test __main__.MyTest.test_onePlusNoneIsNone error:Traceback (most recent call last):
File "run_scripts/tut2.py", line 80, in test_onePlusNoneIsNone
self.assertTrue(1 + None is None) # raises TypeError
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
Test:__main__.MyTest.test_onePlusNoneIsNone Result:EXCEPTION
F test __main__.MyTest.test_onePlusOneEqualsThree failure:Traceback (most recent call last):
File "run_scripts/tut2.py", line 77, in test_onePlusOneEqualsThree
self.assertTrue(1 + 1 == 3) # fails
AssertionError: False is not true
Test:__main__.MyTest.test_onePlusOneEqualsThree Result:FAIL
Test:__main__.MyTest.test_onePlusOneEqualsTwo Result:PASS
.
======================================================================
ERROR: test_onePlusNoneIsNone (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "run_scripts/tut2.py", line 80, in test_onePlusNoneIsNone
self.assertTrue(1 + None is None) # raises TypeError
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
======================================================================
FAIL: test_onePlusOneEqualsThree (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "run_scripts/tut2.py", line 77, in test_onePlusOneEqualsThree
self.assertTrue(1 + 1 == 3) # fails
AssertionError: False is not true
----------------------------------------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=1, errors=1)
Python 3.7でテスト済み-失敗したアサーションの情報を取得するためのサンプルコードですが、エラーの処理方法についてのアイデアを提供できます。
def tearDown(self):
if self._outcome.errors[1][1] and hasattr(self._outcome.errors[1][1][1], 'actual'):
print(self._testMethodName)
print(self._outcome.errors[1][1][1].actual)
print(self._outcome.errors[1][1][1].expected)
一言で言えば、これは、True
これまでに実行されたすべてのテストがエラーや失敗なしで終了したかどうかを示します。
class WatheverTestCase(TestCase):
def tear_down(self):
return not self._outcome.result.errors and not self._outcome.result.failures
_outcome
より詳細な可能性にアクセスするには、のプロパティを調べてください。