如何将包添加到sys路径进行测试

时间:2016-08-24 23:58:31

标签: python

python guide中有关将项目添加到sys路径以在测试中使用的说明引发了这个问题,除非我误解了指令,否则这些指令似乎不起作用

我有像这样的python项目的目录结构

sample/a.py
sample/b.py
sample/c.py
sample/__init__.py
test/context.py
test/test_something.py
test/__init__.py
docs

根据the python guide,我应该创建一个test / context.py文件并添加此

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

import sample

然后,在我的test/test_something.py文件中,它说我可以这样做

from .context import sample

指南说“这将始终按预期工作”。

但是,当我cd进入测试并运行

python -m unittest test_something

我收到错误

ValueError: Attempted relative import in non-package

并且错误消息具体指的是:from .context import sample

问题:如何正确地将我的示例包添加到sys路径?

在回答时,您是否还可以澄清解决方案是否会处理示例包中的绝对导入。例如,我的s​​ample.a导入sample.b等。当我以不同的方式构建测试时,我对sample.a进行了绝对导入,但由于它的相对导入为from .b import Boo,因此它生成了类似的错误

更新

`File "/usr/local/lib/python2.7/runpy.py", line 162 in _run_module_as_main "__main__", fname, loader, pkg_name)
File  "/usr/local/lib/python2.7/runpy.py", line 72, in _run_code exec code in run_globals
File  "/usr/local/lib/python2.7/unittest/__main__.py", line 12, in module main(module=None)
File  "/usr/local/lib/python2.7/unittest/main.py", line 94, in __init__ self.parseArgs(argv)
File  "/usr/local/lib/python2.7/unittest/main.py", line 149 in parseArgs self.createTests()
File  "/usr/local/lib/python2.7/unittest/main.py", line 158, in createTests self.module)
File  "/usr/local/lib/python2.7/unittest/loader.py", line 130, in loadTestsFromNames suites = [self.loadTestsFromName(name,module) for name in names]
File  "/usr/local/lib/python2.7/unittest/loader.py", line 91, in loadTestsFromName module = __import__('-'.join(parts_copy))
File "test_something.py", line 8, in module from .context import sample

更新

如果我从根目录运行以下命令

   python -m unittest test

它说,“冉0测试0.000秒”

如果@cuongnv的评论中提到,我是从根目录

运行的
python -m unittest test/test_something.py

或者这个(没有文件扩展名)

python -m unittest test/test_something 

它说“不支持按文件名导入”

4 个答案:

答案 0 :(得分:2)

尝试将空SOMETHING HAPPENED添加到__init__.pytests/应该这样做。

答案 1 :(得分:2)

  

问题:如何正确地将我的示例包添加到sys路径?

您正在以正确的方式执行此操作,但您错过了将您的文件夹声明为包裹。试试基督徒的解决方案,它应该有用。

您的路径存储在sys.path中。通过这样做:

sys.path.insert(0, os.path.abspath('..'))

您告诉您的python将上层文件夹(当前文件)添加到您的路径中。由于sys.path是一个列表,您可以使用其他列表方法,例如insertappend ......

在您的情况下,您将上部目录插入路径列表的顶部。

请参阅:

In [1]: import sys

In [2]: sys.path
Out[2]: 
['',
 '/usr/local/bin',
 '/usr/lib/python3.4',
 '/usr/lib/python3.4/plat-x86_64-linux-gnu',
 '/usr/lib/python3.4/lib-dynload',
 '/usr/local/lib/python3.4/dist-packages',
 '/usr/lib/python3/dist-packages',
 '/usr/local/lib/python3.4/dist-packages/IPython/extensions',
 '/home/cuong/.ipython']

In [3]: sys.path.insert(0, '/tmp/foo')

In [4]: sys.path
Out[4]: 
['/tmp/foo', **<-- on top**
 '',
 '/usr/local/bin',
 '/usr/lib/python3.4',
 '/usr/lib/python3.4/plat-x86_64-linux-gnu',
 '/usr/lib/python3.4/lib-dynload',
 '/usr/local/lib/python3.4/dist-packages',
 '/usr/lib/python3/dist-packages',
 '/usr/local/lib/python3.4/dist-packages/IPython/extensions',
 '/home/cuong/.ipython']

所以,从这里,当你有

import sample

你的python会尝试查看路径,看看是否有sample个包。

很遗憾,由于您忘记了sample __init__.py文件夹中的sample,因此无法找到query.overview = ...,因为您没有将其作为一个包。

希望我的解释可以帮助你理解,你可以处理与此不同的其他情况。

答案 2 :(得分:0)

我有一场战斗让我的测试目录结构在一个外面工作 IDE。请在下面找到我的解决方案经过测试 Windows 7使用python 3.6和Linux Mint使用python 3.4,运行代码 使用命令行:

python -m pytest test_compress_files.py

我编写的要测试的文件在名为的目录中名为compress_files.py \ SRC。调用包含要使用pytest运行的测试的文件 test_compress_files.py位于子目录\ tests中,因此完整目录路径为 \ SRC \测试。我需要在\ src \ tests中添加一个名为context.py的文件 目录。此文件在test_compress_files.py中用于启用对上面目录中的compress_files.py的访问。 __init__.py文件为空。

目录结构

\src
__init__.py
compress_files.py

\src\tests
__init__.py
context.py
test_compress_files.py  

compress_files.py包含要测试的脚本。

context.py:

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import compress_files  

该行:

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__)

来自于http://docs.python-guide.org/en/latest/writing/structure/的搭便车远足者指导python的建议。这会将/ src / tests目录上方的目录路径添加到sys.path,在本例中为/ src。

test_compress_files.py:

import os
import pytest
from .context import compress_files
from compress_files import *

# tests start here
...

答案 3 :(得分:0)

我无法发表评论,但是我在python 3.7 env中尝试了Oppy的答案,但失败了:

ImportError: cannot import name 'compress_files' from '__main__' (test_compress_files.py)

我使用修改后的test_compress_files.py(注意删除的点)解决了:

import os
import pytest
from context import compress_files
from compress_files import *

# tests start here
...