我想使用pytest对另一个名为src
的文件夹中的脚本进行单元测试。这是我的目录结构:
src
__init__.py
script1.py
script2.py
test
test_fun.py
但是,当我尝试通过命令行在pytest
文件夹中运行test
时,我看到以下错误
来自script2 import fun2
E ModuleNotFoundError:没有名为'script2'的模块
在每个脚本中,我都有以下内容
script2.py :
def fun2():
return('result_from_2')
script1.py :
from script2 import fun2
def fun1():
return(fun2()+'_plus_something')
test_fun.py :
import sys
sys.path.append('../')
from src.script1 import fun1
def test_fun1():
output1 = fun1()
# check output
assert output1=='result_from_2_plus_something'
如何使用上面提供的目录运行pytest?
答案 0 :(得分:2)
导入文件时,Python仅搜索当前目录,即运行入口点脚本的目录和sys.path
。
修改 test_fun.py ,如下所示:
import sys
sys.path.insert(0, '../src/')
from script1 import fun1
def test_fun1():
output1 = fun1()
# check output
assert output1=='result_from_2_plus_something'
答案 1 :(得分:1)
当我们运行pytest时,python使用sys.path查找模块以解决导入问题。所以,如果你 测试位于路径中:“ / Users / YourName / projectName / test”,您需要从“ / Users / YourName / projectName / src”导入一些模块 Python将无法找到它们。
那为什么Python可以找到'pytest'或'sys'?因为它们位于sys.path中的其他路径中。
要验证存在的路径,请使用:
import pprint
import sys
pprint.pprint(sys.path)
您将看到python用来解析导入的可能路径的列表:
['/Users/yourName/YourProject/test',
'/opt/anaconda3/bin',
'/opt/anaconda3/lib/python37.zip',
'/opt/anaconda3/lib/python3.7',
'/opt/anaconda3/lib/python3.7/lib-dynload',
'/opt/anaconda3/lib/python3.7/site-packages',
'/opt/anaconda3/lib/python3.7/site-packages/aeosa']
请注意,该列表不包含“ / Users / YourName / projectName / src”。因此,您需要在test_fun.py文件中使用以下命令在此列表中添加“ src”路径。
import sys
sys.path.append('/Users/YourName/projectName/src').
from src.script1 import fun1
执行此命令后,列表将如下所示:
['/Users/yourName/YourProject/test',
'/opt/anaconda3/bin',
'/opt/anaconda3/lib/python37.zip',
'/opt/anaconda3/lib/python3.7',
'/opt/anaconda3/lib/python3.7/lib-dynload',
'/opt/anaconda3/lib/python3.7/site-packages',
'/opt/anaconda3/lib/python3.7/site-packages/aeosa',
'/Users/yourName/YourProject/src']
然后Python将能够解析您的类的导入。
答案 2 :(得分:0)
执行此操作的一种好方法是遵循Pytest docs中的建议,并结合此答案here中给出的第三种方法。 这意味着:
packages
和package_dir
。阅读更多here。pip install -e .
安装“可编辑”文件,这将在您的项目文件夹中创建.egg.info并安装它。pytest
对其进行测试。pip uninstall name_of_package
删除“可编辑”包,然后使用rm -r $(find . -name '*.egg-info')
删除鸡蛋我知道,这似乎比简单地更改sys.path
的简单技巧要复杂,但这是一种更干净的方法。一开始让我很难理解的一件事是,使用此方法可以有效地安装软件包以进行测试。我没有用其他语言做到这一点。原因:
您可以将其视为也可以测试安装程序本身的一种方式。没有此步骤,就完全有可能通过测试套件,但安装程序已损坏(您最终会意外发布损坏的软件包)
(来自对此答案here的讨论)