2011-08-24 4 views
13

나는 형식 유닛 테스트 표준에서 테스트 모듈이 실패실행 파이썬 유닛 테스트에 아무것도 인쇄되지 않도록 성공하는 경우에만 AssertionError를()하는 경우가

class my_test(unittest.TestCase): 

    def test_1(self): 
     [tests] 

    def test_2(self): 
     [tests] 
    etc.... 

우리 회사가 나의 모듈을 실행하는 독자적인 테스트 환경을 가지고 명령 줄 스크립트 및 내 모듈에서 발생하는 오류를 catch하지만 성공하면 내 모듈이 음소거되어야합니다.

내 테스트 모듈을 실행하여 모든 테스트가 통과하면 아무 것도 화면에 출력되지 않고 테스트가 AssertionError로 실패하면 오류가 표준 파이썬 오류 스택 (다른 모든 오류와 같은 일반 파이썬 스크립트에서와.)

처럼 주어진 모듈에서 모든 테스트를 실행하기 위해 unittest.main() 함수를 사용하는 docs 옹호

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

문제는 이것이 unittest의 하네스에서 테스트 결과를 래핑하므로 모든 테스트가 성공적 일지라도 여전히 pr ints 화면에 약간의 오류가 있고, 오류가있는 경우 일반적인 파이썬 오류로 단순히 덤프되지 않고 하네스에 옷을 입습니다. 여기

with open('.LOG','a') as logf: 
    suite = unittest.TestLoader().loadTestsFromTestCase(my_test) 
    unittest.TextTestRunner(stream = logf).run(suite) 

문제를 사용하여 대체 스트림에 출력을 리디렉션 시도했습니다

모든 것이 (모든 오류 통지 포함) 로그 파일에 파이프됩니다 있다는 것입니다. 따라서 회사에서 모듈을 실행하면 완료 될 수있는 한 오류가 발생하지 않았기 때문에 (모듈이 모두 로그 파일에 연결 되었기 때문에) 성공적으로 완료되었습니다.

정상적인 파이썬 오류 스택을 통해 모든 보풀과 파이프 오류를 억제하는 테스트 러너를 어떻게 구성 할 수 있는지에 대한 제안 사항이 있습니까? 항상 그렇듯이이 문제에 접근하는 더 좋은 방법이 있다고 생각되면 알려 주시기 바랍니다.

편집 :

여기

내가이 문제를 해결하기 위해 사용 결국 것입니다. 첫째, 나는 내 테스트 클래스에 "get_test_names()"방법을 추가 :

class my_test(unittest.TestCase): 
    etc.... 
    @staticmethod 
    def get_test_names(): 
     """Return the names of all the test methods for this class.""" 
     test_names = [ member[0] for memeber in inspect.getmembers(my_test) 
         if 'test_' in member[0] ] 

그런 다음 나는 다음과 unittest.main() 내 전화를 대체 :

# Unittest catches all errors raised by the test cases, and returns them as 
# formatted strings inside a TestResult object. In order for the test 
# harness to catch these errors they need to be re-raised, and so I am defining 
# this CompareError class to do that. 
# For each code error, a CompareError will be raised, with the original error 
# stack as the argument. For test failures (i.e. assertion errors) an 
# AssertionError is raised. 
class CompareError(Exception): 
    def __init__(self,err): 
     self.err = err 
    def __str__(self): 
     return repr(self.err) 

# Collect all tests into a TestSuite() 
all_tests = ut.TestSuite() 
for test in my_test.get_test_names(): 
    all_tests.addTest(my_test(test)) 
# Define a TestResult object and run tests 
results = ut.TestResult() 
all_tests.run(results) 
# Re-raise any script errors 
for error in results.errors: 
    raise CompareError(error[1]) 
# Re-raise any test failures 
for failure in results.failures: 
    raise AssertionError(failure[1]) 

답변

3

내가이 함께했다. 명령 줄을 변경할 수 있으면 내부 리오 리디렉션을 제거 할 수 있습니다.

import sys, inspect, traceback 

# redirect stdout, 
# can be replaced by testharness.py > /dev/null at console 
class devnull(): 
    def write(self, data): 
     pass 

f = devnull() 
orig_stdout = sys.stdout 
sys.stdout = f 

class TestCase(): 
    def test_1(self): 
     print 'test_1' 

    def test_2(self): 
     raise AssertionError, 'test_2' 

    def test_3(self): 
     print 'test_3' 


if __name__ == "__main__": 
    testcase = TestCase() 
    testnames = [ t[0] for t in inspect.getmembers(TestCase) 
         if t[0].startswith('test_') ] 

    for testname in testnames: 
     try: 
      getattr(testcase, testname)() 
     except AssertionError, e: 
      print >> sys.stderr, traceback.format_exc() 

# restore 
sys.stdout = orig_stdout 
+0

Gringo Suave에게 감사드립니다. TestSuite 및 TestResult 클래스를 사용하여 테스트 러너를 작성했지만 결국 코드에서 inspect.getmembers() 호출을 들었습니다. – jeremiahbuddha

+0

@jeremiahbuddha 답변을 수락하거나 직접 작성하고 수락 할 수 있습니까? –

관련 문제