测试和python包结构

测试和python包结构,python,package,Python,Package,我在构建python项目时遇到了一些问题。目前,它是同一文件夹中的一组文件。我试着把它组织成这样 proj/ __init__.py foo.py ... bar/ __init__.py foobar.py ... tests/ foo_test.py foobar_test.py ... 问题是我无法从内部目录导入外部目录中的模块。这对于测试来说尤其烦人 我已经从主模块中了解了相对导入和相对导入。但这两种方法都要求基本包位

我在构建python项目时遇到了一些问题。目前,它是同一文件夹中的一组文件。我试着把它组织成这样

proj/
  __init__.py
  foo.py
  ...
  bar/
    __init__.py
    foobar.py
    ...
  tests/
    foo_test.py
    foobar_test.py
    ...
问题是我无法从内部目录导入外部目录中的模块。这对于测试来说尤其烦人

我已经从主模块中了解了相对导入和相对导入。但这两种方法都要求基本包位于PYTHONPATH中。事实上,我得到了以下错误

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

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

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
但我还是犯了同样的错误。正确的方法是什么

  • 构建一个包含测试的包,以及
  • 是否将基本目录添加到允许导入的路径
编辑根据注释中的要求,我添加了一个失败的导入示例(在文件
foo_test.py
中)


我喜欢尽可能使用完整的
proj.NAME
package前缀导入模块。这是委员会建议的方法

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

这样可以避免上面的
sys.path.append
内容:

% virtualenv ~/virt
% . ~/virt/bin/activate
(virt)~% cd ~/myproject
(virt)~/myproject% python setup.py develop
(virt)~/myproject% python tests/foo_test.py
其中
foo_test.py
使用:

from proj.foo import Foo

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

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

python -m proj.tests.foo_test

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

能否显示一个失败的导入示例?另外,请包括您的
PYTHONPATH
echo$PYTHONPATH
的值,它现在是空的。看起来很有趣。我将不得不调查这个虚拟工具。它是否允许我在虚拟环境中工作,在那里我可以作为一个包访问当前目录?或者它只是一个带有独立python发行版的工具,更像是一个chroot,每次使用它之前我都必须安装我的包?这是一种快速创建一个独立python环境的方法,您可以将它吹走并快速重新创建。非常适合使用pip/easy_install试用模块,而不会污染系统Python。virtualenv
activate
脚本将
~/virt/bin
目录插入到
路径的前面,以便在系统python之前找到
~/virt/bin/python
develop
命令使用
.pth
文件将项目包链接到
~/virt/lib/pythonx.x/site包中。它还修改了
PS1
提示,让您知道自己“在”virtualenv中。这是一个很好的建议,尽管现在您可能希望选择
distribute
作为
setuptools
的更积极维护的替代方案。同意,
setuptools
正在广泛使用,但人们应该转向
distribute
,兼容并积极维护。谢谢!所以我缺少的是
测试本身应该是一个包。这是一个相当愚蠢的错误,但我想不出来。
python -m proj.tests.foo_test