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

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

这里是否存在最佳实践?


当前回答

如果测试很简单,就把它们放在文档字符串中——大多数Python测试框架都可以使用它:

>>> import module
>>> module.method('test')
'testresult'

对于其他更复杂的测试,我将它们放在../tests/test_module.py或tests/test_module.py中。

其他回答

我建议你在GitHub上查看一些主要的Python项目,并获得一些想法。

当你的代码变大,你添加了更多的库,最好在你有setup.py的同一个目录下创建一个测试文件夹,并为每种测试类型镜像你的项目目录结构(unittest, integration,…)

例如,如果你有一个这样的目录结构:

myPackage/
    myapp/
       moduleA/
          __init__.py
          module_A.py
       moduleB/
          __init__.py
          module_B.py
setup.py

添加测试文件夹后,您将拥有如下目录结构:

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

许多正确编写的Python包使用相同的结构。Boto包就是一个很好的例子。 检查https://github.com/boto/boto

我是怎么做的…

文件夹结构:

project/
    src/
        code.py
    tests/
    setup.py

Setup.py指向src/作为包含我的项目模块的位置,然后运行:

setup.py develop

它将我的项目添加到站点包中,指向我的工作副本。要运行测试,我使用:

setup.py tests

使用我配置的任何测试运行程序。

我将测试放在与测试代码(CUT)相同的目录中。在项目中,我可以用我的插件调整pytest,对于foo.py,我使用foo.pt进行测试,这使得编辑特定的模块及其测试非常容易:vi foo.*。

在不能这样做的地方,我使用foo_ut.py或类似的方法。你仍然可以使用vi foo*,尽管它也会捕获foobar.py和foobar_ut.py(如果它们存在的话)。

在这两种情况下,我调整测试发现过程来找到这些。

这将测试放在目录列表中代码的旁边,使测试明显地存在于那里,并使打开测试尽可能容易,当它们位于单独的文件中时。(对于从命令行开始的编辑器,如上所述;对于GUI系统,单击代码文件和相邻的(或非常接近相邻的)测试文件。

正如其他人所指出的,这也使得重构和提取代码以供在其他地方使用变得更容易。

I really dislike the idea of putting tests in a completely different directory tree; why make it harder than necessary for developers to open up the tests when they're opening the file with the CUT? It's not like the vast majority of developers are so keen on writing or tweaking tests that they'll ignore any barrier to doing that, instead of using the barrier as an excuse. (Quite the opposite, in my experience; even when you make it as easy as possible I know many developers who can't be bothered to write tests.)

根据我用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]

通过这种方式,当您使用rpm打包这些库时,您可以只打包主库模块(仅)。这有助于可维护性,特别是在敏捷环境中。

只有一个测试文件

如果只有1个测试文件,建议将其放在顶级目录中:

module/
    lib/
        __init__.py
        module.py
    test.py

在CLI下运行测试

python test.py

许多测试文件

如果有很多测试文件,将其放在tests文件夹中:

module/
    lib/
        __init__.py
        module.py
    tests/
        test_module.py
        test_module_function.py
# test_module.py

import unittest
from lib import module

class TestModule(unittest.TestCase):
    def test_module(self):
        pass

if __name__ == '__main__':
    unittest.main()

在CLI下运行测试

# In top-level /module/ folder
python -m tests.test_module
python -m tests.test_module_function

使用单元测试发现

单元测试发现将在包文件夹中找到所有测试。

在tests/文件夹中创建__init__.py

module/
    lib/
        __init__.py
        module.py
    tests/
        __init__.py
        test_module.py
        test_module_function.py

在CLI下运行测试

# In top-level /module/ folder

# -s, --start-directory (default current directory)
# -p, --pattern (default test*.py)

python -m unittest discover

参考

用于测试布局的pytest良好实践 unittest

单元测试框架

鼻子 nose2 pytest