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

时间:2010-07-01 10:06:05

标签: python unit-testing testcase

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

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 个答案:

答案 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启用)。