python setup.py test
.NET과 동등한 기능을 실행하는 방법을 알아 내려고 노력 중 python -m unittest discover
입니다. run_tests.py 스크립트를 사용하고 싶지 않고 외부 테스트 도구 ( nose
또는 같은 py.test
) 를 사용하고 싶지 않습니다 . 솔루션이 Python 2.7에서만 작동하면 괜찮습니다.
에서 setup.py
, 나는 내가 뭔가를 추가 할 필요가 있다고 생각합니다 test_suite
및 / 또는 test_loader
설정 필드,하지만 난 제대로 작동하는 조합을 찾을 수 없습니다 :
config = {
'name': name,
'version': version,
'url': url,
'test_suite': '???',
'test_loader': '???',
}
unittest
Python 2.7에 내장 된 경우에만 가능 합니까?
참고로 내 프로젝트 구조는 다음과 같습니다.
project/
package/
__init__.py
module.py
tests/
__init__.py
test_module.py
run_tests.py <- I want to delete this
setup.py
업데이트 : 이것은 가능 unittest2
하지만 만 사용하여 동등한 것을 찾고 싶습니다.unittest
에서 https://pypi.python.org/pypi/unittest2
unittest2에는 매우 기본적인 setuptools 호환 테스트 수집기가 포함되어 있습니다. setup.py에 test_suite = ‘unittest2.collector’를 지정하십시오. 이렇게하면 setup.py가 포함 된 디렉토리의 기본 매개 변수를 사용하여 테스트 검색이 시작되므로 아마도 가장 유용한 예입니다 (unittest2 / collector.py 참조).
지금은라는 스크립트를 사용하고 run_tests.py
있지만 .NET 만 사용하는 솔루션으로 이동하여이 문제를 제거 할 수 있기를 바랍니다 python setup.py test
.
run_tests.py
제거 하고 싶은 항목 은 다음과 같습니다 .
import unittest
if __name__ == '__main__':
# use the default shared TestLoader instance
test_loader = unittest.defaultTestLoader
# use the basic test runner that outputs to sys.stderr
test_runner = unittest.TextTestRunner()
# automatically discover all tests in the current dir of the form test*.py
# NOTE: only works for python 2.7 and later
test_suite = test_loader.discover('.')
# run the test suite
test_runner.run(test_suite)
답변
py27 + 또는 py32 +를 사용하는 경우 솔루션은 매우 간단합니다.
test_suite="tests",
답변
Setuptools로 패키지 빌드 및 배포 에서 (강조) :
test_suite
unittest.TestCase 하위 클래스 (또는 이들 중 하나 이상을 포함하는 패키지 또는 모듈 또는 이러한 하위 클래스의 메서드)의 이름을 지정하는 문자열 또는 인수없이 호출 할 수있는 함수 이름을 지정
하고 unittest.TestSuite를 반환합니다 .
따라서 setup.py
TestSuite를 반환하는 함수를 추가합니다.
import unittest
def my_test_suite():
test_loader = unittest.TestLoader()
test_suite = test_loader.discover('tests', pattern='test_*.py')
return test_suite
그런 setup
다음 다음과 같이 명령 을 지정합니다 .
setup(
...
test_suite='setup.my_test_suite',
...
)
답변
이 작업을 수행하기 위해 구성이 필요하지 않습니다. 기본적으로 두 가지 주요 방법이 있습니다.
빠른 방법
당신의 이름을 변경 test_module.py
하는 module_test.py
(기본적으로 추가 _test
특정 모듈에 대한 시험을 접미사로), 그리고 파이썬은 자동으로 찾을 수 있습니다. 이것을 다음에 추가하십시오 setup.py
.
from setuptools import setup, find_packages
setup(
...
test_suite = 'tests',
...
)
먼 길
현재 디렉토리 구조로 수행하는 방법은 다음과 같습니다.
project/
package/
__init__.py
module.py
tests/
__init__.py
test_module.py
run_tests.py <- I want to delete this
setup.py
에서 및 단위 테스트 스크립트 tests/__init__.py
를 가져온 다음 테스트를 실행하는 함수를 만듭니다. 에서 , 이런 일을 입력 :unittest
test_module
tests/__init__.py
import unittest
import test_module
def my_module_suite():
loader = unittest.TestLoader()
suite = loader.loadTestsFromModule(test_module)
return suite
이 TestLoader
클래스에는 loadTestsFromModule
. 당신은 실행할 수 있습니다dir(unittest.TestLoader)
다른 것을보기 위해 있지만 이것은 사용하기 가장 간단합니다.
디렉토리 구조가 이와 같기 때문에에서 스크립트 test_module
를 가져올 수 있기를 원할 것입니다 module
. 이미이 작업을 수행했을 수도 있지만 그렇지 않은 경우를 대비하여 package
모듈과 module
스크립트를 가져올 수 있도록 부모 경로를 포함 할 수 있습니다 . 상단에 다음 test_module.py
을 입력합니다.
import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import unittest
import package.module
...
그런 다음 마지막으로에 모듈을 setup.py
포함하고 tests
생성 한 명령을 실행합니다 my_module_suite
.
from setuptools import setup, find_packages
setup(
...
test_suite = 'tests.my_module_suite',
...
)
그럼 넌 그냥 달려 python setup.py test
.
다음은 누군가가 참조로 만든 샘플 입니다.
답변
한 가지 가능한 해결책은 단순히 test
distutils
및 setuptools
/에 명령을distribute
입니다. 이것은 내가 선호하는 것보다 총체적이고 복잡해 보이지만 실행시 내 패키지의 모든 테스트를 올바르게 발견하고 실행하는 것 같습니다.python setup.py test
. 나는 누군가가 더 우아한 해결책을 제공하기를 희망하면서 이것을 내 질문에 대한 대답으로 선택하는 것을 보류하고 있습니다. 🙂
( https://docs.pytest.org/en/latest/goodpractices.html#integrating-with-setuptools-python-setup-py-test-pytest-runner에서 영감을 얻음 )
예 setup.py
:
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
def discover_and_run_tests():
import os
import sys
import unittest
# get setup.py directory
setup_file = sys.modules['__main__'].__file__
setup_dir = os.path.abspath(os.path.dirname(setup_file))
# use the default shared TestLoader instance
test_loader = unittest.defaultTestLoader
# use the basic test runner that outputs to sys.stderr
test_runner = unittest.TextTestRunner()
# automatically discover all tests
# NOTE: only works for python 2.7 and later
test_suite = test_loader.discover(setup_dir)
# run the test suite
test_runner.run(test_suite)
try:
from setuptools.command.test import test
class DiscoverTest(test):
def finalize_options(self):
test.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
discover_and_run_tests()
except ImportError:
from distutils.core import Command
class DiscoverTest(Command):
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
discover_and_run_tests()
config = {
'name': 'name',
'version': 'version',
'url': 'http://example.com',
'cmdclass': {'test': DiscoverTest},
}
setup(**config)
답변
http://hg.python.org/unittest2/file/2b6411b9a838/unittest2/collector.py에서 약간 영감을 얻은 이상적인 솔루션이 아닙니다 .
TestSuite
발견 된 테스트 를 반환하는 모듈을 추가합니다 . 그런 다음 해당 모듈을 호출하도록 설정을 구성하십시오.
project/
package/
__init__.py
module.py
tests/
__init__.py
test_module.py
discover_tests.py
setup.py
여기 있습니다 discover_tests.py
:
import os
import sys
import unittest
def additional_tests():
setup_file = sys.modules['__main__'].__file__
setup_dir = os.path.abspath(os.path.dirname(setup_file))
return unittest.defaultTestLoader.discover(setup_dir)
그리고 여기 있습니다 setup.py
:
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
config = {
'name': 'name',
'version': 'version',
'url': 'http://example.com',
'test_suite': 'discover_tests',
}
setup(**config)
답변
Python의 표준 라이브러리 unittest
모듈은 검색을 지원합니다 (Python 2.7 이상 및 Python 3.2 이상). 이러한 최소 버전을 가정 할 수 있으면 discover
명령 줄 인수를unittest
됩니다.
다음을 수행하려면 약간만 조정하면됩니다 setup.py
.
import setuptools.command.test
from setuptools import (find_packages, setup)
class TestCommand(setuptools.command.test.test):
""" Setuptools test command explicitly using test discovery. """
def _test_args(self):
yield 'discover'
for arg in super(TestCommand, self)._test_args():
yield arg
setup(
...
cmdclass={
'test': TestCommand,
},
)
답변
이것은 run_tests.py를 제거하지는 않지만 setuptools와 함께 작동합니다. 더하다:
class Loader(unittest.TestLoader):
def loadTestsFromNames(self, names, _=None):
return self.discover(names[0])
그런 다음 setup.py에서 : (같은 일을하고 있다고 가정합니다 setup(**config)
)
config = {
...
'test_loader': 'run_tests:Loader',
'test_suite': '.', # your start_dir for discover()
}
내가 보는 유일한 단점은의 의미를 구부리는 loadTestsFromNames
것이지만 setuptools test 명령은 유일한 소비자이며 지정된 방식으로 호출합니다 .