Django가 모든 모듈에서 모든 DocTest를 찾도록 구성합니까?
-
06-07-2019 - |
문제
다음 명령을 실행하면 :
>python manage.py test
Django는 내 응용 프로그램에서 tests.py를보고 해당 파일에서 DocTest 또는 단위 테스트를 실행합니다. 또한 추가 테스트를 실행하려면 __ 테스트 __ 사전을 살펴 봅니다. 따라서 다른 모듈에서 DocTests를 연결할 수 있습니다.
#tests.py
from myapp.module1 import _function1, _function2
__test__ = {
"_function1": _function1,
"_function2": _function2
}
더 많은 문서를 포함시키고 싶다면이 사전에서 모두 열거하는 것보다 쉬운 방법이 있습니까? 이상적으로는 Django가 MyAPP 응용 프로그램의 모든 모듈에서 모든 DocTest를 찾도록하고 싶습니다.
내가 원하는 곳으로 나를 데려 갈 수있는 반사 해킹이 있습니까?
해결책 4
Alex와 Paul에게 감사합니다. 이것이 제가 생각해 낸 것입니다.
# tests.py
import sys, settings, re, os, doctest, unittest, imp
# import your base Django project
import myapp
# Django already runs these, don't include them again
ALREADY_RUN = ['tests.py', 'models.py']
def find_untested_modules(package):
""" Gets all modules not already included in Django's test suite """
files = [re.sub('\.py$', '', f)
for f in os.listdir(os.path.dirname(package.__file__))
if f.endswith(".py")
and os.path.basename(f) not in ALREADY_RUN]
return [imp.load_module(file, *imp.find_module(file, package.__path__))
for file in files]
def modules_callables(module):
return [m for m in dir(module) if callable(getattr(module, m))]
def has_doctest(docstring):
return ">>>" in docstring
__test__ = {}
for module in find_untested_modules(myapp.module1):
for method in modules_callables(module):
docstring = str(getattr(module, method).__doc__)
if has_doctest(docstring):
print "Found doctest(s) " + module.__name__ + "." + method
# import the method itself, so doctest can find it
_temp = __import__(module.__name__, globals(), locals(), [method])
locals()[method] = getattr(_temp, method)
# Django looks in __test__ for doctests to run
__test__[method] = getattr(module, method)
다른 팁
나는 얼마 전에 이것을 스스로 해결했다.
apps = settings.INSTALLED_APPS for app in apps: try: a = app + '.test' __import__(a) m = sys.modules[a] except ImportError: #no test jobs for this module, continue to next one continue #run your test using the imported module m
이를 통해 모듈 당 테스트를 자체 Test.py 파일에 넣을 수 있으므로 나머지 응용 프로그램 코드와 혼합되지 않았습니다. 각 모듈에서 DOC 테스트 만 찾아서 찾은 경우 실행하려면이를 수정하기가 쉽습니다.
사용 장고 노스 코는 자동으로 모든 테스트를 다시 찾습니다.
다음은 솔루션의 주요 요소입니다.
tests.py :
def find_modules(package):
"""Return list of imported modules from given package"""
files = [re.sub('\.py$', '', f) for f in os.listdir(os.path.dirname(package.__file__))
if f.endswith(".py") and os.path.basename(f) not in ('__init__.py', 'test.py')]
return [imp.load_module(file, *imp.find_module(file, package.__path__)) for file in files]
def suite(package=None):
"""Assemble test suite for Django default test loader"""
if not package: package = myapp.tests # Default argument required for Django test runner
return unittest.TestSuite([doctest.DocTestSuite(m) for m in find_modules(package)])
재귀 사용을 추가합니다 os.walk()
모듈 트리를 가로 지르고 파이썬 패키지를 찾으십시오.
나는 Djano의 테스트에 속도가 빠르지 않지만 이해할 수 있듯이 자동 사용을 사용합니다. 유닛 테스트 좋아요 python -m unittest discover
그리고 코.
그렇다면 다음 파일을 어딘가에 넣을 수 있습니다. test_doctest.py
또는 유사한).
변화 your_package
테스트 할 패키지에. 모든 모듈 (서브 포장 포함)이 문서화됩니다.
import doctest
import pkgutil
import your_package as root_package
def load_tests(loader, tests, ignore):
modules = pkgutil.walk_packages(root_package.__path__, root_package.__name__ + '.')
for _, module_name, _ in modules:
try:
suite = doctest.DocTestSuite(module_name)
except ValueError:
# Presumably a "no docstrings" error. That's OK.
pass
else:
tests.addTests(suite)
return tests