14

「メソッドxは既存のファイルの名前を返しますか?」の行に沿って、すべてがまったく同じテストを実行する必要があるテストケースのグループがあります。

そのための最善の方法は、全員が共有するTestCaseから派生した基本クラスであり、そのクラスにテストを追加することだと思いました。残念ながら、テストフレームワークは依然として基本クラスのテストを実行しようとしますが、それは意味がありません。

class SharedTest(TestCase):
    def x(self):
        ...do test...

class OneTestCase(SharedTest):
    ...my tests are performed, and 'SharedTest.x()'...

次のような派生クラスではなく、基本クラスのオブジェクトで呼び出された場合は、チェックをハックしてテストをスキップしようとしました。

    class SharedTest(TestCase):
        def x(self):
            if type(self) != type(SharedTest()):
                ...do test...
            else:
                pass

しかし、このエラーが発生しました:

ValueError: no such test method in <class 'tests.SharedTest'>: runTest

まず、これを行うためのエレガントな提案があります。次に、type()ハックは実際には使用したくないのですが、なぜ機能しないのかを理解したいと思います。

4

2 に答える 2

31

unittest.TestCaseテスト ランナーが(Django が継承する) から継承するテストのみを実行することを利用して、ミックスインを使用できますTestCase。たとえば、次のようになります。

class SharedTestMixin(object):
    # This class will not be executed by the test runner (it inherits from object, not unittest.TestCase.
    # If it did, assertEquals would fail , as it is not a method that exists in `object`
    def test_common(self):
         self.assertEquals(1, 1)


class TestOne(TestCase, SharedTestMixin):
    def test_something(self):
         pass

    # test_common is also run

class TestTwo(TestCase, SharedTestMixin):
    def test_another_thing(self):
        pass

    # test_common is also run

これが機能する理由の詳細については、Python メソッドの解決順序と多重継承を検索してください。

于 2010-08-31T04:50:03.657 に答える
4

私も同様の問題に直面しました。基本クラスのテストメソッドの実行を防ぐことはできませんでしたが、実際のコードが実行されないようにしました。これを行うには、属性を確認し、設定されている場合はすぐに戻ります。この属性はBaseクラスに対してのみ設定されているため、テストは基本クラス以外のすべての場所で実行されました。

class SharedTest(TestCase):
    def setUp(self):
        self.do_not_run = True

    def test_foo(self):
        if getattr(self, 'do_not_run', False):
            return
        # Rest of the test body.

class OneTestCase(SharedTest):
    def setUp(self):
        super(OneTestCase, self).setUp()
        self.do_not_run = False

これはちょっとしたハックです。これを行うにはおそらくもっと良い方法がありますが、方法がわかりません

アップデート

sdolanが言うように、ミックスインは正しい方法です。なぜ私はそれを前に見なかったのですか?

アップデート2

if getattr(self, 'do_not_run', False):(コメントを読んだ後)(1)スーパークラスのメソッドがハックのチェックを回避できればいいのですが。(2)テストの数が正確にカウントされているかどうか。

これを行うための可能な方法があります。Djangoは、その名前のパッケージでtestsあろうとなかろうと、すべてのテストクラスを取得して実行します。テストスーパークラスがテストモジュールの外部tests.pyで宣言されている場合、これは発生しません。それでも、テストクラスで継承できます。たとえば、テストケースに配置して、テストケースで使用できます。これは、上記のソリューションのよりクリーンなバージョンになります。SharedTestapp.utils

# module app.utils.test
class SharedTest(TestCase):
    def test_foo(self):
        # Rest of the test body.

# module app.tests
from app.utils import test
class OneTestCase(test.SharedTest):
    ...
于 2010-08-31T04:46:10.170 に答える