在python模块的py.test测试目录中,导入该模块的文件

时间:2018-07-23 16:02:31

标签: python pytest python-module

我在目录中安排了一个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

1 个答案:

答案 0 :(得分:1)

import foo.bar as bar

如果您从父目录运行pytest(至少现在才对我有用),那么它应该在bar_test.py中有效。

您无法在python 3中使用import bar(我假设您正在使用的是它),因为它含糊不清-有关更多详细信息,请参见PEP-404a 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