Python : 하위 디렉토리의 모든 소스 파일에 대해 unittest.main ()을 실행하는 방법은 무엇입니까?
저는 여러 소스 파일이있는 Python 모듈을 개발 중이며, 각 파일 에는 소스의 unittest 에서 파생 된 자체 테스트 클래스가 있습니다. 디렉토리 구조를 고려하십시오.
dirFoo\
test.py
dirBar\
__init__.py
Foo.py
Bar.py
Foo.py 또는 Bar.py를 테스트하기 위해 Foo.py 및 Bar.py 소스 파일 끝에 다음을 추가합니다.
if __name__ == "__main__":
unittest.main()
그리고 두 소스에서 Python을 실행합니다.
$ python Foo.py
...........
----------------------------------------------------------------------
Ran 11 tests in 2.314s
OK
이상적으로는 "test.py"가 자동으로 모든 unittest 파생 클래스에 대해 dirBar를 검색하고 "unittest.main ()"을 한 번 호출하도록합니다. 실제로이를 수행하는 가장 좋은 방법은 무엇입니까?
Python을 사용하여 dirBar의 모든 * .py 파일에 대해 execfile 을 호출하려고했습니다.이 파일은 첫 번째 .py 파일에 대해 한 번 실행되고 test.py 호출을 종료 한 다음 unittest.main ()을 추가하여 코드를 복제해야합니다. DRY 원칙을 위반하는 모든 소스 파일.
Python 2.7부터는 unittest 패키지에서 테스트 검색이 자동화됩니다. 로부터 문서 :
Unittest는 간단한 테스트 검색을 지원합니다. 테스트 검색과 호환 되려면 모든 테스트 파일이 프로젝트의 최상위 디렉터리에서 가져올 수있는 모듈 또는 패키지 여야합니다 (즉, 파일 이름이 유효한 식별자 여야 함).
테스트 검색은에서 구현
TestLoader.discover()
되지만 명령 줄에서도 사용할 수 있습니다. 기본 명령 줄 사용법은 다음과 같습니다.cd project_directory python -m unittest discover
기본적으로라는 패키지를 찾지 test*.py
만 다음과 같은 것을 사용할 수 있도록 변경할 수 있습니다.
python -m unittest discover --pattern=*.py
test.py 스크립트 대신.
다음은 작업을 수행하는 것으로 보이는 테스트 검색 코드입니다. 관련 파일에 나열하지 않고도 테스트를 쉽게 확장 할 수 있는지 확인하고 모든 테스트를 하나의 단일 Übertest 파일에 작성하는 것을 피하고 싶었습니다.
그래서 구조는
myTests.py
testDir\
__init__.py
testA.py
testB.py
myTest.py는 다음과 같습니다.
import unittest
if __name__ == '__main__':
testsuite = unittest.TestLoader().discover('.')
unittest.TextTestRunner(verbosity=1).run(testsuite)
나는 이것이 하나의 디렉토리에 여러 테스트 케이스를 작성하는 가장 간단한 솔루션이라고 생각합니다. 이 솔루션에는 Python 2.7 또는 Python 3이 필요합니다.
분명한 해결책이 있다는 것을 알고있었습니다.
dirFoo\
__init__.py
test.py
dirBar\
__init__.py
Foo.py
Bar.py
dirFoo / test.py의 내용
from dirBar import *
import unittest
if __name__ == "__main__":
unittest.main()
테스트를 실행하십시오.
$ python test.py
...........
----------------------------------------------------------------------
Ran 11 tests in 2.305s
OK
어리석은 질문에 대해 죄송합니다.
코 를 시도해야합니다 . 이 테스트를 만드는 데 도움이 도서관 그리고 그것은 통합 unittest
하거나 doctest
. 실행 nosetests
하기 만하면 모든 단위 테스트를 찾을 수 있습니다.
% nosetests # finds all tests in all subdirectories
% nosetests tests/ # find all tests in the tests directory
나는 당신이 원하는 것을 할 수있는 스 니펫을 생각 해냈다. Python 패키지 / 모듈을 찾고 제공하는 경로를 따라 해당 모듈에서 테스트 스위트 세트를 축적 한 다음 모두 한 번에 실행합니다.
이것에 대한 좋은 점은 지정한 디렉토리 아래에 중첩 된 모든 패키지에서 작동하며 새 구성 요소를 추가 할 때 가져 오기를 수동으로 변경할 필요가 없다는 것입니다.
import logging
import os
import unittest
MODULE_EXTENSIONS = set('.py .pyc .pyo'.split())
def unit_test_extractor(tup, path, filenames):
"""Pull ``unittest.TestSuite``s from modules in path
if the path represents a valid Python package. Accumulate
results in `tup[1]`.
"""
package_path, suites = tup
logging.debug('Path: %s', path)
logging.debug('Filenames: %s', filenames)
relpath = os.path.relpath(path, package_path)
relpath_pieces = relpath.split(os.sep)
if relpath_pieces[0] == '.': # Base directory.
relpath_pieces.pop(0) # Otherwise, screws up module name.
elif not any(os.path.exists(os.path.join(path, '__init__' + ext))
for ext in MODULE_EXTENSIONS):
return # Not a package directory and not the base directory, reject.
logging.info('Base: %s', '.'.join(relpath_pieces))
for filename in filenames:
base, ext = os.path.splitext(filename)
if ext not in MODULE_EXTENSIONS: # Not a Python module.
continue
logging.info('Module: %s', base)
module_name = '.'.join(relpath_pieces + [base])
logging.info('Importing from %s', module_name)
module = __import__(module_name)
module_suites = unittest.defaultTestLoader.loadTestsFromModule(module)
logging.info('Got suites: %s', module_suites)
suites += module_suites
def get_test_suites(path):
""":return: Iterable of suites for the packages/modules
present under :param:`path`.
"""
logging.info('Base path: %s', package_path)
suites = []
os.path.walk(package_path, unit_test_extractor, (package_path, suites))
logging.info('Got suites: %s', suites)
return suites
if __name__ == '__main__':
logging.basicConfig(level=logging.WARN)
package_path = os.path.dirname(os.path.abspath(__file__))
suites = get_test_suites(package_path)
for suite in suites:
unittest.TextTestRunner(verbosity=2).run(suite)
누군가를 돕는 일이 발생하면이 문제를 해결하기 위해 내가 도달 한 접근법이 있습니다. 다음과 같은 디렉토리 구조가있는 사용 사례가 있습니다.
mypackage/
tests/
test_category_1/
tests_1a.py
tests_1b.py
...
test_category_2/
tests_2a.py
tests_2b.py
...
...
and I want all of the following to work in the obvious way and to be able to be supplied the same commandline arguments as are accepted by unittest:
python -m mypackage.tests
python -m mypackage.tests.test_category_1
python -m mypackage.tests.test_category_1.tests_1a
The solution was to set up mypackage/tests/__init__.py
like this:
import unittest
def prepare_load_tests_function (the__path__):
test_suite = unittest.TestLoader().discover(the__path__[0])
def load_tests (_a, _b, _c):
return test_suite
return load_tests
and to set up mypackage/tests/__main__.py
like this:
import unittest
from . import prepare_load_tests_function, __path__
load_tests = prepare_load_tests_function(__path__)
unittest.main()
and to copy and paste an empty __init__.py
and the following __main__.py
in each mypackage/tests/test_category_n/
:
import unittest
from .. import prepare_load_tests_function
from . import __path__
load_tests = prepare_load_tests_function(__path__)
unittest.main()
and also to add the standard if __name__ == '__main__': unittest.main()
in each actual tests file.
(Works for me on Python 3.3 on Windows, ymmv.)
'IT TIP' 카테고리의 다른 글
Xcode 예외 중단 점이 throw되는 예외의 세부 정보를 인쇄하지 않습니다. (0) | 2020.12.14 |
---|---|
Ruby 버전은 2.0.0이지만 Gemfile은 2.1.0을 지정했습니다. (0) | 2020.12.14 |
JavaScript 개발 용 IDE (0) | 2020.12.14 |
has_and_belongs_to_many, 조인 테이블에서 중복 방지 (0) | 2020.12.14 |
다중 조인을 만들 때 tmp 테이블에 대한 MySQL 잘못된 키 파일 (0) | 2020.12.14 |