python - unittest is not able to discover / run tests -
there some related questions, none apply.
this directory tree:
» tree abc_backend abc_backend/ ├── backend_main.py ├── funddatabase.db ├── healthcheck.py ├── __init__.py ├── init.py ├── portfolio.py ├── private.py ├── __pycache__ ├── questionnaire.py ├── recurring.py ├── registration.py ├── tests │ ├── config.py │ ├── __init__.py │ ├── __pycache__ │ ├── test_backend.py │ ├── test_healthcheck.py │ └── test_private.py ├── trading.py ├── users.db ├── version └── visualisation.py
unittest
not able find anything:
top » python -m unittest abc_backend ---------------------------------------------------------------------- ran 0 tests in 0.000s ok
not within abc_backend
:
abc_backend » python -m unittest tests ---------------------------------------------------------------------- ran 0 tests in 0.000s ok
what have verified:
- my test methods named (
test_whatever
) - my testcases extend
unittest.testcase
- the
abc_backend
,abc_backend/tests
directories have (empty)__init__.py
- all test modules importable (see below)
unittest discover
finds tests, has problems relative imports (see below)nose
able discover , run tests, no problems
i understand:
- why need pass
discover
unittest
force discover tests?unittest
withoutdiscover
sub-command? (i thought unittest test discovery default). according documentation:
python -m unittest equivalent of python -m unittest discover
- once tests discovered (by forcing
discover
sub-command), why have import issues?
test modules importable
» python python 3.4.3 (default, oct 14 2015, 20:28:29) [gcc 4.8.4] on linux type "help", "copyright", "credits" or "license" more information. >>> import abc_backend.tests >>> import abc_backend.tests.test_private >>> import abc_backend.tests.test_healthcheck >>> import abc_backend.tests.test_backend
unittest discover has problems relative imports
if run top dir:
top » python -m unittest discover abc_backend ====================================================================== error: tests.test_private (unittest.loader.moduleimportfailure) ---------------------------------------------------------------------- traceback (most recent call last): file "/usr/lib/python3.4/unittest/case.py", line 58, in testpartexecutor yield file "/usr/lib/python3.4/unittest/case.py", line 577, in run testmethod() file "/usr/lib/python3.4/unittest/loader.py", line 32, in testfailure raise exception importerror: failed import test module: tests.test_private traceback (most recent call last): file "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests module = self._get_module_from_name(name) file "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name __import__(name) file "/foo/bar/abc_backend/tests/test_private.py", line 6, in <module> .. import init valueerror: attempted relative import beyond top-level package
if run within abc_backend
:
abc_backend » python -m unittest discover tests ====================================================================== error: test_private (unittest.loader.moduleimportfailure) ---------------------------------------------------------------------- traceback (most recent call last): file "/usr/lib/python3.4/unittest/case.py", line 58, in testpartexecutor yield file "/usr/lib/python3.4/unittest/case.py", line 577, in run testmethod() file "/usr/lib/python3.4/unittest/loader.py", line 32, in testfailure raise exception importerror: failed import test module: test_private traceback (most recent call last): file "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests module = self._get_module_from_name(name) file "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name __import__(name) file "/foo/bar/abc_backend/tests/test_private.py", line 6, in <module> .. import init systemerror: parent module '' not loaded, cannot perform relative import
i reproduced problems cpython 3.5, answer should relevant both 3.4 , 3.5.
relative import issues
the reason why there issues relative imports due specifics of invocations not import abc_backend
package.
first, let’s take @
top» python3 -m unittest discover abc_backend
when run tests top way, abc_backend
not imported. because /home/user/top/abc_backend
added sys.path instead of /home/user/top
. solve problem, do
top» python3 -m unittest discover abc_backend -t .
now, in-abc_backend invocation. when do
abc_backend» python3 -m unittest discover tests
abc_backend
not importable, /home/user/top/abc_backend/tests
dir not contain abc_backend
package. can solved with
abc_backend» python3 -m unittest discover tests -t ../
that correctly put /home/user/top
dir (pun intended) sys.path
.
the -t
(or --top-level-directory
) option sets top level directory of project , defaults start directory (which .
default). so, in sys.path
important, affects imports, affect test loading, discovery loads tests using import machinery.
difference between -m unittest
, -m unittest discover
when do
top» python3 -m unittest abc_backend
in reality running unittest/__main__.py
file. there main(module=none)
invoked, , loadtestsfrommodule
does
tests = [] name in dir(module): obj = getattr(module, name) if isinstance(obj, type) , issubclass(obj, case.testcase): tests.append(self.loadtestsfromtestcase(obj))
as abc_backend/__init__.py
not contain test cases, isinstance(obj, type) , issubclass(obj, case.testcase)
returns false
module members (so tests
empty).
to make particular way of invocation work, you’ll have people did in pre-discover
times (aside non-stdlib frameworks): manually import cases test modules (or maybe construct test suite according load_tests
protocol).
so, how
top» python3 -m unittest discover abc_backend
differs?
basically, differences may expressed following conditional:
if len(argv) > 1 , argv[1].lower() == 'discover': # -m unittest discover loader.discover(...) else: # -m unittest loader.loadtestsfromnames(...)
when argv
['python3 -m unittest', 'discover', 'abc_backend']
, actual discovery mechanism used. when argv
['python3 -m unittest', 'abc_backend']
, loadtestsfromnames
used, calls loadtestsfrommodule
@ point, , no tests found. that’s way things in unittest/main.py
.
Comments
Post a Comment