VSCode pytest测试发现失败

105

Pytest测试发现失败。用户界面提示:

测试发现错误,请检查测试的配置设置。

输出窗口显示:

Test Discovery failed: 
Error: Traceback (most recent call last):
  File "C:\Users\mikep\.vscode\extensions\ms-python.python-2019.4.11987\pythonFiles\testing_tools\run_adapter.py", line 16, in <module>
    main(tool, cmd, subargs, toolargs)
  File "C:\Users\mikep\.vscode\extensions\ms-python.python-2019.4.11987\pythonFiles\testing_tools\adapter\__main__.py", line 90, in main
    parents, result = run(toolargs, **subargs)
  File "C:\Users\mikep\.vscode\extensions\ms-python.python-2019.4.11987\pythonFiles\testing_tools\adapter\pytest.py", line 43, in discover
    raise Exception('pytest discovery failed (exit code {})'.format(ec))
Exception: pytest discovery failed (exit code 3)

这是我的设置:

{
    "python.pythonPath": ".venv\\Scripts\\python.exe",
    "python.testing.pyTestArgs": [
        "tests"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.pyTestEnabled": true
}

FWIW,我可以成功地从命令行运行pytest。


你是如何在命令行中运行pytest的?你是否使用虚拟环境中的pytest,并使用与settings.json中指定的相同参数? - Brett Cannon
1
从命令行中,我只是在与 VS Code 使用相同的虚拟环境中运行 pytest tests - devlife
是的,我也在VSCode终端中运行pytest,然后它被发现了,这样我就可以在GUI中运行它了。 - Martin Alexandersson
27个回答

171

在创建一个存在导入错误的测试时,我花了很长时间试图解密这个无用的错误。在进行任何更深入的故障排除之前,请验证您的测试套件是否可以实际执行。

pytest --collect-only 是您的好朋友。


输出应该是什么? - Little Bobby Tables
4
@LittleBobbyTables 的内容大致是 ================================================ 在 0.16 秒内收集了 76 个测试 ================================================= - xi.lin
@autumn 但它只是在命令行中发现和显示,我需要在 VS Code 的测试选项卡中看到它? - Vikas Satpute
5
如果失败了该怎么办? - gustavz
1
这非常有帮助!我有一行未注释的错误代码导致测试无法运行,但是这个命令立即突出了这个错误。 - dzubke
显示剩余3条评论

62

由于我不知道为什么会出现这种情况,也许与您的测试结构有关,因此本回答并不完整。

我通过在我的测试文件夹中放置一个__init__.py文件来解决了这个问题。

例如:


├───.vscode
│       settings.json
│
├───app
│       myapp.py
│
└───tests
        test_myapp.py
        __init__.py

几天前这个还能工作,但是Python扩展最近更新了。我不确定这是否是预期行为或者是发现方式的副作用。

https://github.com/Microsoft/vscode-python/blob/master/CHANGELOG.md
使用Python代码来发现pytest中的测试。(#4795)


3
我在我的“tests”目录中有一个“init.py”。 - devlife
1
@devlife,helgso的解决方案适用于您吗?链接 我可以确认当我降级时,我遇到了相同的退出代码3问题。 - WildStriker
1
如果您的“tests”文件夹中有子模块,请在这些子文件夹中添加“__init__”文件。 - cpinamtz
1
我的解决方案是相反的:*删除__init__.py*。不确定为什么这样可以修复它,或者为什么一开始会出现问题。我确定有一段时间前我不得不添加它。 - NostraDavid

16

我想在这里添加我的答案,因为这可能会影响使用.env文件来设置项目环境设置的人,因为这是12因素应用程序的常见配置。

我的示例假设您正在使用pipenv进行虚拟环境管理,并且您在项目的根目录中有一个.env文件。

我的vscode工作区设置json文件如下所示。对我来说,关键的一行是"python.envFile": "${workspaceFolder}/.env",

{
    "python.pythonPath": ".venv/bin/python",
    "python.linting.enabled": true,
    "python.linting.pylintEnabled": true,
    "python.linting.pycodestyleEnabled": false,
    "python.linting.flake8Enabled": false,
    "python.linting.pylintPath": ".venv/bin/pylint",
    "python.linting.pylintArgs": [
        "--load-plugins=pylint_django",
    ],
    "python.formatting.provider": "black",
    "python.formatting.blackArgs": [
        "--line-length",
        "100"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.pytestEnabled": true,
    "python.testing.pytestPath": ".venv/bin/pytest",
    "python.envFile": "${workspaceFolder}/.env",
    "python.testing.pytestArgs": [
        "--no-cov"
    ],
}

我希望这篇内容能为某些人节省时间,就像我曾经花费的时间一样。


谢谢,env文件设置在我的情况下也起作用了。我需要CLI选项或者环境变量来设置测试的关键值。而且在tox.ini等文件中指定它们不可能,因为这些信息是私有的。 - E. Körner
对我来说,它是这样的:"python.testing.pytestPath": "{$workspaceFolder}\\Lib\\pytest", - paradox
这对我有用,当我添加了 --no-cov 时,我特别忘记了它,但是一旦添加后,它立即起作用。谢谢! - Aidan H

16

在我的情况下,VSCode无法发现测试的问题是由于在setup.cfg(或者是pytest.ini)中启用了coverage模块。

addopts= --cov <path> -ra

由于测试覆盖率不足,导致测试发现失败。解决方案是从配置文件中删除该行。

此外,如文档中建议的:

您还可以通过将以下设置之一且仅为一个设置为 true 来手动配置测试:python.testing.unittestEnabledpython.testing.pytestEnabledpython.testing.nosetestsEnabled

settings.json 中,还可以使用 --no-cov 标志禁用覆盖率:

"python.testing.pytestArgs": ["--no-cov"],

编辑:

略微相关 - 对于更复杂的项目,当使用pytest运行测试时(发生ModuleNotFoundError的情况下),可能需要更改settings.json中的rootdir参数:

    "python.testing.pytestArgs": [
        "--rootdir","${workspaceFolder}/<path-to-directory-with-tests>"
    ],

1
我花了几个星期的时间试图解决pytest发现失败的问题。最终明确设置“rootdir”解决了这个问题。非常感谢!!! - Venkatachalam

9
似乎是VS Code Python扩展程序最新版本的一个漏洞。我遇到了同样的问题,然后我把Python扩展程序降级到2019.3.6558,这样就可以正常工作了。所以我们应该进入VS Code扩展程序列表,选择Python扩展程序,并从该扩展程序的设置中“安装其他版本…”。希望这对你也有用。

1
非常感谢!我将版本从2020.1.58038降级到2019.3.6558,现在我的测试已经被发现了。之前我一直遇到ModuleNotFoundError: No module named 'tests.conftest'的问题。 - nico

5
在开始测试发现之前,请检查python.testing.cwd是否正确指向你的测试目录,以及你的python.testing.pytestEnabled是否设置为true
一旦这些要求正确设置,运行测试发现并查看其输出(参见OUTPUT窗口)。您应该会看到如下内容:
python $HOME/.vscode/extensions/ms-python.python-$VERSION/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir $ROOT_DIR_OF_YOUR_PROJECT -s --cache-clear
Test Discovery failed: 
Error: ============================= test session starts ==============================
<SETTINGS RELATED TO YOUR MACHINE, PYTHON VERSION, PYTEST VERSION,...>
collected N items / M errors
...

重点要强调的是最后一行:已收集N个项目/M个错误。接下来的行将包含有关 pytest 发现的测试的信息。 因此,你的测试可被发现,但与其正确执行有关的错误会出现。

以下行将包含错误,这些错误在大多数情况下将与不正确的导入有关

请检查之前是否已下载所有依赖项。如果你正在使用特定版本的依赖项(requirements.txt 文件中有类似于 your_package == X.Y.Z 的内容),请确保你需要的是正确的版本。


python.testing.cwd不在我的配置中,这就是帮助的作用! - charles.fg
python.testing.cwd 并不在我的配置中,这就是帮助所在! - undefined

5

我通过升级pytest到最新版本4.4.1并使用"pip install --upgrade pytest"命令来解决了这个问题。很明显我之前使用的是旧版本3.4.2。


16
更好的回答应该是:1. 具体说明旧版本为什么会导致问题。2. 说明新版本如何解决了这个问题。随意升级是一个显而易见的解决方案,大多数人不需要去StackOverflow学习这个。 - Frederick Ollinger

4
如果你在使用 pytest 时遇到了问题,我曾经也在发现测试部分方面苦苦挣扎。
在 vscode 中阅读一些打开的问题(其他)后,我找到了一个解决方法,使用test-adapter扩展程序。 market_place_link 这个扩展程序非常好用(并且解决了我的发现问题)。

4

测试文件需要命名为test_*.py或者*_test.py,才能在pytest集合中工作。

在命令行中运行pytest --collect-only,确保所有的测试都被找到。然后神奇的是,VSCode中的flask图标突然显示了测试文件及其测试。

作为一个新手,我一直将我的单元测试放在模块文件中,因为我在遵循unittest的模式,然后使用pytest *.py运行测试。这不适用于pytest,并且我没有找到一个命令行参数来覆盖命名约定。


3

我也曾经遇到过这个问题。现在已经解决了,我想分享一下我采取的步骤。

(Windows 10,Python 3.11,VS Code 1.75.1,pytest 7.2.1)

我不理解所有的步骤,也不知道它们是否都是必要的,但至少它起作用了。

我的项目结构如下:

src
├───.vscode
│       settings.json
│
├───app
│       __init__.py
│       myapp.py
│
└───tests
        __init__.py
        conftest.py
        test_myapp.py

我在VS Code中使用/打开的主要文件夹是src。在此布局中,任何位于其上方(如docs、venv相关等)的内容都无法在VS Code中访问。
步骤:
  1. 卸载并重新安装VS Code中的Python扩展,但这可能不是必要的。

  2. 如果存在以下文件夹,则递归删除src中的所有这些文件夹及其下属文件夹:.pytest_cache__pycache__(尽管后者可能不是必要的)。

  3. 在项目结构中所示的文件夹中放置空的__init__.py文件。

  4. src/.vscode/settings.json包含以下内容:

{
    "python.testing.pytestArgs": [
        "tests"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.pytestEnabled": true
}
  1. 在测试用例文件中(包括conftest.py),在导入我的应用程序之前(例如import appfrom app import ...等),我会包含以下内容:
from pathlib import Path
import os
import sys

main_folder = Path(__file__).parent.parent
sys.path.insert(0, str(main_folder))
sys.path.insert(0, str(main_folder / 'app'))
sys.path.insert(0, str(main_folder / 'tests'))
os.chdir(main_folder / 'app')

import app

这样可以使得测试在VS Code中被发现并正确工作。

要单独运行测试,在每个测试文件的末尾,我包含以下内容:

@report_execution_time
def main_test():

    os.system('python -m pytest ..')


if __name__ == "__main__":

    main_test()

我使用main_test函数,而不是将其“主体”放在if __name__ == "__main__":下面,这样我就可以在其上使用装饰器,在本例中用于报告执行时间。
希望这能对任何人有所帮助。

对我来说,在测试目录中添加一个__init__.py就解决了问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接