2020年8月12日 星期三

[ Python 常見問題 ] Ensuring py.test includes the application directory in sys.path

 Source From Here

Question
I have a project directory structure as follows (which I think is pretty standard):
  1. my_project  
  2.     setup.py  
  3.     mypkg  
  4.         __init__.py  
  5.         foo.py  
  6.     tests  
  7.         functional  
  8.             test_f1.py  
  9.         unit  
  10.             test_u1.py  
I'm using py.test for my testing framework, and I'd expect to be able to run py.test tests when in the my_project directory to run my tests. This does indeed work, until I try to import my application code using (for example) import mypkg in a test. At that point, I get the error "No module named mypkg". On doing a bit of investigation, it appears that py.test runs the tests with the directory of the test file in sys.path, but not the directory that py.test was run from.

In order to work around this, I have added a conftest.py file to my tests directory, containing the following code:
  1. import sys, os  
  2.   
  3. # Make sure that the application source directory (this directory's parent) is  
  4. # on sys.path.  
  5.   
  6. here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  
  7. sys.path.insert(0, here)  
This seems to work, but is it a good way of making sure that the tests see the application code? Is there a better way of achieving this, or am I doing something wrong in how I have my project structured? I've looked in the py.test documentation, but I can't see an explanation of this problem or what the recommended approach is to deal with it.

How-To
As you say yourself py.test basically assumes you have the PYTHONPATH setup up correctly. There are several ways of achieving this:
* Give your project a setup.py and use pip install -e . in a virtualenv for this project. This is probably the standard method.
* As a variation on this if you have a virtualenv but no setup.py use your venv's facility to add the projects directory on sys.path, e.g. pew add . if you use pew, or add2virtualenv . if you use virtualenv and the extensions of virtualenvwrapper.
* If you always like the current working directory on sys.path you can simply always export PYTHONPATH='' in your shell. That is ensure the empty string on on sys.path which python will interpret as the current working direcotry. This is potentially a security hazard though.
* My own favourite hack, abuse how py.test loads conftest files: put an empty conftest.py in the project's top-level directory.

The reason for py.test to behave this way is to make it easy to run the tests in a tests/ directory of a checkout against an installed package. If it would unconditionally add the project directory to the PYTHONPATH then this would not be possible anymore.

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...