当源文件具有依赖项时,pytest(或 unittest)不工作

pytest (or unittest) not working when a source file has a dependency

我不确定为什么这很难开始,但我是 Python 的新手,我正在尝试让任何单元测试框架进行 运行 测试,但是如果我测试一个具有依赖性的文件,我会得到“找不到模块”。我在 SO 上看到过类似的帖子,但其中 none 解决了我的问题。我在 Windows.

上使用 Python

项目结构是这样的:

some_project
---- my_app
     ---- my_app.py
     ---- my_lib.py
---- test
     ---- test_my_app.py

在 my_app.py 中,我有类似的东西:

 def say_hello(name: str) -> str:
         return f"Hello, {name}"

在测试_my_app.py中,我有:

from my_app.my_app import say_hello
def test_say_hello():
    assert say_hello("Bob") == "Hello, Bob"

然后当我 运行 pytest 时,一切正常,测试通过。但是,如果我通过包含 my_lib.py:

将依赖项添加到组合中

在my_lib.py中:

def concat(s1: str, s2: str) -> str:
    return f"{s1}, {s2}"

然后在 my_app.py:

from my_lib import concat
def say_hello(name: str) -> str:
    return concat("Hello", name)

当我 运行 pytest 时,出现错误“ModuleNotFoundError:没有名为 'my_lib'

的模块

怎么能找到my_app.py却找不到my_lib.py?它们在同一个包中。我在 pytest 文档和 python 文档中寻找解决方案,但没有太多相关内容。我试过编辑 sys.path,但没能成功。我将 init.py 文件放在 my_app 包和测试包中,但这并没有改变任何东西。有人对此有解决方案吗?为什么让单元测试在 Python 中工作如此困难?

这真的与 pytest 无关,更像是一个关于 python 导入的一般问题。在不了解更多信息的情况下很难回答您的问题,但我建议您重置路径并快速阅读有关 absolute/relative 导入的内容,看看答案是否显而易见。

但是,如果我不得不猜测,我会说这会解决您的问题。

from my_app.my_lib import concat

我自己一直 运行 关注这个问题。我得到的第一件事是没有找到 pytest。结果我需要在 Windows 中使用“运行 作为管理员...”来 运行 我的控制台。之后,最后一次重新安装“pip install pytest -U”(不确定是否需要,但我还是做了),pytest 开始工作了。

然后我在我的测试文件夹中添加了一个 __init__.py 文件。

some_project
---- my_app
     ---- my_app.py
     ---- my_lib.py
---- tests
     ---- __init__.py
     ---- conftest.py
     ---- setup_my_app.py
     ---- test_my_app.py
     ---- test_my_app.json

__init__.py 里面有这个:

# Allows us to reference other non test_...py and ..._test.py py files in our tests folder and from the parent folder. 
# Allows us to reference non .py files, like .json files
import sys
import os
    
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
    
sys.path.append(currentdir)
sys.path.append(parentdir)

然后我从“some_project”文件夹中运行 pytest。如果您尝试从“some_project/tests”文件夹中 运行 它,它将不起作用。您还可以从“some_project”的父文件夹中 运行 pytest。不确定是否需要 __init__.py 其他地方使用此解决方案。

此时,pytest 将从 some_project 的根目录导入 .py 文件(如果那里有 .py 文件以及子文件夹 .py 文件)。它还允许您引用非 test_...py/..._test.py 文件,例如常规 py、json 等文件。

例如,在 test_my_app.py 我可以有以下内容,然后 运行 pytest 来自 \some_project 路径:

import json
import pytest
import my_app
import setup_my_app


def test_something_super_important():
    with open("tests/test_my_app.json") as f:
        json_str = f.read()
    data = json.loads(json_str)
    assert 1+1 == 2