2010-05-26 6 views
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

개인적으로는 이런 종류의 경우에 nose test generation을 더 좋아합니다. 그러면 다음과 같이 작성합니다.

# 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_')] 
1

나는 위의 패턴이 끔찍하다고 생각하지 않지만 다중 상속은 확실히 생각이 아닙니다.

당신이 TestHase를 TestCase의 하위 클래스로 만들 수없는 이유는 그것이 자동으로 선택되어 테스트로 실행되고 서브 클래 싱해야한다는 것을 모르기 때문입니다.

  1. , 자동으로 선택되지 않는 쓰기 방법이 오히려 TEST_ 기능을 추가하는 대신, 다음 추가 테스트() 당신의 서브 클래스의 각 :

    나는이 문제를 해결 두 가지 다른 방법을 입수했습니다. 분명 이상적이지 않습니다.

  2. unittest를 빨지 말고 다시 작성하여 __test__ = False을 기본 클래스로 설정하는 옵션을 허용합니다. (Testify 참조)
1

테스트 할 클래스에 별칭을 사용하지 않는 이유는 무엇입니까? 당신은 가짜 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 목록에 추가하면됩니다.