[python] 디렉토리에서 모든 Python 단위 테스트를 어떻게 실행합니까?

파이썬 단위 테스트가 들어있는 디렉토리가 있습니다. 각 단위 테스트 모듈의 형식은 test _ *. py 입니다. all_test.py 라는 파일을 만들려고합니다.이 파일 은 위에서 언급 한 테스트 양식으로 모든 파일을 실행하고 결과를 반환합니다. 지금까지 두 가지 방법을 시도했습니다. 둘 다 실패했습니다. 나는 두 가지 방법을 보여줄 것이며, 누군가가 실제로 이것을 올바르게 수행하는 방법을 알고 있기를 바랍니다.

첫 번째 용감한 시도를 위해 “파일에서 모든 테스트 모듈을 가져온 다음이 unittest.main()doodad 를 호출 하면 제대로 작동합니까?”라고 생각했습니다. 글쎄, 내가 틀렸다는 것이 밝혀졌다.

import glob
import unittest

testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]

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

이것은 효과가 없었습니다. 결과는 다음과 같습니다.

$ python all_test.py 

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

내 두 번째 시도를 위해, 그래도, 나는 아마도이 전체 테스트 작업을보다 “수동적 인”방식으로 시도 할 것입니다. 그래서 아래에서 시도했습니다.

import glob
import unittest

testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
[__import__(str) for str in module_strings]
suites = [unittest.TestLoader().loadTestsFromName(str) for str in module_strings]
[testSuite.addTest(suite) for suite in suites]
print testSuite 

result = unittest.TestResult()
testSuite.run(result)
print result

#Ok, at this point I have a result
#How do I display it as the normal unit test command line output?
if __name__ == "__main__":
    unittest.main()

이것은 또한 작동하지 않았지만 너무 가깝습니다!

$ python all_test.py 
<unittest.TestSuite tests=[<unittest.TestSuite tests=[<unittest.TestSuite tests=[<test_main.TestMain testMethod=test_respondes_to_get>]>]>]>
<unittest.TestResult run=1 errors=0 failures=0>

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

나는 일종의 스위트를 가지고있는 것처럼 보이고 결과를 실행할 수 있습니다. 나는 그것이 단지 내가 가지고 있다고 말하는 것에 대해 조금 걱정하고 run=1있습니다 run=2. 그러나 결과를 main에 어떻게 전달하고 표시합니까? 아니면 기본적으로 어떻게 작동하게해서이 파일을 실행할 수 있고, 그렇게 할 때이 디렉토리에서 모든 단위 테스트를 실행합니까?



답변

Python 2.7 이상에서는이를 위해 새 코드를 작성하거나 타사 도구를 사용할 필요가 없습니다. 명령 행을 통한 재귀 테스트 실행이 내장되어 있습니다. 를 넣어 __init__.py테스트 디렉토리에 :

python -m unittest discover <test_directory>
# or
python -m unittest discover -s <directory> -p '*_test.py'

python 2.7
또는 python 3.x unittest 문서 에서 더 많은 내용을 읽을 수 있습니다 .


답변

이를 위해 테스트 러너를 사용할 수 있습니다. 예를 들어 는 매우 좋습니다. 실행되면 현재 트리에서 테스트를 찾아 실행합니다.

업데이트 :

코 이전의 몇 가지 코드가 있습니다. 모듈 이름의 명시적인 목록을 원하지 않을 수도 있지만 나머지는 유용 할 것입니다.

testmodules = [
    'cogapp.test_makefiles',
    'cogapp.test_whiteutils',
    'cogapp.test_cogapp',
    ]

suite = unittest.TestSuite()

for t in testmodules:
    try:
        # If the module defines a suite() function, call it to get the suite.
        mod = __import__(t, globals(), locals(), ['suite'])
        suitefn = getattr(mod, 'suite')
        suite.addTest(suitefn())
    except (ImportError, AttributeError):
        # else, just load all the test cases from the module.
        suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t))

unittest.TextTestRunner().run(suite)


답변

파이썬 3에서 다음을 사용하는 경우 unittest.TestCase:

  • 디렉토리 __init__.py에 비어 있거나 다른 파일이 있어야 합니다 (이름을 지정 해야 합니다 ).testtest/
  • 내부의 테스트 파일 test/은 패턴과 일치합니다 test_*.py. 이들은 아래의 서브 디렉토리 안에있을 수 있으며 해당 서브 디렉토리 test/는 무엇이든 지정할 수 있습니다.

그런 다음 다음을 사용하여 모든 테스트를 실행할 수 있습니다.

python -m unittest

끝난! 100 줄 미만의 솔루션. 다른 파이썬 초보자가 이것을 찾아서 시간을 절약하기를 바랍니다.


답변

이제 unittest : unittest.TestLoader.discover 에서 직접 가능합니다 .

import unittest
loader = unittest.TestLoader()
start_dir = 'path/to/your/test/files'
suite = loader.discover(start_dir)

runner = unittest.TextTestRunner()
runner.run(suite)


답변

글쎄, 위의 코드 (특히 TextTestRunnerand를 사용 하여 defaultTestLoader) 를 연구함으로써 꽤 가까워 질 수있었습니다. 결국 모든 테스트 스위트를 “수동으로”추가하지 않고 단일 스위트 생성자에 전달하여 다른 문제를 해결함으로써 코드를 수정했습니다. 그래서 여기 내 해결책이 있습니다.

import glob
import unittest

test_files = glob.glob('test_*.py')
module_strings = [test_file[0:len(test_file)-3] for test_file in test_files]
suites = [unittest.defaultTestLoader.loadTestsFromName(test_file) for test_file in module_strings]
test_suite = unittest.TestSuite(suites)
test_runner = unittest.TextTestRunner().run(test_suite)

네, 아마도 코를 사용하는 것이이 일을하는 것보다 쉬울 것입니다. 그러나 그것은 요점입니다.


답변

다양한 테스트 케이스 클래스에서 모든 테스트를 실행하고 명시 적으로 지정하려면 다음과 같이 할 수 있습니다.

from unittest import TestLoader, TextTestRunner, TestSuite
from uclid.test.test_symbols import TestSymbols
from uclid.test.test_patterns import TestPatterns

if __name__ == "__main__":

    loader = TestLoader()
    tests = [
        loader.loadTestsFromTestCase(test)
        for test in (TestSymbols, TestPatterns)
    ]
    suite = TestSuite(tests)

    runner = TextTestRunner(verbosity=2)
    runner.run(suite)

어디에 uclid내 프로젝트 및 TestSymbolsTestPatterns의 서브 클래스입니다 TestCase.


답변

discover방법 을 사용하여 load_tests코드의 (최소한, 생각하는) 숫자 줄로이 결과를 달성했습니다.

def load_tests(loader, tests, pattern):
''' Discover and load all unit tests in all files named ``*_test.py`` in ``./src/``
'''
    suite = TestSuite()
    for all_test_suite in unittest.defaultTestLoader.discover('src', pattern='*_tests.py'):
        for test_suite in all_test_suite:
            suite.addTests(test_suite)
    return suite

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

5-5에서 실행

Ran 27 tests in 0.187s
OK