Rea*_*nly 464 python unit-testing code-organization
如果您正在编写库或应用程序,那么单元测试文件会在哪里进行?
将测试文件与主应用程序代码分开是很好的,但将它们放入app根目录内的"tests"子目录中是很尴尬的,因为这会导致导入您将要测试的模块变得更加困难.
这里有最好的做法吗?
小智 189
对于文件module.py,通常应test_module.py按照Pythonic命名约定调用单元测试.
有几个普遍接受的地方test_module.py:
module.py.../tests/test_module.py(与代码目录相同的级别).tests/test_module.py(代码目录下的一级).我更喜欢#1,因为它很容易找到测试并导入它们.无论您使用什么构建系统,都可以轻松配置为以#开头运行文件test_.实际上,用于测试发现的默认unittest模式是test*.py.
Ste*_*ing 59
如果没有很多测试文件,将它放在顶级目录中是很好的(我认为这是一种pythonic(推荐)方式):
module/
lib/
__init__.py
module.py
test.py
Run Code Online (Sandbox Code Playgroud)
如果有许多测试文件,请将其放在一个tests文件夹中:
python test.py
Run Code Online (Sandbox Code Playgroud)
但是如果你把测试放在unittest discovery文件夹中,测试不能unittest discovery在CLI中因为__init__.py 无法导入相关模块,所以我们可以使用nose,或者我们可以将一个父目录添加到python导入路径,为此我将创建一个
module/
lib/
__init__.py
module.py
tests/
test_module.py
test_module_function.py
Run Code Online (Sandbox Code Playgroud)
在
# test_module.py
import unittest
from lib import module
class TestModule(unittest.TestCase):
def test_module(self):
pass
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
并tests/在测试导入模块之前
# In top-level /module/ folder
python -m tests.test_module
python -m tests.test_module_function
Run Code Online (Sandbox Code Playgroud)
Cri*_*ian 50
通常的做法是将tests目录放在与模块/包相同的父目录中.因此,如果您的模块被称为foo.py,您的目录布局将如下所示:
parent_dir/
foo.py
tests/
Run Code Online (Sandbox Code Playgroud)
当然没有一种方法可以做到这一点.您还可以创建一个tests子目录并使用绝对导入导入模块.
无论你在哪里进行测试,我都会建议你用鼻子来测试它们.Nose在您的目录中搜索测试.这样,您可以将测试放在组织最有意义的地方.
Pau*_*ndt 32
编写Pythoscope(http://pythoscope.org)时,我们遇到了同样的问题,它为Python程序生成单元测试.在我们选择目录之前,我们在python列表中对人们进行了测试,有很多不同的意见.最后,我们选择将"tests"目录放在与源代码相同的目录中.在该目录中,我们为父目录中的每个模块生成一个测试文件.
Tho*_*ews 27
我也倾向于将我的单元测试放在文件本身中,就像Jeremy Cantrell上面说的那样,虽然我倾向于不将测试功能放在主体中,而是将所有内容放入
if __name__ == '__main__':
do tests...
Run Code Online (Sandbox Code Playgroud)
块.这最终会将文档作为"示例代码"添加到文件中,以了解如何使用您正在测试的python文件.
我应该补充一下,我倾向于编写非常紧凑的模块/类.如果你的模块需要大量的测试,你可以将它们放在另一个中,但即便如此,我仍然会添加:
if __name__ == '__main__':
import tests.thisModule
tests.thisModule.runtests
Run Code Online (Sandbox Code Playgroud)
这使得任何阅读源代码的人都知道在哪里查找测试代码.
Jan*_*zny 17
每次在一段时间后,我发现自己检查了测试放置的话题,每一次多数建议库代码旁边有一个单独的文件夹结构,但我发现,每一个参数是相同的,时间不是那么令人信服.我最终将我的测试模块放在核心模块旁边.
这样做的主要原因是:重构.
当我移动东西时,我确实希望测试模块随代码一起移动; 如果它们位于单独的树中,则很容易丢失测试.老实说,迟早你会得到一个完全不同的文件夹结构,比如django,flask和许多其他文件夹.如果你不在乎,这很好.
你应该问自己的主要问题是:
我写的是:
如果一个:
一个单独的文件夹和维护其结构的额外努力可能更适合.没有人会抱怨您的测试部署到生产中.
但是,当它们与核心文件夹混合时,将测试排除在外也同样容易; 把它放在setup.py中:
find_packages("src", exclude=["*.tests", "*.tests.*", "tests.*", "tests"])
Run Code Online (Sandbox Code Playgroud)
如果b:
您可能希望 - 正如我们每个人所做的那样 - 您正在编写可重用的库,但大多数时候他们的生活与项目的生命紧密相关.能够轻松维护您的项目应该是一个优先事项.
然后,如果你的工作做得很好,你的模块是一个不错的选择另一个项目,它可能会被复制 - 不分叉或做成一个单独的库 - 这个新的项目,以及移动,在相同的文件夹结构旁边躺着测试与在一个单独的测试文件夹变成的混乱中进行钓鱼测试相比,这很容易.(你可能会说,首先它不应该是混乱,但让我们在这里是现实的).
所以选择仍然是你的,但我认为,通过混合测试,你可以实现与单独的文件夹相同的所有东西,但是更少的努力保持整洁.
Joh*_*kin 14
我使用一个tests/目录,然后使用相对导入导入主应用程序模块.所以在MyApp/tests/foo.py中,可能有:
from .. import foo
Run Code Online (Sandbox Code Playgroud)
导入MyApp.foo模块.
dwe*_*ook 12
我不相信有一个既定的"最佳实践".
我将测试放在应用程序代码之外的另一个目录中.然后我在运行所有测试之前将主app应用程序目录添加到sys.path(允许您从任何地方导入模块)中我的测试运行器脚本(还有其他一些东西).这样我就不必在发布时从主代码中删除测试目录,节省了我的时间和精力,如果这么少的话.
小智 11
根据我在Python中开发测试框架的经验,我建议将python单元测试放在一个单独的目录中.保持对称的目录结构.这将有助于仅包装核心库而不包装单元测试.下面通过原理图实现.
<Main Package>
/ \
/ \
lib tests
/ \
[module1.py, module2.py, [ut_module1.py, ut_module2.py,
module3.py module4.py, ut_module3.py, ut_module.py]
__init__.py]
Run Code Online (Sandbox Code Playgroud)
这样,当您使用rpm打包这些库时,您只需打包主库模块(仅限).这有助于维护,特别是在敏捷环境中.
Ara*_*ash 10
我建议你在GitHub上查看一些主要的Python项目并获得一些想法.
当您的代码变大并添加更多库时,最好在setup.py所在的同一目录中创建一个测试文件夹,并镜像每个测试类型的项目目录结构(unittest,integration,...)
例如,如果您有一个目录结构,如:
myPackage/
myapp/
moduleA/
__init__.py
module_A.py
moduleB/
__init__.py
module_B.py
setup.py
Run Code Online (Sandbox Code Playgroud)
添加测试文件夹后,您将拥有如下目录结构:
myPackage/
myapp/
moduleA/
__init__.py
module_A.py
moduleB/
__init__.py
module_B.py
test/
unit/
myapp/
moduleA/
module_A_test.py
moduleB/
module_B_test.py
integration/
myapp/
moduleA/
module_A_test.py
moduleB/
module_B_test.py
setup.py
Run Code Online (Sandbox Code Playgroud)
许多正确编写的Python包使用相同的结构.一个很好的例子是Boto包.检查https://github.com/boto/boto
我是怎么做的......
文件夹结构:
project/
src/
code.py
tests/
setup.py
Run Code Online (Sandbox Code Playgroud)
Setup.py指向src /作为包含我的项目模块的位置,然后运行:
setup.py develop
Run Code Online (Sandbox Code Playgroud)
这将我的项目添加到站点包中,指向我的工作副本.为了运行我的测试我使用:
setup.py tests
Run Code Online (Sandbox Code Playgroud)
使用我配置的测试运行器.
小智 5
我更喜欢顶级测试目录。这确实意味着进口变得更加困难。为此,我有两个解决方案:
test_suite='tests.runalltests.suite'进入setup(),并且可以简单地运行测试:python setup.py testPYTHONPATH=. python tests/runalltests.py以下是 M2Crypto 中的代码如何支持这些东西:
如果你更喜欢用鼻子测试运行测试,你可能需要做一些不同的事情。