6

私は現在、夏のクラスの準備として python を学んでおり、さまざまな種類のヒープと優先度に基づくデータ構造を実装することから始めました。

私はプロジェクトの単体テスト スイートを書き始めましたが、インターフェイスのみをテストし、実際の実装を忘れる一般的な単体テストを作成するのに苦労しました。

私はこのようなことをすることが可能かどうか疑問に思っています..

suite = HeapTestSuite(BinaryHeap())
suite.run()
suite = HeapTestSuite(BinomialHeap())
suite.run()

私が現在行っていることは...間違っていると感じています(多重継承? ACK!)..

class TestHeap:

    def reset_heap(self):
        self.heap = None

    def test_insert(self):
        self.reset_heap()
        #test that insert doesnt throw an exception...
        for x in self.inseq:
            self.heap.insert(x)


    def test_delete(self):
        #assert we get the first value we put in
        self.reset_heap()
        self.heap.insert(5)
        self.assertEquals(5, self.heap.delete_min())

        #harder test. put in sequence in and check that it comes out right
        self.reset_heap()
        for x in self.inseq:
            self.heap.insert(x)

        for x in xrange(len(self.inseq)):
            val = self.heap.delete_min()
            self.assertEquals(val, x)

class BinaryHeapTest(TestHeap, unittest.TestCase):
    def setUp(self):
        self.inseq = range(99, -1, -1)
        self.heap = BinaryHeap()

    def reset_heap(self):
        self.heap = BinaryHeap()

class BinomialHeapTest(TestHeap, unittest.TestCase):
    def setUp(self):
        self.inseq = range(99, -1, -1)
        self.heap = BinomialHeap()

    def reset_heap(self):
        self.heap = BinomialHeap()


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

3 に答える 3

4

I personally like nose test generation more for this sort of thing. I'd then write it like:

# They happen to all be simple callable factories, if they weren't you could put
# a function in here:
make_heaps = [BinaryHeap, BinomialHeap]

def test_heaps():
    for make_heap in make_heaps:
        for checker in checkers: # we'll set checkers later
            yield checker, make_heap

def check_insert(make_heap):
    heap = make_heap()
    for x in range(99, -1, -1):
        heap.insert(x)

# def check_delete_min etc.

checkers = [
    value
    for name, value in sorted(globals().items())
    if name.startswith('check_')]
于 2010-05-26T20:09:48.930 に答える
2

テストしたいクラスのエイリアスを使用しないのはなぜですか? 偽のクラスを参照するテスト クラスを作成し、HeapImpl各テストを実行する前に特定の実装をそれに割り当てることができます。

class TestHeap(unittest.TestCase):
    def setUp(self):
        self.heap = HeapImpl()
    #test cases go here

if __name__ == '__main__'
    suite = unittest.TestLoader().loadTestsFromTestCase(TestHeap)
    heaps = [BinaryHeap, BinomialHeap]
    for heap in heaps:
        HeapImpl = heap
        unittest.TextTestRunner().run(suite)

テスト スイートで使用しているインターフェイスに準拠している限り、これは正常に機能するはずです。また、リストに追加するだけで、必要な数の実装を簡単にテストできますheaps

于 2010-05-26T18:45:05.710 に答える
1

上記のパターンはひどいとは思いませんが、多重継承は確かに考えられません。

TestHeap を TestCase のサブクラスにすることができない理由は、サブクラス化する必要があることを知らずに、自動的に選択されてテストとして実行されるためだと思います。

私はこの問題を他の 2 つの方法で回避しました。

  1. test_ 関数を追加するのではなく、自動的に取得されないメソッドを作成してから、各サブクラスに test() を追加します。明らかに理想的ではありません。
  2. unittest をサックしないように書き直し__test__ = Falseて、基本クラスに設定するオプションを許可しました。(証言を参照)
于 2010-05-26T17:30:45.540 に答える