使用鼻子进行测试的 Python 导入 - 导入当前包之上的模块的最佳实践是什么

发布于 2024-11-19 20:37:21 字数 963 浏览 2 评论 0原文

这是一个经常以不同形式被问到的问题,并且经常得到“哈哈,你做得不对”的回答。很确定这是因为人们(包括我)尝试使用一个常识性场景作为实现,并且解决方案并不明显(如果您以前没有这样做过)。

会接受“让飞出瓶子”的答案。

给定

project/
    __init__.py
    /code
        __init__.py
        sut.py
    /tests
        __init__.py
        test_sut.py

tests_sut.py开始的位置:

import code.sut

在根目录中运行nosetests会导致:

ImportError: No module named code.sut

走过的大道:

a)使用相对进行

from ..code import sut

b)将项目的根添加到PYTHONPATH

c)使用

sys.path.append

在开头的导入之前添加..路径每个测试模块。

d) 只需记住

setup.py 

在运行测试之前对项目进行操作以将模块安装到站点包中。


因此,要求是让测试位于可以访问项目的测试包根目录下。以上每一项对我来说都感觉不“自然”,已经证明是有问题的,或者看起来像是太辛苦了!

在 java 中,这是可行的,但基本上是通过构建工具/IDE 将所有类放在类路径上。也许问题是我期待 Python 的“魔力”?在 Flask webframework 测试中注意到,选项 d) 似乎是首选。

无论如何,下面推荐首选解决方案的陈述将消除我自己的“不自然”感觉。

This is a question which is asked frequently in different forms, and often obtains "lol you're not doing it properly" responses. Pretty sure that's because there's a common sense scenario people (including me) are trying to use as an implementation, and the solution is not obvious (if you've not done it before).

Would accept an answer which "lets the fly out of the bottle".

Given

project/
    __init__.py
    /code
        __init__.py
        sut.py
    /tests
        __init__.py
        test_sut.py

Where tests_sut.py starts:

import code.sut

Running nosetests in the root dir leads to:

ImportError: No module named code.sut

Avenues traveled:

a) do a relative using

from ..code import sut

b) add root of project to PYTHONPATH

c) use the

sys.path.append

to add the .. path before the imports at the start of each test module.

d) just remember to do a

setup.py 

on the project to install the modules into the site-packages before running tests.


So the requirement is to have tests located beneath the test package root which have access to the project. Each of the above don't feel "natural" to me, have proved problematic or seem like too much hard work!

In java this works, but basically by dint of your build tool / IDE placing all your classes on the classpath. Perhaps the issue is I'm expecting "magic" from Python? Have noted in the Flask webframework tests, option d) seems to be preferred.

In any case, statements below recommending a preferred solution would remove the feeling of "unnaturalness" in my own.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半夏半凉 2024-11-26 20:37:21

我遇到了同样的问题,并在相关问题中找到了适合我的答案

只需删除项目根目录中的 __init__.py 即可。

I had the same problem and found an answer in a related question work for me.

Just remove the __init__.py in the project root.

荒岛晴空 2024-11-26 20:37:21

你已经很好地回答了你的问题..
D(安装到系统位置)是可分发代码的首选。我通常使用 C(修改 sys.path),因为我不想在系统范围内安装数百个自定义库。理论上,A(相对导入)似乎更好,但也有失败的情况。
B (PYTHONPATH) 是正确的,在我看来,实际上仅用于测试目的。

这几乎概括了所有选项。您喜欢的选项(Python 神奇地知道去哪里查找)实际上并不是一个可行的解决方案,因为它可能会导致不可预测的结果,例如从不相关的项目中自动查找库。

在我看来,最好的办法是将其放在程序的入口点:

import sys, os
sys.path = [os.path.abspath(os.path.dirname(__file__))] + sys.path

You have answered your question pretty well already..
D (install to system location) is preferred for distributable code. I usually use C (modify sys.path) because I don't want system-wide installs of my hundreds of custom libs. In theory A (relative import) seems nicer, but there are cases where it fails.
B (PYTHONPATH) is right out, really only for testing purposes in my opinion.

That pretty much sums up all of the options. The option you prefer (Python magically knows where to look) is really not a workable solution because it can lead to unpredictable results, such as automagically finding libraries from unrelated projects.

In my opinion, the best thing to do is put this at the entry point(s) to your program:

import sys, os
sys.path = [os.path.abspath(os.path.dirname(__file__))] + sys.path
国际总奸 2024-11-26 20:37:21

我知道已经检查了答案,并且我仍然认为这是分享其他替代方案的充分理由:)

有一个 nose-pathmunge 为您提供在调用 nosestests 时设置 sys.path 的控件。

I know there is a answer checked and I still think it's a good reason to share other alternatives :)

There is a nose-pathmunge giving you a control to set sys.path while invoking nosestests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文