2010-11-30 20 views
9

Bazı değişmezleri paylaşan ve ortak bir arabirime sahip birkaç sınıfım var ve her biri için aynı testi otomatik olarak çalıştırmak istiyorum. Örnek olarak, bir veri kümesinin bölümlendirilmesi için farklı yaklaşımlar uygulayan birkaç sınıfa sahip olduğumu varsayalım. Buradaki ortak değişmez, bütün bu sınıflar için tüm bölümler üzerindeki kaynağın orijinal veri kümesine eşit olması gerektiği olurdu. Farklı sınıflar için aynı deneme vakası nasıl çalıştırılır?

class PartitionerInvariantsTests(unittest.TestCase): 
    def setUp(self): 
     self.testDataSet = range(100) # create test-data-set 

    def impl(self, partitioner): 
     self.assertEqual(self.testDataSet, 
         chain.from_iterable(partitioner(self.testDataSet)) 

O zaman bu sınıfın bir örneği ile test etmek istediğiniz sınıfların her biri için impl çağıran farklı bir işlevi ekleyin:

Şu anda ne var böyle bir şey görünüyor. Birden fazla test fonksiyonu için bunu yaparken sorun ortaya çıkıyor. 5 test fonksiyonum ve test etmek istediğim 5 sınıfa sahip olduğumu varsayalım. Bu, tüm testleri çağırmak için neredeyse aynı görünen 25 işlevi gerçekleştirir.

Düşündüğüm başka bir yaklaşım, şablonu süper sınıf olarak uygulamak ve sonra test etmek istediğim sınıfların her biri için bir alt sınıf oluşturmaktı. Alt sınıflar, sınıfın başlatılması için bir işlev sağlayabilir. Buradaki sorun, varsayılan test yükleyicinin (kullanışsız) temel sınıfın geçerli bir test vakası olduğunu düşünmesi ve bunu çalıştırmayı denemesidir ki bu başarısız olur.

Peki, önerileriniz nelerdir? Test etmek istediğiniz her Partitioner sınıf için

class PartitionerInvariantsTests(unittest.TestCase): 
    def test_impl(self): 
     self.assertEqual(self.testDataSet, 
         chain.from_iterable(self.partitioner(self.testDataSet)) 

class PartitionerATests(PartitionerInvariantsTests): 

:

P.S. .: Ben Python 2.6

+1

unittest o 'unittest.TestCase' devralan etmezse temel sınıfa çalıştırmayı dener misin? – nmichaels

+0

@Nathon: Şimdi söylüyorsun, bunu henüz denemedim. –

+0

@Nathon, fikrinizi bir yanıt olarak göndermek isterseniz, ben de mutlu bir şekilde benimkini sileceğim. – unutbu

cevap

11

Birden kullanabilirsiniz: Nathon yorumuyla ilgili takibi

, bunu object sadece miras alarak test edilmesini temel sınıfını önleyebilir miras.

class PartitionerInvariantsFixture(object): 
    def setUp(self): 
     self.testDataSet = range(100) # create test-data-set 
     super(PartitionInvariantsFixture, self).setUp() 

    def test_partitioner(self): 
     TestCase.assertEqual(self.testDataSet, 
        chain.from_iterable(self.partitioner(self.testDataSet)) 

class MyClassTests(TestCase, PartitionerInvariantsFixture): 
    partitioner = Partitioner 
+0

zincir yineleyici listeyi kullanarak muhtemelen yinelenmelidir (zincir ...) – kevpie

+3

Neden kurulumda süper aramak gerekiyor? – dylam

+0

+1 Çeneüm düştü. SO üzerinde benzer soruların düzinelerce var (aynı testleri, çekirdek çekirdeği olmayan farklı nesnelerde çalıştırıyor), ama bu kesinlikle bulduğum en iyi cevap. Python'un birden fazla mirasa sahip olduğunu bile bilmiyordum (veya hatırlamıyordum). –

0

alt sınıf PartitionerInvariantsTests kullanıyorum. Daha sonra, her Partitioner sınıfı için miras yoluyla test_impl çalıştırılacaktır.

import unittest 

class Test(object): 
    def test_impl(self): 
     print('Hi') 

class TestA(Test,unittest.TestCase): 
    pass 

class TestB(Test,unittest.TestCase): 
    pass 

if __name__ == '__main__': 
    unittest.sys.argv.insert(1,'--verbose') 
    unittest.main(argv = unittest.sys.argv)  

Running test.py verimleri

test_impl (__main__.TestA) ... Hi 
ok 
test_impl (__main__.TestB) ... Hi 
ok 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

OK 
+2

Evet, ancak temel sınıf da çalıştırılacak ve başarısız olacak. Alt sınıfları çalıştırmanın bir yolu var mı, taban sınıfı değil mi? –

İlgili konular