2009-06-22 4 views
37

unittest를 가져오고 일부 TestCases가있는 모듈이 있습니다. 일부 명령 행 옵션 (예 : 아래의 데이터 파일 이름)을 허용하려면, 하지만 옵션을 전달하려고 할 때 "옵션 -i not recognized"메시지가 나타납니다. unittest + 앱에 옵션을 제공 할 수 있습니까 (참고 : 옵션을 처리하기 위해 optparse를 사용하고 있습니다)? 감사.python, unittest : 명령 행 옵션을 앱에 전달하는 방법이 있나요

$ python test_app_data.py -i data_1.txt 

option -i not recognized 

=====================

후속은 :

import cfg_master #has the optparse option-handling code 

... 

if __name__ == '__main__':  
    #add you app's options here... 
    options_tpl = ('-i', '--in_dir', '-o', '--out_dir') 
    del_lst = [] 
    for i,option in enumerate(sys.argv): 
     if option in options_tpl: 
      del_lst.append(i) 
      del_lst.append(i+1) 

    del_lst.reverse() 
    for i in del_lst: 
     del sys.argv[i] 

    unittest.main() 
:이 제안 된 솔루션의 구현입니다 당신이 unittest 코드에 제어를 전달하기 전에 후자의 코드가 명령 행 옵션을 해석하려고하지 않도록 당신이 우리를 표시하지 않는 당신의 if __name__ == '__main__': 섹션에서
+0

을 unittest.main 호출합니다. 이 경우 응답은 사용자가 제공하지 않은 세부 정보에 크게 의존합니다. –

+0

@jd. 귀하의 "후속 조치"가 답변으로 게시되어야합니다. 귀하의 질문에는 ... 잘 ... 질문 만 포함되어야합니다. – user1251007

답변

45

건물 알렉스의 대답에, 그것은 argparse을 사용하여이 작업을 수행하기 위해 실제로 매우 쉽게 :

if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('--input', default='My Input') 
    parser.add_argument('filename', default='some_file.txt') 
    parser.add_argument('unittest_args', nargs='*') 

    args = parser.parse_args() 
    # TODO: Go do something with args.input and args.filename 

    # Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone) 
    sys.argv[1:] = args.unittest_args 
    unittest.main() 

난 당신이 그들이 작동 여부 있는지 확인하기 위해 유닛 테스트에 통과 할 수 플래그의 모든 테스트를하지 않은,하지만 시험을 통과 수행 작업, 예에서 이름 : foodata.txt와 MYTEST

python test.py --input=foo data.txt MyTest 

실행됩니다.

작은 독립형 앱의
+3

니스! 더 나아가,'unittest.main()'은 argv 매개 변수를 받아들이므로 전역 sys.argv를 처리 할 필요가 없습니다. 이렇게 :'unit_argv = [sys.argv [0]] + args.unittest_args; unittest.main (argv = unit_argv)' – wutz

+3

대신'.parse_known_args()'를 사용할 수 있으며'nargs = '*''옵션을 사용할 필요가 없습니다. 내 버전은 [Python : unittest.TestCase를 실행하여 unittest.main()?] (http://stackoverflow.com/a/17259773)을 참조하십시오. –

+0

나는이 접근법이 @MartijnPieters가 참조한 질문에서이 접근법을 연상케했다. 그러나,이 답변을 구현할 때 플래그 (--failfast 및 --catch)를 전달할 때 작동하지 않으므로 Martijn의 대답으로 되돌아갔습니다. –

31

, 당신은 다음 del sys.argv[1:]optparse에 필요합니다 다시 때 요 이미 그것들을 다루었습니다. 약간의 옵션을 으로 지정하는 것이 조금 더 어려워서 unittest으로 전달할 수 있지만 복잡한 요구가있는 경우 수행 할 수 있습니다.

+0

위대한, 감사합니다; 그냥 확인하려면 : 먼저 optparse가 (아마도 다중이고 가변적 인) app 옵션을 처리 한 다음 sys.argv에서 삭제하고 마지막으로 unittest가 대신하도록 허용 하시겠습니까? –

+0

@jd 옙, 그것의 요지! –

+0

Brilliant, 감사합니다. Alex! 나는 이것을 전혀 해결하지 못했습니다 : P – Skilldrick

-7

unittests를 실행하기 위해 인수와 옵션을 취하지 않아야합니다. 단위 테스트를 다른 방법으로 예측하기 어려운 상태로 실행하게하십시오. 왜 다른 데이터로 테스트를 실행해야하는지 파악해야하고, 매번 다르게 실행하지 않고 모든 데이터 세트의 기반을 충분히 커버 할 수있는 테스트 슈트를 만들 수 있어야합니다.

+0

매주 데이터 보고서 (파일)를받습니다. 공개 보고서를 작성하기 전에이 새로운 보고서를 unittest에 제공하고 싶습니다. 어떤 이유로 데이터의 구조 또는 유형이 변경된 경우 (예 : 새로운 열 필드 추가, 데이터 범위가 변경되어 버그가 공개됨) 테스트와 관련하여 알려 드리고 싶습니다. 희망이 의미가 있습니다. –

+2

확실하지만 unittesting이 아니라 데이터 검증이 필요합니다. – ironfroggy

+2

조건부 테스트 건너 뛰기는 어떻습니까?unittest의 테스트를 수행하여 모든 테스트 케이스를 실행하지만 쉬운 명령 행 방식을 사용할 수 있도록 @skipUnless ('- full'in sys.argv)와 같은 특정 테스트에서 주석을 가질 수 있으면 좋을 것 같습니다. 모든 테스트를 실행하거나 일부만 실행합니다. –

1

, 나는 초기 감시 옵션 (-t)를 사용하고 예, 일반적인 용어() argparse.ArgumentParser()를 호출하기 전에

if __name__ == "__main__": 
    if len(sys.argv) > 1 and sys.argv[1] in ["-t", "--test"]: 
     del(sys.argv[1]) 
     sys.exit(unittest.main()) # pass sys.argv[ 

    p = argparse.ArgumentParser() 
    . . . 
관련 문제