几天后,Visual Studio Code Python 单元测试发现在几个包含名为
utils
的包的项目中不再适用于我:
2023-10-18 09:37:36.901 [info] Discovering unittest tests with arguments: /home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/unittestadapter/discovery.py,--udiscovery,-v,-s,./tests,-p,test_*.py
...
ModuleNotFoundError: No module named 'utils.export_to_dict_helper'; 'utils' is not a package
一旦我将整个
utils
文件夹重命名为其他名称(例如 helper_utils
),它就会起作用。使用从终端运行测试
python3 -m unittest discover -v tests
工作得很好,即使目录仍然命名为
utils
。我已经尝试将“Python”扩展降级几个月并切换到另一个Python版本(到目前为止尝试过3.8和3.11),但错误是一致的。
测试文件的顶部如下所示(打印 sys.path 用于调试):
import sys
print(sys.path)
# Other (working) imports...
from utils.data_storage_selector import DataStorageSelector
from utils.export_to_dict_helper import ExportToDictHelper
测试发现的完整输出如下所示:
2023-10-18 09:37:36.901 [info] Discovering unittest tests with arguments: /home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/unittestadapter/discovery.py,--udiscovery,-v,-s,./tests,-p,test_*.py
2023-10-18 09:37:36.901 [info] > ~/.pyenv/versions/3.8.16/bin/python ~/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/unittestadapter/discovery.py --udiscovery -v -s ./tests -p test_*.py
2023-10-18 09:37:36.901 [info] cwd: .
2023-10-18 09:37:37.218 [info] [
'/home/phip/.../poleno-event-model/tests',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/lib/python',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/unittestadapter',
'/home/phip/.../poleno-event-model',
'/home/phip/.pyenv/versions/3.8.16/lib/python38.zip',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/lib-dynload',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/site-packages',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/site-packages/CharPyLS-1.0.3-py3.8-linux-x86_64.egg',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/lib/python',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles',
'/home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/lib/python'
]
2023-10-18 09:37:37.498 [info] Test server connected to a client.
2023-10-18 09:37:37.571 [error] Unittest test discovery error
Failed to import test module: test_data_model_base
Traceback (most recent call last):
File "/home/phip/.pyenv/versions/3.8.16/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
module = self._get_module_from_name(name)
File "/home/phip/.pyenv/versions/3.8.16/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "/home/phip/.../poleno-event-model/tests/test_data_model_base.py", line 20, in <module>
from poleno_event_model.data_model_base import DataModelBase
File "/home/phip/.../poleno-event-model/poleno_event_model/__init__.py", line 18, in <module>
from .event_model_decl import event_model
File "/home/phip/.../poleno-event-model/poleno_event_model/event_model_decl.py", line 44, in <module>
from utils.export_to_dict_helper import AttributeFilter
ModuleNotFoundError: No module named 'utils.export_to_dict_helper'; 'utils' is not a package
Failed to import test module: test_poleno_event_model
Traceback (most recent call last):
File "/home/phip/.pyenv/versions/3.8.16/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
module = self._get_module_from_name(name)
File "/home/phip/.pyenv/versions/3.8.16/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "/home/phip/.../poleno-event-model/tests/test_poleno_event_model.py", line 26, in <module>
from poleno_event_model import BackgroundData, MeasurementEvent
File "/home/phip/.../poleno-event-model/poleno_event_model/__init__.py", line 18, in <module>
from .event_model_decl import event_model
File "/home/phip/.../poleno-event-model/poleno_event_model/event_model_decl.py", line 44, in <module>
from utils.export_to_dict_helper import AttributeFilter
ModuleNotFoundError: No module named 'utils.export_to_dict_helper'; 'utils' is not a package
为了进行比较,这是手动运行测试时的输出:
python3 -m unittest discover tests
[
'/home/phip/.../poleno-event-model/tests',
'/home/phip/.../poleno-event-model',
'/home/phip/.../poleno-event-model',
'/home/phip/.pyenv/versions/3.8.16/lib/python38.zip',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/lib-dynload',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/site-packages',
'/home/phip/.pyenv/versions/3.8.16/lib/python3.8/site-packages/CharPyLS-1.0.3-py3.8-linux-x86_64.egg'
]
................
----------------------------------------------------------------------
Ran 17 tests in 0.192s
OK
utils
目录位于项目的根目录(与tests
和大多数其他本地包目录处于同一级别),并包含一个__init__.py
文件。
如果重要的话,工具版本如下:
在写问题的时候,我大概就发现了问题所在。 VSCode 扩展文件夹
unittestadapter
在发现过程中放入 sys.path
以及工作区文件夹之前,如下所示:
ls -alh /home/phip/.vscode/extensions/ms-python.python-2023.19.12901009/pythonFiles/unittestadapter
total 44K
drwxrwxr-x 3 phip phip 4.0K Okt 17 16:18 .
drwxrwxr-x 8 phip phip 4.0K Okt 17 16:17 ..
-rw-rw-r-- 1 phip phip 4.6K Okt 17 16:17 discovery.py
-rw-rw-r-- 1 phip phip 11K Okt 17 16:17 execution.py
-rw-rw-r-- 1 phip phip 94 Okt 17 16:17 __init__.py
drwxrwxr-x 2 phip phip 4.0K Okt 17 16:25 __pycache__
-rw-rw-r-- 1 phip phip 7.9K Okt 17 16:17 utils.py
这个
utils.py
模块遮盖了我的项目本地 utils
包。
根据上述发现,问题归结为如何在运行 VSCode 单元测试发现时修复 sys.path 元素的顺序,以便工作区文件夹位于之前任何扩展目录?
第二个问题是为什么这种情况突然发生变化并且显然只影响我;至少我在网上搜索找不到类似的东西。如果这是最近 VSCode 版本的问题,我会认为网络上充斥着有关它的报告。
我仍然没有找到问题的解决方案,但进行了更多调查:显然,
unittestadapter
中的sys.path
目录根本不应该存在,因为其内部utils
模块以合格的方式使用( unittestadapter.utils
)。因此,只应添加 pythonFiles
路径,该路径位于列表中稍靠下的位置。
有趣的是,在创建新的最小项目(只是一个主模块、一个带有单个模块和一个测试文件的 utils 包)时,我无法重现该问题;在这种情况下,不会添加额外的
unittestadapter
。所以这可能不是VSCode安装的问题。但是,至少有两个包含 utils
模块的项目仍然存在该问题。并且它无法通过删除 __pycache__
目录或重命名项目文件夹(以使 VSCode 安装/配置文件中的任何缓存无效)来修复。
虽然我还没有找到问题的解决方案,但至少有一个解决方法:在 VSCode 中切换到使用 pytest 而不是 unittest 可以让测试被发现并运行得很好。
为此我所要做的就是从
.vscode/settings.json
中删除与单元测试相关的设置
"python.testing.unittestArgs": [
"-v",
"-s",
"./tests",
"-p",
"test*.py"
],
"python.testing.unittestEnabled": true,
然后重新加载窗口。这使得 VSCode 提供了测试配置,这次我选择了
pytest
。然后它添加了这些设置:
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
不需要对代码进行任何更改,因为 pytest 几乎与单元测试框架完全兼容,包括运行
asyncio
-使用 IsolatedAsyncioTestCase
进行测试。
不过,我仍然希望看到纯单元测试发现的根本问题的解决方案(或至少是一个解释)。