【发布时间】:2016-05-18 18:20:15
【问题描述】:
我有一个具有以下存储库结构的 python 库:
repobase
|- mylibrary
| |- __init__.py
|- tests
|- test_mylibrary.py
到目前为止,只需在 repobase 目录中调用 py.test 即可运行测试。 test_mylibrary.py 中的 import mylibrary 然后使用 repobase/mylibrary 中的本地代码。
现在,我已扩展库以使用已编译的代码。因此,repobase/mylibrary 中的源代码本身不能正常工作。我必须做一个setup.py build。这将创建 repobase/build/lib.linux-x86_64-2.7/mylibrary。
有没有合理的方法让 py.test 使用这个目录来导入 mylibrary?鉴于这些限制:
我不想在 test_mylibrary.py 中包含任何
sys.path/ import 魔法,因为这可能会破坏其他环境中的测试。我不想放弃从 repobase 运行
py.test的可能性。因此修改 PYTHONPATH 没有帮助,因为.仍将是sys.path中的第一个。因此 repobase/mylibrary 会比 repobase/build/lib.linux-x86_64-2.7/mylibrary 更受青睐。
如果不是,测试需要构建的 python 库的标准方法是什么?
【问题讨论】:
-
不清楚您所说的“...我已经扩展库以使用编译代码...”是什么意思,即编译版本是否提供与 Python 版本相同的接口,或者确实Python 版本
import编译后的版本?如果是前者,那么您实际上是在测试两种不同的东西,所以即使测试套件相同,它们也应该有不同的名称,q.v. Python 的pickle与cPickle。如果是后者,那么它们肯定应该有不同的名称。一个常见的 Python 习惯用法是在编译部分前加下划线 q.v。 Python 的socket与_socket。 -
(续)无论哪种方式,让两个不同的模块实现共享相同的名称都是自找麻烦。即使您的解决方案适用于今天所有可能的运行时案例,您也无法预测所有可能的未来运行时案例,您最终可能会在没有意识到的情况下导入或测试错误的版本。
-
@Aya 我只有一个实现。编译后的代码替换一些以前的 python 代码。正如我所写的“因此,repobase/mylibrary 的源代码本身不能正常工作。”。我需要编译后的代码才能运行测试。
-
所以如果编译后的代码应该替换 Python 代码,那么你能不能不直接从存储库中删除 Python 代码?如果答案是“否”,因为它只替换了“部分”功能,那么它不是真正的替换,而是扩展。
-
python代码被淘汰。说,我有一个函数
do_something(args),它是用python实现的。现在,python 实现被对一些编译的 c 代码的内部调用所取代。do_something的 API 没有改变,我仍然想执行相同的测试。在测试之前,只需运行来自repobase/mylibrary的原始代码。更改后,这是不可能的,因为原始 python 代码本身不再起作用。相反,我必须先setup.py build,然后使用build子目录中的代码。问题是如何让 py.test 使用该代码。