我在目录中安排了一个python模块。称为foo
。
这是文件布局:
caller.py
foo/__init__.py
foo/bar.py
foo/test/bar_test.py
也就是说,该模块被称为foo
,并且foo/__init__.py
中的import foo
语句运行时,caller.py
中的代码也将被导入。
在foo/__init__.py
中,我希望访问bar.py
的内容。这是通过import foo.bar
完成的。
编写在foo/test/bar_test.py
中运行的代码时出现了我的问题。如果该文件只是foo/bar_test.py
,那么它也可以使用import foo.bar
来导入foo.bar.py
的内容。不幸的是,我们有一个编码标准,其中规定单元测试位于一个名为tests
的子目录中。
鉴于该编码标准,我们如何导入bar.py?
这不起作用:
# foo/test/bar_test.py
import foo.bar
def test_return5():
assert bar.return5() == 5
它给了我
$ py.test
================================================== test session starts ==================================================
platform linux -- Python 3.6.3, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
rootdir: /home/hadoop/xxx/foo, inifile:
collected 0 items / 1 errors
======================================================== ERRORS =========================================================
___________________________________________ ERROR collecting test/bar_test.py ___________________________________________
ImportError while importing test module '/home/hadoop/xxx/foo/test/bar_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test/bar_test.py:3: in <module>
import foo.bar
E ModuleNotFoundError: No module named 'foo'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================ 1 error in 0.10 seconds ================================================
这有效,但是很麻烦:
# foo/test/bar_test.py
import os
import sys
sys.path.append( os.path.join(os.path.dirname(__file__), "../.."))
import foo.bar
def test_return5():
assert foo.bar.return5() == 5
这不起作用:
# foo/test/bar_test.py
import os
import sys
sys.path.append( os.path.join(os.path.dirname(__file__), ".."))
import bar
def test_return5():
assert bar.return5() == 5
因为:
$ py.test
================================================== test session starts ==================================================
platform linux -- Python 3.6.3, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
rootdir: /home/hadoop/xxx/foo, inifile:
collected 0 items / 1 errors
======================================================== ERRORS =========================================================
___________________________________________ ERROR collecting test/bar_test.py ___________________________________________
ImportError while importing test module '/home/hadoop/xxx/foo/test/bar_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test/bar_test.py:8: in <module>
import bar
bar.py:3: in <module>
import foo
E ModuleNotFoundError: No module named 'foo'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================ 1 error in 0.10 seconds ================================================
因为bar.py具有:
# foo/bar.py
import foo
def return5():
return 5
答案 0 :(得分:1)
import foo.bar as bar
如果您从父目录运行pytest(至少现在才对我有用),那么它应该在bar_test.py
中有效。
您无法在python 3中使用import bar
(我假设您正在使用的是它),因为它含糊不清-有关更多详细信息,请参见PEP-404和a more in depth stackoverflow answer。
编辑:查看扩展示例,问题似乎在于bar_test.py
不是foo
软件包的一部分(因为test
目录不是软件包) 。如果您将__init__.py
文件添加到test
目录,则pytest会愉快地运行测试::
$ pytest foo/test/bar_test.py
===================================================================== test session starts ======================================================================
platform linux -- Python 3.5.3, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: /home/xxxx/tmp/blank, inifile:
collected 1 item
foo/test/bar_test.py . [100%]
=================================================================== 1 passed in 0.03 seconds ===================================================================
$ ls -lh foo/test/
total 12K
-rw-rw-r-- 1 xxxx xxxx 95 Jul 26 14:44 bar_test.py
-rw-rw-r-- 1 xxxx xxxx 0 Jul 27 16:38 __init__.py
-rw-rw-r-- 1 xxxx xxxx 132 Jul 27 16:38 __init__.pyc
drwxrwsr-x 2 xxxx xxxx 4.0K Jul 27 16:38 __pycache__
请注意,我必须在添加__pycache__
后删除__init__.py
。
有关更多信息,请参见pytest docs。