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

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

这里是否存在最佳实践?


当前回答

在c#中,我通常将测试分离到单独的程序集中。

在Python中——到目前为止——我倾向于编写doctests,其中测试位于函数的文档字符串中,或者将它们放在模块底部的if __name__ == "__main__"块中。

其他回答

我建议你在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

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

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

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

只有一个测试文件

如果只有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

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

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

我也倾向于把我的单元测试放在文件本身中,正如Jeremy Cantrell上面所指出的,尽管我倾向于不把测试函数放在主体中,而是把所有东西都放在一个文件中

if __name__ == '__main__':
   do tests...

块。这最终会将文档添加到文件中,作为如何使用您正在测试的python文件的“示例代码”。

我应该补充一点,我倾向于编写非常紧凑的模块/类。如果你的模块需要大量的测试,你可以把它们放在另一个测试中,但即使这样,我仍然会补充:

if __name__ == '__main__':
   import tests.thisModule
   tests.thisModule.runtests

这让任何阅读源代码的人都知道到哪里去寻找测试代码。