2015-11-03 17 views
5

Khi có sự chồng chéo đáng kể trong quá trình thiết lập thử nghiệm, nó có thể giữ mọi thứ KHẢ NĂNG sử dụng kế thừa. Nhưng điều này gây ra các vấn đề với sự trùng lặp không cần thiết thực hiện kiểm tra:Tại sao các bài kiểm tra trong các lớp dẫn xuất chạy lại các bài kiểm tra lớp cha mẹ?

from unittest import TestCase 

class TestPotato(TestCase): 
    def test_in_parent(self): 
     print 'in parent' 

class TestSpud(TestPotato): 
    def test_in_child(self): 
     print 'in child' 

kiểm tra module này chạy test_in_parent hai lần.

$ python -m unittest example 
in parent 
.in child 
.in parent 
. 
---------------------------------------------------------------------- 
Ran 3 tests in 0.000s 

OK 

Tại sao? Đây có phải là do thiết kế không? Nó có thể được vô hiệu hóa bằng cách cấu hình các Á hậu thử nghiệm một cách nhất định?

Tôi có thể khắc phục sự cố bằng cách di chuyển thiết lập vào lớp không được khám phá và sau đó sử dụng nhiều tính kế thừa, nhưng có vẻ như hơi bị hack và không cần thiết.

lưu ý: Cùng một vấn đề xảy ra ở vận động viên khác như mũi (nosetests -s example.py) và pytest (py.test example.py)

+2

Bởi vì họ kế thừa phương pháp thử nghiệm của cha mẹ, vì vậy khi 'unittest' trông qua' dir' của họ (hoặc '__dict__' hoặc bất cứ điều gì nó) cho các phương thức bắt đầu 'test_' nó cũng tìm ra các phương thức kế thừa. Tôi không nghĩ rằng việc giải quyết điều này đòi hỏi sự thừa kế * nhiều *; trừu tượng những gì cả hai cần đến một lớp thứ ba, không thể khám phá mà không có phương thức 'test_' và có cả hai đều thừa hưởng nó. – jonrsharpe

+0

Nhìn vào một lớp con có một lớp cha có chứa các phương thức được đặt trước bằng kiểm tra sẽ hiển thị lớp con với các phương thức đó. Đây là OOP trăn. Tôi không nghĩ rằng việc chuyển các phương thức thiết lập thành mixin hay là một lớp cơ sở riêng biệt có vẻ như là hacky và có lẽ là DRYer – dm03514

+0

Dường như một trường hợp sử dụng tuyệt vời cho các mixin cho các nhóm khác nhau. ..tree-inheritance không giống như mô hình phù hợp ở đây. – Shashank

Trả lời

3

chạy thử nghiệm tìm kiếm của tất cả các phương pháp bắt đầu với test. Các phương thức kế thừa có mặt trong lớp con - do đó chúng được phát hiện như là các phép thử để chạy. Để tránh điều đó, bạn nên trích xuất mã chung trong lớp cha và không kế thừa bất kỳ thử nghiệm thực tế nào.

from unittest import TestCase 

class PotatoTestTemplate(TestCase): 
    def setUp(): 
     pass 

class PotatoTest1(PotatoTestTemplate): 
    def test1(self): 
     pass 

class PotatoTest2(PotatoTestTemplate): 
    def test1(self): 
     pass 
+0

Vâng, tôi biết về cách giải quyết này và đã sử dụng nó trong quá khứ. Nhưng tôi không thích nó! – wim

+0

Tôi đã giải quyết trên một mẫu tương tự như thế này - thay vì 'PotatoTestTemplate' tôi sử dụng một' PotatoSetup (đối tượng) '. Nó không phải là một 'TestCase', nó giống như một mixin. Sau đó, tôi sử dụng 'PotatoTest (PotatoSetup, TestCase)' và 'SpudTest (PotatoSetup, TestCase)' với thiết lập thêm trong một trong hai bài kiểm tra nếu tôi cần nó. – wim

1

Một cách giải quyết khác mà tôi đã thấy mọi người sử dụng là các lớp lồng nhau sẽ không chạy như một phần của nosetests, ví dụ:

from unittest import TestCase 
class NotTested: 
    class TestPotato(TestCase): 
     def test_in_parent(self): 
      print 'in parent' 

class TestSpud(NotTested.TestPotato): 
    def test_in_child(self): 
     print 'in child' 

Một workaround tôi không thành công cố gắng là sử dụng đa kế thừa vì vậy lớp TestPotato mở rộng đối tượng và TestSpud không mở rộng từ TestCase và TestPotato ví dụ

from unittest import TestCase 

class TestPotato(object): 
    def test_in_parent(self): 
     # still gets ran twice because 
     # nosetests runs anything that starts with test_* :(
     print 'in parent' 

class TestSpud(TestCase, TestPotato): 
    def test_in_child(self): 
     print 'in child' 

Nhưng điều này thực sự không làm việc cho tôi, tôi muốn nó đã làm bởi vì bạn sẽ không cần làm tổ thêm mã ... nhưng có vẻ như sử dụng multiple inheritance is bad anyway

1

Nếu thử nghiệm cài đặt từ một lớp học thử nghiệm khác nhau là tất cả các bạn cần, bạn có thể làm điều này:

from unittest import TestCase 

class TestPotato(TestCase): 
    def setUp(self): 
     print('fixtures here') 

    def test_in_parent(self): 
     print 'in parent' 


class TestSpud(TestCase): 
    def setUp(self): 
     TestPotato.setUp(self) 

    def test_in_child(self): 
     print 'in child' 
Các vấn đề liên quan