测试和python包结构

And*_*rea 8 python package

我在构建我的python项目时遇到了一些问题.目前它是同一文件夹中的一堆文件.我试着像它一样构造它

proj/
  __init__.py
  foo.py
  ...
  bar/
    __init__.py
    foobar.py
    ...
  tests/
    foo_test.py
    foobar_test.py
    ...
Run Code Online (Sandbox Code Playgroud)

问题是我无法从内部目录导入外部目录中的模块.这对测试尤其烦人.

我已经阅读了关于相关进口的PEP 328和关于主要模块的相对进口的PEP 366.但是这两种方法都要求基础包在我的PYTHONPATH中.确实,我得到以下错误

ValueError:在非包中尝试相对导入.

所以我在测试文件的顶部添加了以下样板代码

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
Run Code Online (Sandbox Code Playgroud)

我仍然得到同样的错误.什么是正确的方法

  • 构建一个包,完成测试,和
  • 将基目录添加到路径以允许导入?

编辑根据评论中的要求,我添加了一个失败的示例导入(在文件中foo_test.py)

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
from ..foo import Foo
Run Code Online (Sandbox Code Playgroud)

nco*_*lan 12

使用-m开关运行代码时,将添加当前目录sys.path.因此,运行测试的最简单方法是proj使用以下命令从父目录:

python -m proj.tests.foo_test
Run Code Online (Sandbox Code Playgroud)

要使其工作,您需要__init__.py在测试目录中包含一个文件,以便将测试正确识别为包的一部分.


sam*_*ias 5

我想尽可能使用完整的proj.NAME包前缀导入模块.这是Google Python样式指南推荐的方法.

允许您保留包结构,使用完整包路径并继续开发的一个选项是使用virtualenv并将项目置于开发模式.您的项目setup.py需要使用setuptools而不是distutils获取develop命令.

这可以让你避免sys.path.append上面的东西:

% virtualenv ~/virt
% . ~/virt/bin/activate
(virt)~% cd ~/myproject
(virt)~/myproject% python setup.py develop
(virt)~/myproject% python tests/foo_test.py
Run Code Online (Sandbox Code Playgroud)

foo_test.py使用:

from proj.foo import Foo
Run Code Online (Sandbox Code Playgroud)

现在,当您python从virtualenv中运行时,您PYTHONPATH将指向项目中的所有包.您可以创建一个较短的shell别名来输入您的virtualenv,而无需. ~/virt/bin/activate每次都输入.