2011-10-07 50 views
19

不幸的是,我发现在Python中保持单元测试的方法太多了,而且通常没有很好的文档记录。Python模块单元测试的最佳文件结构组织?

我正在寻找一个 “终极” 结构,一个将完成大部分的以下要求:

  • 通过测试框架可被发现,其中包括:
    • pytest
    • nosetests
    • tox
  • 测试应该是outside the module files和另一个目录中的模块本身(维护),可能位于包级别的tests/目录中。
  • 应该有可能只是执行测试文件(测试必须能够知道的是,应该测试模块)

请提供样品测试文件,做了假的测试,指定文件名和目录。

+0

你的问题是,真的吗?你为什么不使用其中的一个框架,让所有人都按照自己的意愿去做? – pvoosten

回答

17

这是我一直在使用方法:

目录结构

# All __init__.py files are empty in this example. 
app 
    package_a 
     __init__.py 
     module_a.py 
    package_b 
     __init__.py 
     module_b.py 
    test 
     __init__.py 
     test_app.py 
    __init__.py 
main.py 

main.py

# This is the application's front-end. 
# 
# The import will succeed if Python can find the `app` package, which 
# will occur if the parent directory of app/ is in sys.path, either 
# because the user is running the script from within that parect directory 
# or because the user has included the parent directory in the PYTHONPATH 
# environment variable. 

from app.package_a.module_a import aaa 
print aaa(123, 456) 

module_a.py

# We can import a sibling module like this. 
from app.package_b.module_b import bbb 
def aaa(s, t): 
    return '{0} {1}'.format(s, bbb(t)) 

# We can also run module_a.py directly, using Python's -m option, which 
# allows you to run a module like a script. 
# 
# python -m app.package_a.module_a 
if __name__ == '__main__': 
    print aaa(111, 222) 
    print bbb(333) 

module_b.py

def bbb(s): 
    return s + 1 

test_app.py

import unittest 

# From the point of view of testing code, our working modules 
# are siblings. Imports work accordingly, as seen in module_a. 
from app.package_a.module_a import aaa 
from app.package_a.module_a import bbb 

class TestApp(unittest.TestCase): 

    def test_aaa(self): 
     self.assertEqual(aaa(77, 88), '77 89') 

    def test_bbb(self): 
     self.assertEqual(bbb(99), 100) 

# Simiarly, we can run our test modules directly as scripts using the -m option, 
# or using nose. 
# 
# python -m app.test.test_app 
# nosetests app/test/test_app.py 

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

谢谢,例如,但我敢肯定,如果你将运行test_app.py它会抱怨,无法找到'应用程序'。认为测试必须在包被部署到Python包含路径之前通过。 – sorin

+0

@sorin不错,但您可以在我的答案结尾处提供的两个示例中获得非常接近的结果。 – FMc

+0

整个过程就是在没有任何参数的情况下调用测试框架。 – sorin