首页 文章

测试和python包结构

提问于
浏览
8

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

proj/
  __init__.py
  foo.py
  ...
  bar/
    __init__.py
    foobar.py
    ...
  tests/
    foo_test.py
    foobar_test.py
    ...

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

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

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

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

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))

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

  • 构造一个包,完成测试,和

  • 将基目录添加到允许导入的路径?

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

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
from ..foo import Foo

2 回答

  • 5

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

    python -m proj.tests.foo_test
    

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

  • 12

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

    允许您保留包结构,使用完整包路径并继续开发的一个选项是使用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
    

    foo_test.py 使用的地方:

    from proj.foo import Foo
    

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

相关问题