在sitepackage中安装Python单元测试有意义吗?

2024-06-17 19:03:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发我的第一个Python发行包。我的学习曲线 Python的打包似乎有点稳定,但我仍然在努力 一些开放性问题。一个是我是否应该让我的单元测试 安装在我的代码旁边。在

我明白it's important to include tests in a source distribution。我想知道的是我是否真的应该配置它们来安装?在

我见过至少有一个流行的软件包是故意这么做的 (PyHamcrest),以及至少一个看起来是偶然的 (behave)。在

所以我的问题是:

  • 把我的包单元测试和我的 包装代码?

  • 如果是,那么用例是什么?谁会用它们做什么?那是谁 会使用那些不太乐意下载源代码的程序 分发并运行python setup.py test

  • 他们将如何使用已安装的单元测试?像import test; test.run()之类的 像那样?


Tags: to代码intestsourceincludetestsit
3条回答

在我看来,正确的答案是否定的,但是你会发现很多安装测试的发行版。不应该安装测试,但它们应该包含在源代码分发中。在我看来,在理想情况下,测试已安装的包应该是由包管理器(pip)执行的任务,site-packages目录不应该被测试源污染。在

我最近研究了这个主题,收集了来自不同来源的信息,发现了几种不同的方法来构建包含库源和测试的发行版的目录/包层次结构。这些结构中的大多数似乎已经过时了,它们的发明是为了解决当时旧的配电系统的不完整特性集。不幸的是,很多在线资源(旧的博客文章/文档)仍然在宣传过时的方法,因此很容易通过在线搜索找到过时的发布指南/教程。在

假设您有一个名为“my_lib”的库,并且希望构建您的发行版的源代码。我将展示两种流行的、似乎过时的方法来构建您的发行版,第三种方法是我发现最通用的。第三种方法可能也过时了,但这是我所知道的最好的一种,即发布此答案的时间。;—)

方法1

(有意或无意)安装测试的发行版通常使用这种方法。在

层次结构

+- my_lib
|  +- __init__.py
|  +- source1.py
|  +- source2.py
|  +- tests
|     +- __init__.py
|     +- test_1.py
|     +- test_2.py
+- setup.py

方法2

未安装测试,但它们应该通过MANIFEST.in文件包含在源分发中。在

层次结构

^{pr2}$

方法3(我更喜欢这个)

这与方法2非常相似,只是有点扭曲(即srcdir)。在

层次结构

+- src
|  +- my_lib
|     +- __init__.py
|     +- source1.py
|     +- source2.py
+- tests
|  +- __init__.py
|  +- test_1.py
|  +- test_2.py
+- setup.py

setup()调用设置.py

from setuptools import setup, find_packages

setup(
    ...
    packages=find_packages('src'),
    package_dir={'': 'src'},
    ...
)

清单.in

recursive-include tests *.py

不会安装测试,但它们将通过我们的MANIFEST.in包含在源代码分发中。在

对于方法3,您有一个src目录,该目录通常只包含作为lib根目录的单个包。将my_lib包放入src目录(目录而不是包,因此您不需要src/__init__.py)有以下好处:

  • 执行setup.py时,包含setup.py的目录将隐式添加到python路径中。这意味着在setup.py中,如果库的包与setup.py位于同一目录中,则可能会意外地错误地从库中导入内容。通过将my_lib包放入src中,我们可以避免这个问题。在
  • 您可以轻松地使用分布式测试源来测试分布式库源和已安装的库:

    • 当您使用setup.py test运行测试时,setup()调用的package_dir={'': 'src'}部分保证您的测试将看到您保存在src/my_lib中的my_lib库包。在
    • 也可以不使用setup.py运行测试。在最简单的情况下,您可以使用python -m unittest命令来完成此操作。在本例中,srcdir不会是python路径的一部分,因此您可以使用此方法来测试库的已安装版本,而不是src中的源代码。在

但是我不是专家,我想分享我的观点。在

如果我认为某些东西可能会因外部原因而失败,我总是把测试放在代码旁边。无论是位顺序,奇怪的时区,字符编码,24位整数或任何其他奇怪的东西,你可以遇到和测试。在

谁会不乐意下载源代码并运行测试? 可能一些debian用户的包被从源代码中剥离出来(我知道您在谈论python,但让我稍微概括一下),您的库偶尔会因为系统中的一些奇怪的事情而失败。在

如果您的测试只确保内部的健全性,我将跳过附加它们,因为没有源代码,它们就没有多大价值,因为您永远不会更改库的内部结构。在

就我个人而言,我听说过一件事失败了,因为它被移到了某台IBM机器上,而这台机器有不同的位顺序。我不记得它是依赖于位操作还是预先计算并静态缓存的。但有时检查一下是否加载了您认为保存的内容是明智的。在

编辑: 也许重新措辞会更好。我会在您觉得可能存在可移植性警告时安装测试。我认为在不同的系统上部署东西时检查一下总是很好的。在

在研究了这个问题之后,直到更有经验的人有一分钟时间来权衡,我的理解是简单的答案是:“不,不应安装单元测试,只应包括在源代码分布中”。在

在我发现的安装了测试的少数几个案例中,结果都是意外的,而且在没有注意到的情况下犯错误比人们想象的要容易。在

事情是这样发生的:

  1. packages=find_packages()参数用于设置.py这样就可以在不必显式列出包的情况下找到它们。在
  2. test文件夹被制成一个包(通过添加__init__.py),这样测试可以引用它们使用相对命名(如from .. import pkg.mod)测试的模块。在
  3. setuptools将{}作为一个单独的包安装,与项目中的其他包一起安装。注意这意味着您可以在python解释器中执行import test,而且它可以正常工作,几乎肯定不是您想要的,特别是因为许多其他人使用这个名称作为他们的测试目录:)

修复方法是使用设置:packages=find_packages(exclude=['test'])阻止安装测试目录。在

相关问题 更多 >