2013-09-30 5 views
7

unittest.testcase 클래스를 하위 클래스로 분류하여 사용자 정의 단위 테스트 프레임 워크를 만들려고 시도했지만 __init__ 메서드를 처리 할 때 실수를 한 것 같습니다.python에서 unittest.testcase을 오버로드합니다.

에있는 생성자보다 먼저 ComplexTest 생성자가 호출되지 않고 예외가 생성자와 관련되어있는 것 같습니다.

나는이 특별한 문제를 해결하는 방법에 대한 도움이나 나의 유스 케이스에 대한 대체 아키텍처를 가장 환영 할 것입니다.

감사합니다.

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) 지금을 실행하려고, 나는 다음과 같은 스택을 참조

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

'슈퍼'의 큰 장점 중 하나는 슈퍼 클래스를 명시 적으로 지정하지 않아도된다는 것입니다. 오류에서 알 수 있듯이 그 코드로'TestCase .__ init__' 대신'object .__ init__'을 호출하고 있습니다. – Bakuriu

+1

Python 3에서만 'super'에 대한 클래스 인수를 생략 할 수 있습니다. – chepner

답변

17

실제로 init 메서드가 잘못되었습니다.

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

은 다음과 같아야합니다

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

이의 TestCase이다 BasicTest의 어머니 클래스에 __init__를 호출합니다. 이것은 setUp과 tearDown에 대해서도 동일합니다 :

class BasicTest(unittest.TestCase): 
    ... 
    def setUp(self): 
     print('BasicTest.setUp') 
     super(BasicTest, self).setUp() 
+0

우수 : 오해가있는 것 같습니다.하지만 지금은 매력처럼 작동합니다. 고맙습니다! – doberkofler

+0

setUp 예제의 마지막 줄은'super (BasicTest, self) .setUp()'이어야합니다. 지금은 tearDown 부모 메서드를 호출합니다.이 메서드는 논리가 아닙니다.질문 코드 샘플도 마찬가지입니다. – manelvf

0

Ah super! 누가 왜 그 일을하는지 알지. 상위 클래스를 테스트에서 사용하는 대신 명시 적으로 전화를 중지하면이 같은하려는 :

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

OK 

참조 : 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) 

당신은 아래에 출력 될 겁니다

+0

다중 상속의 일부가 될 것으로 예상하지 않는 경우에만 해당됩니다. 그렇지 않으면 일이 중단되고 예기치 않은 동작이 발생할 수 있습니다. –

+0

그것은 물건을 부수 지 않는다. 특히'unittest.TestCase'는 super를 사용하지 않기 때문에 특히 그렇습니다. 호출하려는 순서대로 원하는 코드를 명시 적으로 호출하는 경우입니다. – aychedee

+0

이 클래스와이 클래스에 대한 직접 부모로 'unittest.TestCase'를 서브 클래스하는 또 다른 클래스가 있거나이 클래스가 다른 메소드보다 먼저 mro에서 끝나는 다른 클래스가 있다면 문제가 될 것입니다. 어쨌든이 특별한 경우에는 더 적을 지 모르지만 더 일반적으로 좋은 선택은 아닙니다 (특히 객체의 직접 하위 클래스 인 경우) –