2013-09-30 10 views
7

Unittest.testcase sınıfını alt sınıflara ayırarak özel birim sınama çerçevesi oluşturmaya çalışıyorum ancak __init__ yöntemiyle çalışırken bir hata yapıyor gibi görünüyor.python'da unittest.testcase yüklemesi

ComplexTest kurucusunun neden BasicTest numaralı telefondan neden alınmadığını anlayamıyorum ve istisna da kurucularla ilgili görünüyor.

Python'a oldukça yeni geldim, bu nedenle bu sorun veya alternatif mimarileri kullanım durumumun nasıl çözüleceğine dair herhangi bir yardım en hoş karşılanacaktır.

Teşekkür ederiz!

1) test_framework.py

import unittest 

class BasicTest(unittest.TestCase): 
    def __init__(self, *args, **kwargs): 
     print('BasicTest.__init__') 
     super(unittest.TestCase, self).__init__(*args, **kwargs) 

    def setUp(self): 
     print('BasicTest.setUp') 
     super(unittest.TestCase, self).tearDown() 

    def tearDown(self): 
     print('BasicTest.tearDown') 
     super(unittest.TestCase, self).tearDown() 


class ComplexTest(BasicTest): 
    def __init__(self, *args, **kwargs): 
     print('ComplexTest.__init__') 
     super(BasicTest, self).__init__(*args, **kwargs) 

    def setUp(self): 
     print('ComplexTest.setUp') 
     super(BasicTest, self).tearDown() 

    def tearDown(self): 
     print('ComplexTest.tearDown') 
     super(BasicTest, self).tearDown() 

2) test.py

import unittest 
import test_framework 

class TestValueFunctions(test_framework.ComplexTest): 
    def __init__(self, *args, **kwargs): 
     print('TestValueFunctions.__init__') 
     super(test_framework.ComplexTest, self).__init__(*args, **kwargs) 

    def setUp(self): 
     print('TestValueFunctions.setUp') 
     super(test_framework.ComplexTest, self).tearDown() 
     self.value = 4711 

    def tearDown(self): 
     print('TestValueFunctions.tearDown') 
     super(test_framework.ComplexTest, self).tearDown() 

    def test_value(self): 
     print('TestValueFunctions.test_value') 
     self.assertEqual(self.value, 4711) 

if __name__ == '__main__': 
    unittest.main() 

3) şimdi çalıştırmak için çalışırken, i aşağıdaki yığın bakınız

TestValueFunctions.__init__ 
BasicTest.__init__ 
Traceback (most recent call last): 
    File "D:\MyDev\ljs_app\trunk\examples\python\unittest\test.py", line 23, in <module> 
    unittest.main() 
    File "C:\Python27\lib\unittest\main.py", line 94, in __init__ 
    self.parseArgs(argv) 
    File "C:\Python27\lib\unittest\main.py", line 149, in parseArgs 
    self.createTests() 
    File "C:\Python27\lib\unittest\main.py", line 155, in createTests 
    self.test = self.testLoader.loadTestsFromModule(self.module) 
    File "C:\Python27\lib\unittest\loader.py", line 65, in loadTestsFromModule 
    tests.append(self.loadTestsFromTestCase(obj)) 
    File "C:\Python27\lib\unittest\loader.py", line 56, in loadTestsFromTestCase 
    loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) 
    File "D:\MyDev\ljs_app\trunk\examples\python\unittest\test.py", line 7, in __init__ 
    super(test_framework.ComplexTest, self).__init__(*args, **kwargs) 
    File "D:\MyDev\ljs_app\trunk\examples\python\unittest\test_framework.py", line 6, in __init__ 
    super(unittest.TestCase, self).__init__(*args, **kwargs) 
TypeError: object.__init__() takes no parameters 
+0

biri yapmak olduğunu ** değil ** açıkça üst sınıf devlet zorunda. Hatalarda gördüğünüz gibi, bu kodla 'TestCase .__ init__' yerine' object .__ init__' diyorsunuz. – Bakuriu

+1

Sadece Python 3'te sınıf argümanını "süper" olarak atlayabilirsiniz. – chepner

cevap

17

Gerçekten de init yönteminiz yanlış.

class BasicTest(unittest.TestCase): 
    def __init__(self, *args, **kwargs): 
     print('BasicTest.__init__') 
     super(unittest.TestCase, self).__init__(*args, **kwargs) 

olmalı:

class BasicTest(unittest.TestCase): 
    def __init__(self, *args, **kwargs): 
     print('BasicTest.__init__') 
     super(BasicTest, self).__init__(*args, **kwargs) 

Bu TestCase olan BasicTest annesi sınıfı üzerinde __init__ arayacak. Bu kurulum ve ayırma aynıdır:

super` `büyük avantajlarından
class BasicTest(unittest.TestCase): 
    ... 
    def setUp(self): 
     print('BasicTest.setUp') 
     super(BasicTest, self).setUp() 
+0

Mükemmel: Ben süper yanlış anlaşıldım gibi görünüyor ama şimdi bir çekicilik gibi çalışır. Teşekkür ederim! – doberkofler

+0

setUp örneğinin son satırı şöyle olmalıdır: 'super (BasicTest, self) .setUp()'. Şu anda mantık olmayan tearDown ana yöntemini çağırır.Soru kodu örnekleri için aynı. – manelvf

0

Ah super! Kim bilir neden bir şey yapar. Eğer üst sınıfını Testinizdeki kullanmaktan ve bunun yerine açıkça çağrı durdurmak Eğer bu gibi istediğiniz:

TestValueFunctions.__init__ 
ComplexTest.__init__ 
TestValueFunctions.setUp 
ComplexTest.setUp 
TestValueFunctions.test_value 
TestValueFunctions.tearDown 
ComplexTest.tearDown 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 

Bkz: Python's Super is nifty, but you can't use it

class BasicTest(unittest.TestCase): 
    def __init__(self, *args, **kwargs): 
     print('BasicTest.__init__') 
     unittest.TestCase.__init__(self, *args, **kwargs) 

Aşağıdaki çıkışı ile bitireceğiz

+0

Bu, yalnızca birden fazla kalıtımın bir parçası olmasını beklememeniz durumunda geçerlidir; Aksi takdirde, bu durumları kırıp potansiyel olarak beklenmedik davranışlara neden olacaktır. –

+0

Hiçbir şey bozmaz. Özellikle de 'unittest.TestCase' süper kullanılmadığı için. Bu, aramak istediğiniz sırayla istediğiniz kodu açıkça çağırmaktır. – aychedee

+0

Doğru değil, eğer bu sınıfın alt sınıfı olan "unittest.TestCase" alt sınıfının hem bu sınıfa hem de başka bir yönteme göre başka bir yönteme sahip olması durumunda başka bir yöntem varsa, sorunlu olur. Belki bu durumda daha az, ama daha genel olarak iyi bir seçim değildir (özellikle de nesnenin doğrudan bir alt sınıfı ise) –