如果你正在编写一个库或应用程序,那么单元测试文件应该放在哪里?

将测试文件与主应用程序代码分开是很好的,但将它们放在应用程序根目录中的“tests”子目录中是很尴尬的,因为这会使导入将要测试的模块变得更加困难。

这里是否存在最佳实践?


当前回答

我更喜欢顶层测试目录。这确实意味着进口变得更加困难。对此,我有两个解决方案:

使用setuptools。然后你可以将test_suite='tests.runalltests.suite'传递给setup(),并可以简单地运行测试 在运行测试时设置PYTHONPATH: PYTHONPATH=。python测试/ runalltests.py

下面是M2Crypto中的代码是如何支持这些东西的:

http://svn.osafoundation.org/m2crypto/trunk/setup.py http://svn.osafoundation.org/m2crypto/trunk/tests/alltests.py

如果您更喜欢使用鼻子测试运行测试,则可能需要做一些不同的事情。

其他回答

我们使用

app/src/code.py
app/testing/code_test.py 
app/docs/..

在每个测试文件中,我们插入../src/ sys.path。这不是最好的解决办法,但很有效。我认为如果有人提出类似java中的maven之类的东西,给你提供标准的约定,无论你在做什么项目,都可以工作,那就太好了。

每隔一段时间,我发现自己检查了测试放置的主题,每次大多数人都建议在库代码旁边使用单独的文件夹结构,但我发现每次的论点都是一样的,而且没有那么令人信服。我最终把我的测试模块放在核心模块旁边的某个地方。

这样做的主要原因是:重构。

当我移动东西时,我确实希望测试模块与代码一起移动;如果测试位于单独的树中,则很容易丢失测试。说实话,迟早你会得到一个完全不同的文件夹结构,就像django, flask和其他的一样。如果你不在乎也没关系。

你应该问自己的主要问题是:

我在写:

A)可重复使用的库或 B)构建一个项目,而不是将一些半分离的模块捆绑在一起?

如果一个:

单独的文件夹和额外的维护其结构的工作可能更适合。没有人会抱怨将测试部署到生产环境中。

但是,当测试与核心文件夹混合在一起时,也很容易将它们排除在分发之外;把这个放到setup.py中:

find_packages("src", exclude=["*.tests", "*.tests.*", "tests.*", "tests"]) 

如果b:

您可能希望—正如我们每个人都希望—您正在编写可重用的库,但是大多数时候它们的生命与项目的生命紧密相连。能够轻松地维护您的项目应该是优先考虑的。

然后,如果你做得很好,你的模块很适合另一个项目,它可能会被复制到这个新项目中,而不是被分叉或被做成一个单独的库,并且与在一个单独的测试文件夹中搜索测试相比,在相同的文件夹结构中移动放在它旁边的测试很容易。(你可能会说,它一开始就不应该一团糟,但让我们现实一点)。

所以选择仍然是你的,但我认为混合测试可以实现与单独文件夹相同的功能,但在保持文件整洁方面花费的精力更少。

我们在编写为Python程序生成单元测试的Pythoscope (https://pypi.org/project/pythoscope/)时遇到了同样的问题。在我们选择目录之前,我们对python列表中的测试进行了民意调查,有很多不同的意见。最后,我们选择将“tests”目录放在与源代码相同的目录中。在该目录中,我们为父目录中的每个模块生成一个测试文件。

我不相信存在既定的“最佳实践”。

我把我的测试放在应用程序代码之外的另一个目录中。然后,我将主应用程序目录添加到sys。路径(允许您从任何地方导入模块)在我的测试运行脚本(它也做一些其他的事情)之前运行所有的测试。这样,当我发布主代码时,我就不必从主代码中删除测试目录,节省了我的时间和精力,即使时间和精力非常少。

When writing a package called "foo", I will put unit tests into a separate package "foo_test". Modules and subpackages will then have the same name as the SUT package module. E.g. tests for a module foo.x.y are found in foo_test.x.y. The __init__.py files of each testing package then contain an AllTests suite that includes all test suites of the package. setuptools provides a convenient way to specify the main testing package, so that after "python setup.py develop" you can just use "python setup.py test" or "python setup.py test -s foo_test.x.SomeTestSuite" to the just a specific suite.