Интерфейсы поблочного тестирования в Python

Я в настоящее время изучаю 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()
6
задан Nicholas Mancuso 26 May 2010 в 17:23
поделиться

3 ответа

Лично мне больше нравится поколение тестов носа для подобных вещей. Тогда я бы написал это так:

# 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_')]
4
ответ дан 17 December 2019 в 00:04
поделиться

Почему бы просто не использовать псевдоним для класса, который вы хотите протестировать? Вы можете написать свой тестовый класс, ссылаясь на поддельный класс 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)

Если они соответствуют интерфейсу, который вы используете в тесте Suite, это должно работать нормально. Кроме того, вы можете легко протестировать столько реализаций, сколько захотите, просто добавьте их в список heaps .

2
ответ дан 17 December 2019 в 00:04
поделиться

Я не думаю, что вышеприведенный шаблон ужасен, но множественное наследование - это, конечно, не идея.

Я думаю, причина, по которой вы не можете просто сделать TestHeap подклассом TestCase, в том, что он будет автоматически подхвачен и запущен как тест, не зная, что он должен быть подклассом.

Я обошел эту проблему двумя другими способами:

  1. Вместо того, чтобы добавлять функции test_, напишите методы, которые не будут автоматически подхватываться, а затем добавьте test() в каждый из ваших подклассов. Очевидно, не идеальный вариант.
  2. Переписал unittest, чтобы он не был отстойным, позволяя установить __test__ = False для базового класса. (См. Testify)
1
ответ дан 17 December 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: