2010-05-26 33 views
6

Tôi hiện đang học python trong preperation cho một lớp học trong mùa hè và đã bắt đầu bằng cách thực hiện các loại heaps và cấu trúc dữ liệu dựa trên ưu tiên.Đơn vị kiểm tra giao diện trong Python

Tôi bắt đầu viết một bộ kiểm thử đơn vị cho dự án nhưng gặp khó khăn trong việc tạo ra một thử nghiệm đơn vị chung mà chỉ kiểm tra giao diện và không biết thực hiện thực tế.

Tôi tự hỏi nếu nó có thể làm điều gì đó như thế này ..

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

gì Tôi hiện đang làm chỉ cảm thấy ... sai (đa kế thừa? 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() 

Trả lời

4

Cá nhân tôi thích nose test generation nhiều hơn cho loại điều này. Sau đó tôi sẽ viết như sau:

# 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

Tôi không nghĩ rằng mô hình trên là khủng khiếp, nhưng nhiều thừa kế chắc chắn không phải là ý tưởng.

Tôi đoán lý do bạn không thể chỉ có TestHeap là một lớp con của TestCase là vì nó sẽ tự động được chọn và chạy thử nghiệm, không biết rằng nó cần phải được phân lớp.

tôi đã nhận được xung quanh vấn đề này theo hai cách khác:

  1. Thay vì thêm test_ chức năng, có phương pháp ghi mà không tự động được nhặt, sau đó thêm thử nghiệm() cho mỗi lớp con của bạn. Rõ ràng không lý tưởng.
  2. Viết lại unittest để không hút, cho phép tùy chọn đặt __test__ = False thành lớp cơ sở. (Xem Testify)
1

Tại sao không chỉ sử dụng bí danh cho lớp bạn muốn kiểm tra? Bạn có thể viết lớp thử nghiệm của bạn đề cập đến một HeapImpl lớp giả, và sau đó gán một thực hiện cụ thể để nó trước mỗi lần chạy thử nghiệm:

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) 

Chừng nào họ tuân thủ các giao diện bạn đang sử dụng trong các bộ kiểm tra, điều này sẽ hoạt động tốt. Ngoài ra, bạn có thể dễ dàng kiểm tra nhiều triển khai tùy thích, chỉ cần thêm chúng vào danh sách heaps.

Các vấn đề liên quan