32

Python unittestモジュールで、状況によっては (モジュールをインポートできない場合や重要なリソースを見つけられない場合など)、完全にスキップするようにテスト ランナーに指示するようにしたいと考えています。

を使用してunittest.TestCase@unittest.skipIf(...)クラスをスキップできますが、モジュール全体をスキップするにはどうすればよいですか? モジュールのインポートに失敗すると、クラス定義自体が例外を引き起こす可能性があるため、すべてのクラスにスキップを適用するだけでは不十分です。

4

11 に答える 11

22

と の定義を見るunittest.skipIfと、テスト実行時にunittest.skipキーが動いていることがわかります。テストランナーで複数のテストではなく、スキップされた1 つraise unittest.SkipTest(reason)のテストとして表示されても問題ない場合は、インポート時に自分自身を高くすることができます。unittest.SkipTest

import unittest
try:
    # do thing
except SomeException:
    raise unittest.SkipTest("Such-and-such failed. Skipping all tests in foo.py")

で実行すると、次のようになりnosetests -vます。

Failure: SkipTest (Such-and-such failed. Skipping all tests in foo.py) ... SKIP:
Such-and-such failed. Skipping all tests in foo.py

----------------------------------------------------------------------
Ran 1 test in 0.002s

OK (SKIP=1)
于 2012-09-19T04:22:04.150 に答える
14

setUp で skipTest を使用するとうまくいくことがわかりました。モジュールをインポートする必要がある場合は、try ブロックを使用して module_failed = True などを設定し、設定されている場合は setUp で skipTest を呼び出します。これは、短い try ブロックのみが必要なテスト スキップの正しい数を報告します。

import unittest

try:
    import my_module
    module_failed = False
except ImportError:
    module_failed = True

class MyTests(unittest.TestCase):
    def setUp(self):
        if module_failed:
            self.skipTest('module not tested')

    def test_something(self):
            #...
于 2014-05-08T08:42:33.153 に答える
8

ここで他の答えを見た後、これは私が思いついた最良の答えです。テストスイート全体を例外処理に埋め込むのは醜いですが、それはあなたが望むことをしているように見えます。特に、インポートが機能しない場合はテストをスキップします。

テストを実行するためにnosetests-xを使用することについて話していると仮定すると、スキップするテストを超えて実行する必要があります。少なくとも、私が試したときはそう見えました。

import unittest
try:
    import PyQt4
    # the rest of the imports


    # actual tests go here.
    class TestDataEntryMixin(unittest.TestCase):
        def test_somefeature(self):
            # ....

except ImportError, e:
    if e.message.find('PyQt4') >= 0:
        class TestMissingDependency(unittest.TestCase):

            @unittest.skip('Missing dependency - ' + e.message)
            def test_fail():
                pass
    else:
        raise

if __name__ == '__main__':
    unittest.main()

インポートが失敗した場合、テストの実行は単にスキップする単一のテストに置き換えられます。また、意図せずに例外を飲み込まないように努めました。この解決策は、質問に対する他のすべての回答とコメントに多くを負っています。

詳細モードで実行すると、スキップしたときにこれが表示されます。

test_fail (test_openihm_gui_interface_mixins.TestMissingDependency) ... skipped 'Missing dependency - No module named PyQt4'
于 2012-09-20T10:12:54.537 に答える
4

Python 2.7+ (または unittest2 バックポートを使用) の場合:

...

import unittest

def setUpModule():
    try:
        import something
    except ImportError as err:
        raise unittest.SkipTest(str(err))

class Tests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        try:
            import something
        except ImportError as err:
            raise unittest.SkipTest(str(err))
...
于 2016-06-17T19:21:58.767 に答える
3

私の意見では、otus によって提案された解決策は機能し、承認された解決策よりも簡単です。しかし、少なくとも 1 つの欠点があります。デコレーターでクエリを実行して、次my_moduleのような単一のテストをスキップする場合

@unittest.skipIf(my_module.support_foo, 'foo not supported')
def test_foo(self):
...

を取得しNameError: name 'my_module' is not definedます。解決策は、スキップを関数定義内に配置することです。

def test_foo(self):
    if not my_module.support_foo:
        self.skipTest('foo not supported')
于 2014-09-10T14:43:11.707 に答える
3

モジュールでカスタムload_tests関数を定義してみてください。

import unittest
try:
    (testcases)
except ImportError as e:
    def load_tests(*args, **kwargs):
        print("Failed to load tests: skipping")
        return unittest.TestSuite() # no tests
于 2012-09-19T04:25:55.860 に答える
2

すべてのサブクラス定義をブロックに入れるのは汚いかもしれませんが、うまくいきます:unittest.TestCasetry...except

import unittest
try:
    import eggs
    class Spam(unittest.TestCase):
        pass
    class Ham(unittest.TestCase):
        pass
    # ...
except ImportError:
    # print 'could not import eggs'
    pass

eggsインポートが失敗し、それらのすべてのクラス ( Spam, Ham, etc.) がスキップされた場合、サブクラスは定義されません。それは出力に反映されません (あなたが望むものに応じて良いか悪いか)。

于 2012-09-19T04:00:51.173 に答える