如何在Python中自动将大量测试用例添加到测试套件中

11

我有许多不同文件夹中的测试用例。在根目录下有一个测试运行器。

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)
3个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
11

在我看来,你应该转换使用unittest2或其他具有发现功能的测试框架。发现测试是一种真正明智的运行它们的方式。

最为知名的有:

例如,使用nosetest仅需从项目根目录运行nosetests,它将发现并运行所有找到的单元测试。非常简单。

还要注意,unittest2将包含在Python 2.7中(并且我想已经向后移植到2.4)。


unittest2库似乎是一个非常有趣的工具。感谢您提供的信息。 - stanleyxu2005

9

以上模块都很好,但是当尝试输入参数时,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()

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.")

然后你可以轻松地在命令行中运行测试,例如:

$ ./run_tests.py -h http://example.com/ test1.py test2.py

你可以使用通配符来指定某些目录中的所有文件,或者使用新的globbing选项**)递归运行所有测试(通过shopt -s globstar启用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,