5

次の Python UnitTest があるとします。

import unittest

def Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # Get some resources
        ...

        if error_occurred:
            assert(False)

    @classmethod
    def tearDownClass(cls):
        # release resources
        ...

setUpClass 呼び出しが失敗した場合、tearDownClass は呼び出されないため、リソースは解放されません。これは、次のテストでリソースが必要な場合のテスト実行中の問題です。

setUpClass 呼び出しが失敗したときにクリーンアップを行う方法はありますか?

4

3 に答える 3

6

setUpClass メソッドに try キャッチを配置し、except で直接 TeaDown を呼び出すことができます。

def setUpClass(cls):
     try: 
         # setUpClassInner()
     except Exception, e:
        cls.tearDownClass()
        raise # to still mark the test as failed.

単体テストを実行するために外部リソースを要求することは、悪い習慣です。これらのリソースが利用できず、奇妙なバグについてコードの一部をテストする必要がある場合、すぐに実行することはできません。統合テストと単体テストを区別するようにしてください。

于 2013-07-09T00:55:37.077 に答える
5

他の場所でリソースを保護するのと同じ方法。 try-except:

def setUpClass(cls):
    # ... acquire resources 
    try:
        # ... some call that may fail
    except SomeError, e:
        # cleanup here

cls.tearDownClass()クリーンアップは、exceptブロック を呼び出すのと同じくらい簡単です。次に、または任意のメソッドを呼び出しassert(False)て、テストを早期に終了できます。

于 2013-07-09T00:55:11.357 に答える
3

テスト インスタンスを取得し、addCleanup を使用してスレッドや一時ファイルなどをきれいにセットアップ/破棄するテスト ヘルパー関数がたくさんあるので、クラス レベルのフィクスチャでも機能するように addCleanup API が必要でした。unittest の doCleanup 機能を少し再実装して助けになり、クラスのセットアップ中にモックを使用して addCleanup() にパッチを適用しました

import unittest
import logging
import mock

LOGGER = logging.getLogger(__name__)

class ClassCleanupTestCase(unittest.TestCase):
    _class_cleanups = []

    @classmethod
    def setUpClassWithCleanup(cls):
        def cleanup_fn():
            """Do some cleanup!"""
        # Do something that requires cleanup
        cls.addCleanup(cleanup_fn)

    @classmethod
    def addCleanupClass(cls, function, *args, **kwargs):
        cls._class_cleanups.append((function, args, kwargs))

    @classmethod
    def doCleanupsClass(cls):
        results = []
        while cls._class_cleanups:
            function, args, kwargs = cls._class_cleanups.pop()
            try:
                function(*args, **kwargs)
            except Exceptions:
                LOGGER.exception('Exception calling class cleanup function')
                results.append(sys.exc_info())

        if results:
            LOGGER.error('Exception(s) raised during class cleanup, re-raising '
                         'first exception.')
            raise results[0]

    @classmethod
    def setUpClass(cls):
        try:
            with mock.patch.object(cls, 'addCleanup') as cls_addCleanup:
                cls_addCleanup.side_effect = cls.addCleanupClass
                cls.setUpClassWithCleanup()
        except Exception:
            cls.doCleanupsClass()
            raise

    @classmethod
    def tearDownClass(cls):
        cls.doCleanupsClass()
于 2016-04-18T14:51:25.613 に答える