3

unittestを使用したテスト スイートを含む JSON パーサー ライブラリ ( ijson ) があります。ライブラリには、実際にはいくつかの解析実装 (「バックエンド」) が、同一の API を持つモジュールの形式で含まれています。利用可能なバックエンドごとに、テスト スイートを数回自動的に実行したいと考えています。私の目標は次のとおりです。

  • バックエンドに依存しないため、すべてのテストを 1 か所に保持したいと考えています。
  • テストが失敗したときに、現在使用されているバックエンドの名前が何らかの方法で表示されるようにします。
  • unittest で通常許可されているように、単一の TestCase または単一のテストを実行できるようにしたいと考えています。

では、このためにテスト スイートを構成する最善の方法は何でしょうか? カスタム テスト ランナーを作成しますか? TestCases にバックエンド自体をロードさせますか? バックエンドごとに個別の TestCase クラスを命令的に生成しますか?

ところで、私は特に unittest ライブラリと結婚していません。問題が解決する場合は、別のライブラリを試してみることにオープンです。ただし、テスト コードは既に用意されているため、unittest を使用することをお勧めします。

4

2 に答える 2

1

一般的な方法の 1 つは、バックエンドのインスタンスを作成する (テストで複数のインスタンスを作成する必要がある場合)、またはsetUpバックエンドのインスタンスを作成することを期待する抽象メソッドを使用して、すべてのテストを 1 つのクラスにグループ化することです。

その後、必要に応じてさまざまなバックエンドを作成するサブクラスを作成できます。

サブクラスを自動的に検出するテスト ローダーを使用している場合はTestCase、おそらく 1 つの変更を加える必要があります: 共通の基本クラスを のサブクラスにしないでTestCaseください: 代わりにそれを mixin として扱い、バックエンド クラスを と の両方からサブクラス化しますTestCase。ミックスイン。

例えば:

class BackendTests:
    def make_backend(self):
        raise NotImplementedError

    def test_one(self):
        backend = self.make_backend()
        # perform a test on the backend

class FooBackendTests(unittest.TestCase, BackendTests):
    def make_backend(self):
        # Create an instance of the "foo" backend:
        return foo_backend

class BarBackendTests(unittest.TestCase, BackendTests):
    def make_backend(self):
        # Create an instance of the "bar" backend:
        return bar_backend

上記からテスト スイートを構築すると、独立したテスト ケースが作成FooBackendTests.test_oneBarBackendTests.test_oneれ、2 つのバックエンドで同じ機能がテストされます。

于 2012-10-15T02:51:04.450 に答える
1

James Henstridge のアイデアをすべてのテストを保持する mixin クラスで採用しましたが、バックエンドがインポート時に失敗する可能性があるため、実際のテスト ケースは命令的に生成されます。

class BackendTests(object):
    def test_something(self):
        # using self.backend 

# Generating real TestCase classes for each importable backend
for name in ['backend1', 'backend2', 'backend3']:
    try:
        classname = '%sTest' % name.capitalize()
        locals()[classname] = type(
            classname,
            (unittest.TestCase, BackendTests),
            {'backend': import_module('backends.%s' % name)},
        )
    except ImportError:
        pass
于 2012-10-16T07:44:41.083 に答える