68

tearDown()メソッドでテストの結果(つまり、すべてのアサーションに合格したかどうか)を取得することは可能ですか?Seleniumスクリプトを実行していて、tearDown()内からレポートを作成したいのですが、これが可能かどうかはわかりません。

4

13 に答える 13

58

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に関連するすべてのものと多くのマイナーノートを削除しました。

于 2016-09-21T01:16:27.030 に答える
41

の実装を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用に変更されています)。

于 2010-12-11T03:40:46.503 に答える
13

警告:現在、開発ボックスから離れているため、次の理論を再確認する方法はありません。だから、これは暗闇の中でのショットかもしれません。

sys.exc_info()おそらく、tearDown()メソッド内の戻り値を確認できます。それが返さ(None, None, None)れた場合は、テストケースが成功したことがわかります。それ以外の場合は、返されたタプルを使用して例外オブジェクトに問い合わせることができます。

sys.exc_infoのドキュメントを参照してください。

もう1つのより明確なアプローチは、この特別な処理を必要とするすべてのテストケースメソッドにスラップできるメソッドデコレータを作成することです。このデコレータは、アサーション例外をインターセプトし、それに基づいてself、tearDownメソッドが何が起きているかを学習できるようにするためにいくつかの状態を変更できます。

@assertion_tracker
def test_foo(self):
    # some test logic
于 2010-12-11T02:01:01.967 に答える
10

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:
        ...
于 2014-03-23T21:42:53.973 に答える
10

作成するレポートの種類によって異なります。

失敗時にいくつかのアクション(スクリーンショットの生成など)を実行したい場合は、を使用する代わりに、を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
于 2015-05-16T21:15:45.293 に答える
9

amatellanesの回答に続いて、Python 3.4を使用している場合は、を使用できません_outcomeForDoCleanups。これが私が一緒にハックすることに成功したものです:

def _test_has_failed(self):
    for method, error in self._outcome.errors:
        if error:
            return True
    return False

やっかいですが、うまくいくようです。

于 2014-04-19T22:38:35.103 に答える
3

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プライベート関数を作成しなかったでしょう;-)

于 2017-08-30T02:11:29.270 に答える
2

あなたの質問に対する正しい答えは、でテスト結果を取得するためのクリーンな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.
于 2020-08-06T09:15:18.427 に答える
1

Python2.7。

unittest.main()の後に結果を取得することもできます。

t = unittest.main(exit=False)
print t.result

またはスイートを使用します:

suite.addTests(tests)
result = unittest.result.TestResult()
suite.run(result)
print result
于 2016-04-13T07:41:19.950 に答える
1

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参照を行うことができます呼ばれています:failruestearDown()

@@ -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>

于 2016-09-04T00:20:39.027 に答える
0

現在のテストの名前は、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)
于 2016-06-13T12:35:14.107 に答える
0

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)
于 2018-12-12T08:53:52.000 に答える
0

一言で言えば、これは、Trueこれまでに実行されたすべてのテストがエラーや失敗なしで終了したかどうかを示します。

class WatheverTestCase(TestCase):

    def tear_down(self):
        return not self._outcome.result.errors and not self._outcome.result.failures

_outcomeより詳細な可能性にアクセスするには、のプロパティを調べてください。

于 2019-10-21T07:20:50.297 に答える