Zor*_*b29 72 python import pytest
我正在使用Python编写一个包.我用virtualenv.我在virtualenv的.pth路径中设置了模块根目录的路径,这样我就可以在开发代码的同时导入包的模块并进行测试(问题1:这是一个好方法吗?).这工作正常(这是一个例子,这是我想要的行为):
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from rc import ns
>>> exit()
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python tests/test_ns.py
issued command: echo hello
command output: hello
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试使用PyTest,我会收到一些导入错误消息:
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ pytest
=========================================== test session starts ============================================
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/zz/Desktop/GitFolders/rc, inifile:
collected 0 items / 1 errors
================================================== ERRORS ==================================================
________________________________ ERROR collecting tests/test_ns.py ________________________________
ImportError while importing test module '/home/zz/Desktop/GitFolders/rc/tests/test_ns.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ns.py:2: in <module>
from rc import ns
E ImportError: cannot import name ns
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================= 1 error in 0.09 seconds ==========================================
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ which pytest
/home/zz/Desktop/VirtualEnvs/VEnvTestRc/bin/pytest
Run Code Online (Sandbox Code Playgroud)
我有点困惑,看起来这表示导入错误,但Python做得很好,为什么PyTest特别存在问题?对原因/补救措施的任何建议(问题2)?我用谷歌搜索并堆叠溢出了PyTest的'ImportError:无法导入'错误,但是我得到的命中与丢失的python路径相关并对此进行了补救,这似乎不是问题.有什么建议?
Zor*_*b29 84
找到答案:
__init__.py
如果您打算使用pytest,请不要将文件放在包含TESTS的文件夹中.我有一个这样的文件,删除它解决了问题.
这实际上埋没在PATH问题的第二个答案的评论中,pytest'ImportError:没有名为YadaYadaYada的模块'所以我没有看到它,希望它在这里得到更多的可见性.
Tom*_*Tom 45
我不能说我明白为什么会这样,但我遇到了同样的问题,如果我跑的话,测试工作正常python -m pytest
.
我是一个virtualenv,全球也有pytest:
(proj)tom@neon ~/dev/proj$ type -a python
python is /home/tom/.virtualenvs/proj/bin/python
python is /usr/bin/python
(proj)tom@neon ~/dev/proj$ python -V
Python 3.5.2
(proj)tom@neon ~/dev/proj$ type -a pytest
pytest is /home/tom/.virtualenvs/proj/bin/pytest
pytest is /usr/bin/pytest
(proj)tom@neon ~/dev/proj$ pytest --version
This is pytest version 3.5.0, imported from /home/tom/.virtualenvs/proj/lib/python3.5/site-packages/pytest.py
Run Code Online (Sandbox Code Playgroud)
ian*_*ian 25
从 pytest 7.0 开始,您现在可以在 pytest.ini 中添加 pythonpath。无需在根目录中添加__init__.py
或。conftest.py
[pytest]
minversion = 7.0
addopts = --cov=src
pythonpath = src
testpaths =
tests
Run Code Online (Sandbox Code Playgroud)
无需任何参数即可运行pytest
。
https://docs.pytest.org/en/7.0.x/reference/reference.html#confval-pythonpath
更新:
这是一个关于如何使用上述配置设置项目的示例存储库:
https://github.com/ianpogi5/pytest-path
mik*_*ent 22
2024-02-10 路径和能见度之谜的解释
我最初是在 2021 年 10 月回答这个问题的。多年来我一直在解决这个问题。正如我在下面的原始答案中所描述的,这里的解决方案都不起作用。两年多来,我获得了 24 票赞成(和 2 票反对),所以其他人似乎也遇到了类似的棘手困难。我不情愿地得出结论,我必须进行操作sys.path
才能让 pytest 能够“看到”我认为它应该看到的文件。
我错了,无法理解有关路径的一些东西。至关重要的是,这涉及到项目的运行(就像我的大多数项目一样),其中使用以下命令运行应用程序(在 W10 中):
> python src\core
Run Code Online (Sandbox Code Playgroud)
也就是说,从一开始,CWD就不是当前(项目根)目录,而是一个子目录【项目根目录】\src\core(其中包含文件__main__.py
)
这就是问题出现的地方。如果您实际上没有在项目的根目录中运行文件,您需要注意,将该目录放入tests
根目录将使您陷入痛苦和困惑的世界:同级 .py 文件将莫名其妙地无法“找到” ” 在您的主“运行”目录中,即 CWD 所在的位置,即通过命令行。
相反,就我而言,我需要根“tests”目录成为 src\core 的子目录(相对于我的项目的根目录)。
作为更一般的规则:当您将项目作为应用程序运行时,无论项目的 CWD 位于何处,您都必须放置“tests”目录。
希望这对某人有帮助。
-------------- 我最初对 2021 年 10 月的天真、错误的回答:
另一个建议
我在 SO 和其他地方探索了这个问题以及其他各种问题...有关在项目目录结构的各个部分中添加(或删除)空 in 和/或 conftest.py 的所有内容__init__.py
,有关 PYTHONPATH 的所有内容等,等等:这些解决方案都不适合我,实际上这是一个非常简单的情况,并且不应该引起任何悲伤。
我认为这是 pytest 当前设置中的一个缺陷。事实上,我最近收到了一条来自 SO 上某人的消息,他清楚地知道他的东西。他说 pytest 并不是设计用于(根据 Java/Groovy/Gradle)单独的“src”和“test”目录结构,并且测试文件应该混合在应用程序目录和文件中。这也许在某种程度上提供了解释……但是,测试,特别是集成/功能测试,并不总是一定与特定目录完全对应,我认为 pytest 应该在这方面为用户提供更多选择。
我的项目结构:
project_root
src
core
__init__.py
__main__.py
my_other_file.py
tests
basic_tests
test_first_tests.py
Run Code Online (Sandbox Code Playgroud)
导入问题提出:很简单,__main__.py
有一行import my_other_file
. python src/core
当我刚刚运行应用程序(即从根目录运行)时,这(毫不奇怪)工作正常。
但是当我运行pytest
导入测试时__main__.py
我得到
ModuleNotFoundError: No module named 'my_other_file'
Run Code Online (Sandbox Code Playgroud)
__main__.py
在尝试导入“my_other_file”的行上。请注意,就我而言,这里的问题是,在 pytest 测试过程中,一个应用程序文件无法在同一包中找到另一个应用程序文件。
使用 PYTHONPATH
经过大量实验,并将__init__.py
文件和 confest.py 文件放入我能找到的几乎每个目录中(我认为关键文件已__init__.py
添加到“tests”和“basic_tests”中,请参阅上面的目录结构),并且然后将 PYTHONPATH 设置为如下
PYTHONPATH=D:\My Documents\software projects\EclipseWorkspace\my_project\src\core
Run Code Online (Sandbox Code Playgroud)
...我发现它有效。测试文件中的导入必须进行一些调整,一般模式是from core import app, project
,但测试文件能够“看到” core
,并且至关重要的是,无需弄乱import
应用程序文件中的命令。
然而......由于某种原因,现在使用这种方法测试运行速度要慢得多!与下面的解决方案相比,core
可以看到包仅被加载一次,我怀疑 PYTHONPATH 解决方案可能会导致大量代码被一次又一次地重新加载。我还不能证实这一点,但我看不到任何其他解释。
另一种选择
正如我所说,我认为这是 pytest 设置中的一个缺陷。我完全不知道 pytest 做了什么来建立常识性的设置sys.path
,但它显然是错误的。应该不需要依赖 PYTHONPATH 或其他什么,如果这确实是“官方”解决方案,那么关于这个主题的文档非常缺乏。
唯一有效的解决方案,至少在我的机器上(OS W10 和 Linux,如 pytest 7.3.1),是将应用程序包添加到sys.path
. 乱搞是不可取的sys.path
,但在这种情况下,其他任何事情对我来说都不起作用。
最明显的地方是conftest.py
,它在每次 pytest 运行开始时执行,并保留在项目根目录中。它不涉及应用程序文件的修改。通常(对于上述目录/文件设置):
this_file_path = pathlib.Path(__file__)
src_core_dir_path_str = str(this_file_path.parent.joinpath('src', 'core'))
sys.path.insert(0, src_core_dir_path_str)
Run Code Online (Sandbox Code Playgroud)
我目前(2023-08)使用 pytest v 7.3.1,并且还尝试编辑 pytest.ini,如ian's 2022 答案所建议,其中建议 pytest.ini 中的这些配置是解决问题的新事物自 v7(2021 年 12 月发布)起。在我的机器中,这并不能解决问题:如果不手动更改sys.path
pytest 在我的示例中的导入尝试__main__.py
会像以前一样失败:因为import my_other_file
raises ModuleNotFoundError: No module named 'my_other_file'
。
PS 我现在已经建立了一个最小的 git 存储库来说明问题:在https://github.com/Mrodent/pytest_probs/tree/main下载 .zip ,并阅读我在 README.md 中所说的内容。有兴趣知道是否有人得到与我得到的不同的结果。
--
Aar*_*lin 17
我只是通过删除项目根目录中的__init__.py来解决此问题:
.
??? __init__.py <--- removed
??? models
? ??? __init__.py
? ??? address.py
? ??? appointment.py
? ??? client.py
??? requirements.txt
??? setup.cfg
??? tests
? ??? __init__.py
? ??? models
? ? ??? __init__.py
? ? ??? appointment_test.py
? ? ??? client_test.py
? ??? other_test.py
??? script.py
Run Code Online (Sandbox Code Playgroud)
小智 11
就我而言,我在一个容器中工作,不幸的是 pytest 倾向于使用 python2.7 而不是我选择的 python3 解释器。
在我的情况下,这有效:
python3 -m pytest
Run Code Online (Sandbox Code Playgroud)
我的文件夹结构
/
app/
-module1.py
-module2.py
-tests/
--test_module1.py
--test_module2.py
requirements.txt
README.md
Run Code Online (Sandbox Code Playgroud)
Mar*_*ark 10
我有同样的问题,但出于另一个原因,而不是提到的:
我在全局安装了py.test,而软件包安装在虚拟环境中.
解决方案是pytest
在虚拟环境中安装.(如果你的shell散列可执行文件,就像Bash那样,使用hash -r
或使用完整路径py.test
)
小智 10
我通过PYTHONPATH
为我运行测试的特定配置设置环境变量来解决我的问题。
当您在 PyCharm 上查看测试文件时:
Edit Configurations
PYTHONPATH
。更新
$PYTHONPATH
为项目的根目录并将其导出:export PYTHONPATH=$(pwd)
Run Code Online (Sandbox Code Playgroud)
__init__.py
从tests/
目录或src/
目录中删除 。另请注意:
__init__.py
conftest.py
在项目的根目录中不需要。$PYTHONPATH
仅在当前终端/控制台会话期间可用;所以你每次都需要设置这个。(如果您使用的是 pycharm,则可以按照此更新之前的步骤进行操作)。只需conftest.py
在项目根目录下放一个空文件,因为当pytest
发现一个 conftest.py 时,它会修改 sys.path 以便它可以从conftest
模块中导入东西。一般目录结构可以是:
Root
??? conftest.py
??? module1
? ??? __init__.py
? ??? sample.py
??? tests
??? test_sample.py
Run Code Online (Sandbox Code Playgroud)
我已将所有测试放在测试文件夹中,但遇到了相同的错误。我通过在该文件夹中添加一个解决了这个问题,__init__.py
如下所示:
.
|-- Pipfile
|-- Pipfile.lock
|-- README.md
|-- api
|-- app.py
|-- config.py
|-- migrations
|-- pull_request_template.md
|-- settings.py
`-- tests
|-- __init__.py <------
|-- conftest.py
`-- test_sample.py
Run Code Online (Sandbox Code Playgroud)
请在此处查看:https : //docs.pytest.org/en/documentation-restructure/background/pythonpath.html
我有 pytest 的问题(已使用 解决python -m pytest
);错误是
FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.9/site-packages/...
Run Code Online (Sandbox Code Playgroud)
我发现问题__init__.py
在tests/
和中丢失tests/subfolders
。
我有一个类似的问题,完全相同的错误,但不同的原因。我运行测试代码很好,但是针对旧版本的模块。在我的代码的先前版本中,一个类存在,而另一个不存在。更新我的代码后,我应该运行以下命令来安装它。
sudo pip install ./ --upgrade
安装更新的模块后,运行 pytest 产生了正确的结果(因为我使用了正确的代码库)。
就我而言,发生导入错误是因为包指向另一个同名的包/目录,并且其路径比我实际想要的文件夹高一级。我想这也解释了为什么有些人需要删除 _ init _.py 而其他人需要重新添加。
我只是把print(the_root_package.__path__)
(after import the_root_package
) 放在python
控制台和pytest
脚本中来比较差异
底线:当你这样做时python
,你导入的包可能与你运行时的包不同pytest
。
如果您有一个tests.py
文件和一个带有的测试文件夹,则会发生此问题tests/__init__.py
。
在收集过程中,pytest会找到文件夹,但是当尝试从文件夹中导入测试文件时,tests.py
文件会导致导入问题。
要解决此问题,只需删除tests.py
文件,然后将所有测试放在tests/
文件夹中即可。
对于您的特定情况,修复将精确地是:
/home/zz/Desktop/GitFolders/rc/tests.py
/home/zz/Desktop/GitFolders/rc/tests/__init__.py
存在 归档时间: |
|
查看次数: |
52266 次 |
最近记录: |