There were already questions regarding this topic. Sometimes programmers put some __init__.py
at some places, often it is said one should use absolute paths. However, I don't get it to work here:
How do I import a class from a package so that tests in pytest run and the code can be used?
At the moment I get pytest or the code passing respective running.
My example project structure is
.
├── testingonly
│ ├── cli.py
│ ├── __init__.py
│ └── testingonly.py
└── tests
├── __init__.py
└── test_testingonly.py
__init__.py
is in both cases an empty file.
$ cat testingonly/cli.py
"""Console script for testingonly."""
from testingonly import Tester
def main(args=None):
"""Console script for testingonly."""
te = Tester()
return 0
main()
$ cat testingonly/testingonly.py
"""Main module."""
class Tester():
def __init__(self):
print("Hello")
This gives - as expected:
$ python3 testingonly/cli.py
Hello
Trying to test this, however, fails:
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 0 items / 1 error
=============================================================== ERRORS ================================================================
_____________________________________________ ERROR collecting tests/test_testingonly.py ______________________________________________
ImportError while importing test module '/home/stefan/Development/testingonly/tests/test_testingonly.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.7/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_testingonly.py:10: in <module>
from testingonly import cli
testingonly/cli.py:2: in <module>
from testingonly import Tester
E ImportError: cannot import name 'Tester' from 'testingonly' (/home/stefan/Development/testingonly/testingonly/__init__.py)
Renaming testingonly/testingonly.py
to testingonly/mytest.py
and changing the imports in test_testingonly.py (from testingonly import mytest) and cli.py (from mytest import Tester) gives
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 0 items / 1 error
=============================================================== ERRORS ================================================================
_____________________________________________ ERROR collecting tests/test_testingonly.py ______________________________________________
ImportError while importing test module '/home/stefan/Development/testingonly/tests/test_testingonly.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.7/importlib/__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_testingonly.py:10: in <module>
from testingonly import cli
testingonly/cli.py:2: in <module>
from mytest import Tester
E ModuleNotFoundError: No module named 'mytest'
======================================================= short test summary info =======================================================
ERROR tests/test_testingonly.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================== 1 error in 0.37s ===========================================================
$ python3 testingonly/cli.py
Hello
The other proposed solution with renaming to mytest.py lets the tests pass, but in cli.py using from testingonly.mytest import Tester
gives a NameNotFound error.
$ python3 testingonly/cli.py
Traceback (most recent call last):
File "testingonly/cli.py", line 2, in <module>
from testingonly.mytest import Tester
ModuleNotFoundError: No module named 'testingonly'
$ pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/stefan/Development/testingonly
collected 1 item
tests/test_testingonly.py . [100%]
========================================================== 1 passed in 0.12s ==========================================================
The self-named module testingonly
and file name of testingonly.py
may be causing some issues with the way the modules are imported.
Remove the __init__.py
from the tests
directory. Ref this answer .
Try renaming testingonly.py
to mytest.py
and then importing it into your project again.
In the cli.py
, it should be:
from testingonly.mytest import Tester
And then for your test file test_testingonly.py
:
from testingonly.mytest import Tester
You're test_testingonly.py
file should look like this:
import pytest
from testingonly.mytest import Tester # Import the Tester Class
def test_tester(capsys):
# Create the Tester Class
te = Tester()
# Get the captured output
captured = capsys.readouterr()
# Assert that the capture output is tested
assert captured.out == "Hello\n"
Finally, Run your tests with:
python -m pytest tests/
Here is a fully working example based off of your code: https://github.com/cdesch/testingonly