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

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

这里是否存在最佳实践?


当前回答

我使用tests/目录,然后使用相对导入导入主要应用程序模块。在MyApp/tests/foo.py中,可能有:

from .. import foo

导入MyApp。foo模块。

其他回答

我使用tests/目录,然后使用相对导入导入主要应用程序模块。在MyApp/tests/foo.py中,可能有:

from .. import foo

导入MyApp。foo模块。

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

使用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

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

我最近开始用Python编程,所以我还没有机会找到最佳实践。 但是,我已经写了一个模块,它可以找到所有的测试并运行它们。

所以,我有:

app/
 appfile.py
test/
 appfileTest.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

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

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

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

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

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

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