2012-08-22 14 views
0

파이썬 2.7의 새로운 발견 기능을 사용하여, 나는 이상한 오류를 받고 있어요. 약간의 추가 설정과 파일의 일부 구성원 데이터가 필요한 단위 테스트가 있습니다. load_tests()에 전달 된 현재 테스트 스위트에 설치 테스트 케이스를 추가하려고합니다. 테스트 스위트 tests 이미 (현재 모듈에서 TestCase 객체 포함) 표준 테스트가 포함되어 있기 때문에 단, 자동으로 추가 테스트 케이스에 대한 적절한 설정이 완료와 나는 AttributeError를 얻을 수 없습니다. 아래 코드 이상한 행동

load_tests()는 CSV 파일 데이터의 각 행에 대해 하나의 테스트 케이스를 생성하는데 사용된다. 파일에는 세 줄이 있지만 어떤 이유로 4 번째 테스트 사례가 만들어지고 있습니다.

#!/usr/bin/python 
import unittest 

class Foo(unittest.TestCase):  
    def setup(self,bar): 
     print "Foo.setup()" 
     self.bar = bar 
    def runTest(self): 
     print self.bar 

def load_tests(loader, tests, pattern): 
    f = open('data.csv') # data.csv contains three lines: "a\nb\nc" 
    for line in f: 
     tc = Foo() 
     tc.setup(line) 
     tests.addTest(tc) 
    return tests 

unittest.main() 

이 코드를 실행하면 결과에 4 개의 테스트가 실행되었고 그 중 하나는 실패한 것으로 나타납니다. 데이터 파일에는 세 줄만 포함되어 있으며 Foo.setup()은 세 번만 호출되었습니다. 따라서 load_tests()은 설계된대로 세 개의 테스트 케이스를 생성했습니다.

Foo.setup() 
Foo.setup() 
Foo.setup() 
Ea 

.b 

.c 

. 
====================================================================== 
ERROR: runTest (__main__.Foo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "./foo.py", line 11, in runTest 
    print self.bar 
AttributeError: 'Foo' object has no attribute 'bar' 

---------------------------------------------------------------------- 
Ran 4 tests in 0.002s 

스위트에 자동으로로드 된 TestCase를 제거 할 수있는 방법이 있습니까? 이미 존재하는 다른 모든 테스트가 필요하기 때문에 새로운 빈 TestSuite를 만들 수 없습니다. 이 테스트를 스위트에 추가하기 만하면됩니다.

편집 : 내 질문 및 코드 예제를 명확히. 나는 조금 모호했다.

답변

0

은 당신이 할 수있는 몇 가지 방법이 있습니다. 당신은 항상 푸를 인스턴스화하려는 경우

, 당신은 클래스의 __init__ 방법에 줄을 설정할 수 있습니다.

class Foo(unittest.TestCase): 
    def __init__(self, bar, *args, **kwargs): 
     super(Foo, self).__init__(*args, **kwargs) 
     self.bar = bar 
    def runTest(self): 
     print self.bar 

f = Foo("some string") 

내가 직접하기 전에 load_tests 패턴을 사용하지 않은 - 나는 대개 코의 자동 테스트 발견에 의존,하지만이 모든 당신의 설정에 작동합니다. 나중에 TestSuite s와 unittest/nose의 테스트 자동 검색을 사용하고 싶었 클래스를 사용하고 싶다면, 당신은 클래스 팩토리 사용할 수 있습니다

def make_foo_case(the_bar): 
    class Foo(unittest.TestCase): 
     bar = the_bar 
     def runTest(self): 
      print self.bar 
    return Foo 

f = (make_testcase("some string"))() 

또는 foo는 서브 클래스 type을 사용하고있는 요소를 설정 회원들, 예를 들어, (이전 본질적으로 동일) :

class Foo2(object): 
    def runTest(self): 
     print self.bar 

f = (type("Tester2", (Foo2,unittest.TestCase), {"bar":"some string"}))() 
+0

답장을 보내 주셔서 감사합니다. 그러나 문제가 해결되지 않았습니다. 제 질문에 대해 명확하지 않은 것 같아요. 그래서 그것을 편집하고 더 자세한 코드를 추가했습니다. – Rusty

+0

@Rusty, 클래스의'__init__' 메소드를 사용하여 객체에 막대를 추가하려고하면 실제로 어떻게됩니까? 여전히 동일한 오류가 표시됩니까? 그런 식으로 unittest가 여분의 테스트 케이스를 선택해서는 안됩니다. ("추가 테스트 케이스"로 질문하시는 것이 무엇인지에 대해 100 % 확신하지 못했습니다) –

+0

"추가 테스트 케이스"가 무엇을 의미하는지 설명하겠습니다.'load_tests()'함수는'data.csv' 파일에있는 각 데이터 행에 대해 하나의 테스트를 세 번 수행해야합니다. 그러나 4 개의 테스트가 생성되어 실행됩니다. 그 중 하나는 일반 테스트 로더를 통해 자동으로 추가 된 테스트 케이스입니다. 'load_tests()'가 존재한다는 것이 정상적인 테스트 케이스 로딩을 완전히 불가능하게한다는 것을 이해했다. 하지만 분명히 나는 ​​오해하고있다. – Rusty

0

은 분명히 나는 ​​load_tests() 오해. /usr/lib/python2.7/unittest/loader.py의 Python 코드에 따르면 테스트는 정상적으로 모듈에서로드됩니다. 그런 다음 load_tests()이 있으면 호출됩니다.

def loadTestsFromModule(self, module, use_load_tests=True): 
    """Return a suite of all tests cases contained in the given module""" 
    tests = [] 
    for name in dir(module): 
     obj = getattr(module, name) 
     if isinstance(obj, type) and issubclass(obj, case.TestCase): 
      tests.append(self.loadTestsFromTestCase(obj)) 

    load_tests = getattr(module, 'load_tests', None) 
    tests = self.suiteClass(tests) 
    if use_load_tests and load_tests is not None: 
     try: 
      return load_tests(self, tests, None) 
     except Exception, e: 
      return _make_failed_load_tests(module.__name__, e, 
              self.suiteClass) 
    return tests 

그래서 제 솔루션은 생성 된 추가 테스트 사례를 수락하고 확인한 다음 전달하는 것입니다. Jeff가 나를 도우려는 것에 대해 대단히 감사합니다.