问题
I used easy_install to install pytest on a mac and started writing tests for a project with a file structure likes so:
repo/
repo/app.py
repo/settings.py
repo/models.py
repo/tests/
repo/tests/test_app.py
run py.test
while in the repo directory, everything behaves as you would expect
but when I try that same thing on either linux or windows (both have pytest 2.2.3 on them) it barks whenever it hits its first import of something from my application path. Say for instance from app import some_def_in_app
Do I need to be editing my PATH to run py.test on these systems? Has Anyone experienced this?
回答1:
Yes, the source folder is not in Python's path if you cd
to the tests directory.
You have 2 choices:
Add the path manually to the test files, something like this:
import sys, os myPath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, myPath + '/../')
Run the tests with the env var
PYTHONPATH=../
.
回答2:
I'm not sure why py.test does not add the current directory in the PYTHONPATH itself, but here's a workaround (to be executed from the root of your repository):
python -m pytest tests/
It works because Python adds the current directory in the PYTHONPATH for you.
回答3:
I had the same problem. I fixed it by adding an empty __init__.py
file to my tests
directory.
回答4:
conftest
solution
The least invasive solution is adding an empty file named conftest.py
in the repo/
directory:
$ touch repo/conftest.py
That's it. No need to write custom code for mangling the sys.path
or remember to drag PYTHONPATH
along, or placing __init__.py
into dirs where it doesn't belong.
The project directory afterwards:
repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
└── test_app.py
Explanation
pytest
looks for the conftest
modules on test collection to gather custom hooks and fixtures, and in order to import the custom objects from them, pytest
adds the parent directory of the conftest.py
to the sys.path
(in this case the repo
directory).
Other project structures
If you have other project structure, place the conftest.py
in the package root dir (the one that contains packages but is not a package itself, so does not contain an __init__.py
), for example:
repo
├── conftest.py
├── spam
│ ├── __init__.py
│ ├── bacon.py
│ └── egg.py
├── eggs
│ ├── __init__.py
│ └── sausage.py
└── tests
├── test_bacon.py
└── test_egg.py
src
layout
Although this approach can be used with the src
layout (place conftest.py
in the src
dir):
repo
├── src
│ ├── conftest.py
│ ├── spam
│ │ ├── __init__.py
│ │ ├── bacon.py
│ │ └── egg.py
│ └── eggs
│ ├── __init__.py
│ └── sausage.py
└── tests
├── test_bacon.py
└── test_egg.py
beware that adding src
to PYTHONPATH
mitigates the meaning and benefits of the src
layout! You will end up with testing the code from repository and not the installed package. If you need to do it, maybe you don't need the src
dir at all.
Where to go from here
Of course, conftest
modules are not just some files to help the source code discovery; it's where all the project-specific enhancements of the pytest
framework and the customization of your test suite happen. pytest
has a lot of information on conftest
modules scattered throughout their docs; start with conftest.py: local per-directory plugins
Also, SO has an excellent question on conftest
modules: In py.test, what is the use of conftest.py files?
回答5:
Run pytest
itself as a module with:
python -m pytest tests
回答6:
You can run with PYTHONPATH in project root
PYTHONPATH=. py.test
Or use pip install as editable import
pip install -e . # install package using setup.py in editable mode
回答7:
I created this as an answer to your question and my own confusion. I hope it helps. Pay attention to PYTHONPATH in both the py.test command line and in the tox.ini.
https://github.com/jeffmacdonald/pytest_test
Specifically: You have to tell py.test and tox where to find the modules you are including.
With py.test you can do this:
PYTHONPATH=. py.test
And with tox, add this to your tox.ini:
[testenv]
deps= -r{toxinidir}/requirements.txt
commands=py.test
setenv =
PYTHONPATH = {toxinidir}
回答8:
I started getting weird ConftestImportFailure: ImportError('No module named ...
errors when I had accidentally added __init__.py
file to my src directory (which was not supposed to be a Python package, just a container of all source).
回答9:
I fixed it by removing the top-level __init__.py
in the parent folder of my sources.
回答10:
I was getting this error due to something even simpler (you could even say trivial). I hadn't installed the pytest
module. So a simple apt install python-pytest
fixed it for me.
'pytest' would have been listed in setup.py as a test dependency. Make sure you install the test requirements as well.
回答11:
For me the problem was tests.py
generated by Django along with tests
directory. Removing tests.py
solved the problem.
回答12:
I got this error as I used relative imports incorrectly. In the OP example, test_app.py should import functions using e.g.
from repo.app import *
However liberally __init__.py files are scattered around the file structure, this does not work and creates the kind of ImportError seen unless the files and test files are in the same directory.
from app import *
Here's an example of what I had to do with one of my projects:
Here’s my project structure:
microbit/
microbit/activity_indicator/activity_indicator.py
microbit/tests/test_activity_indicator.py
To be able to access activity_indicator.py from test_activity_indicator.py I needed to:
- start test_activity_indicatory.py with the correct relative import:
from microbit.activity_indicator.activity_indicator import *
- put __init__.py files throughout the project structure:
microbit/
microbit/__init__.py
microbit/activity_indicator/__init__.py
microbit/activity_indicator/activity_indicator.py
microbit/tests/__init__.py
microbit/tests/test_activity_indicator.py
回答13:
I had a similar issue. pytest
did not recognize a module installed in the environment I was working in.
I resolved it by also installing pytest
into the same environment.
回答14:
Very often the tests were interrupted due to module being unable to be imported,After research, I found out that the system is looking at the file in the wrong place and we can easily overcome the problem by copying the file, containing the module, in the same folder as stated, in order to be properly imported. Another solution proposal would be to change the declaration for the import and show MutPy the correct path of the unit. However, due to the fact that multiple units can have this dependency, meaning we need to commit changes also in their declarations, we prefer to simply move the unit to the folder.
来源:https://stackoverflow.com/questions/10253826/path-issue-with-pytest-importerror-no-module-named-yadayadayada