如何正确使用py.test导入包?

7 投票
1 回答
1991 浏览
提问于 2025-04-18 00:21

我有以下的文件结构:

/spamalot
    /spam
        __init__.py
        spam.py
        /spam_on_eggs
            __init__.py
            spam_on_eggs.py
    /tests

        test_spam.py

这个“spam”恰好是一个 Flask 应用程序。

spam.py 文件里,我有:

import spam_on_eggs.spam_on_eggs as eggs
# Other Flask setup & application code here.

这个运行得很好——从 spamalot 目录我可以执行 python spam/spam.py

但是,当我开始加入测试的时候,情况就没那么顺利了。

在我的 test_spam.py 文件里,我有:

import spam.spam
test_client = spam.spam.app.test_client()

def test_it_fails():
     assert False

然而,它并没有在我预期的地方失败,而是在导入的那一行出错:

/spamalot/ $ py.test
# some output
E    ImportError

我可以通过在我的 /tests 文件夹里放一个 __init__.py 文件来解决这个问题,但这又让我遇到了另一个导入错误:

spam/spam.py:1: in <module>
>    import spam_on_eggs.spam_on_eggs as eggs
E    ImportError: No module named 'spam_on_eggs'

我可以通过把那一行改成:

from spam.spam_on_eggs import spam_on_eggs

这样我可以进行测试这又让我无法运行 $ python spam/spam.py——因为我会得到:

ImportError: no module named 'spam'

显然,我对模块导入是怎么工作的,以及 py.test 是如何在这个系统中运作的理解有些欠缺。

我遗漏了什么呢?

我描述的这种文件结构是否真的可行——能否在 spamalot 目录下同时运行 py.test 和我的服务器?

相关问题:

1 个回答

-1

py.test会始终使用包含__init__.py文件的最短目录路径。

如果你在spamalot文件夹里放一个__init__.py文件,那么你就可以导入spamalot.spam.spam这个模块。

参考链接:选择测试布局

撰写回答