我在不同的文件夹中有十几个测试用例。在根目录中有一个测试运行器。
unittest\
package1\
test1.py
test2.py
package2\
test3.py
test4.py
testrunner.py
目前,我手动将四个测试用例添加到测试套件中
import unittest
from package1.test1 import Test1
from package1.test2 import Test2
from package2.test3 import Test3
from package2.test4 import Test4
suite = unittest.TestSuite()
suite.addTests(unittest.makeSuite(Test1))
suite.addTests(unittest.makeSuite(Test2))
suite.addTests(unittest.makeSuite(Test3))
suite.addTests(unittest.makeSuite(Test4))
result = unittest.TextTestRunner(verbosity=2).run(suite)
if not result.wasSuccessful():
sys.exit(1)
如何让测试运行器自动测试所有测试用例?如:
for testCase in findTestCases():
suite.addTests(testCase)
答案 0 :(得分:10)
在我看来,您应该切换到unittest2或其他具有发现功能的测试框架。发现测试是运行它们的一种非常理智的方式。
最知名的是:
例如,使用nosetest足以从项目根目录运行nosetests
,它将发现并运行它找到的所有单元测试。很简单。
另请注意,unittest2将包含在python 2.7中(并且我估计会向后移植到2.4)。
答案 1 :(得分:8)
上面的模块很好但是NoseTests在尝试输入参数时会很有趣,这也很快,很适合另一个模块。
import os, unittest
class Tests():
def suite(self): #Function stores all the modules to be tested
modules_to_test = []
test_dir = os.listdir('.')
for test in test_dir:
if test.startswith('test') and test.endswith('.py'):
modules_to_test.append(test.rstrip('.py'))
alltests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
module.testvars = ["variables you want to pass through"]
alltests.addTest(unittest.findTestCases(module))
return alltests
if __name__ == '__main__':
MyTests = Tests()
unittest.main(defaultTest='MyTests.suite')
如果要将结果添加到日志文件,请在最后添加:
if __name__ == '__main__':
MyTests = Tests()
log_file = 'log_file.txt'
f = open(log_file, "w")
runner = unittest.TextTestRunner(f)
unittest.main(defaultTest='MyTests.suite', testRunner=runner)
同样在模块的底部,您正在测试这样的地方代码:
class SomeTestSuite(unittest.TestSuite):
# Tests to be tested by test suite
def makeRemoveAudioSource():
suite = unittest.TestSuite()
suite.AddTest(TestSomething("TestSomeClass"))
return suite
def suite():
return unittest.makeSuite(TestSomething)
if __name__ == '__main__':
unittest.main()
答案 2 :(得分:0)
我所做的是运行单独测试文件的包装脚本:
主要包装run_tests.py
:
#!/usr/bin/env python3
# Usage: ./run_tests.py -h http://example.com/ tests/**/*.py
import sys, unittest, argparse, inspect, logging
if __name__ == '__main__':
# Parse arguments.
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", help="increase output verbosity" )
parser.add_argument("-d", "--debug", action="store_true", dest="debug", help="show debug messages" )
parser.add_argument("-h", "--host", action="store", dest="host", help="Destination host" )
parser.add_argument('files', nargs='*')
args = parser.parse_args()
# Load files from the arguments.
for filename in args.files:
exec(open(filename).read())
# See: http://codereview.stackexchange.com/q/88655/15346
def make_suite(tc_class):
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(tc_class)
suite = unittest.TestSuite()
for name in testnames:
suite.addTest(tc_class(name, cargs=args))
return suite
# Add all tests.
alltests = unittest.TestSuite()
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj) and name.startswith("FooTest") and len(name) > len("FooTest"):
alltests.addTest(make_suite(obj))
# Run tests.
result = unittest.TextTestRunner(verbosity=2).run(alltests)
sys.exit(not result.wasSuccessful())
然后是另一个测试包装器:
class FooTest(unittest.TestCase):
def __init__(self, *args, cargs=None, **kwargs):
super().__init__(*args, **kwargs)
self.vdisplay = Xvfb(width=1280, height=720)
self.vdisplay.start()
self.args=cargs
self.log=logging
def setUp(self):
self.site = webdriver.Firefox()
def kill(self):
self.vdisplay.stop()
然后在单独的文件中的每个测试看起来像:
import sys, os, unittest
from FooTest import FooTest
class FooTest1(FooTest):
def test_homepage(self):
self.site.get(self.base_url + "/")
log.debug("Home page loaded.")
然后您可以轻松地从shell运行测试,如:
$ ./run_tests.py -h http://example.com/ test1.py test2.py
您可以使用通配符指定某些目录中的所有文件,或使用a new globbing option(**
)以递归方式运行所有测试(由shopt -s globstar
启用)。