Python, 单元测试 - 将命令行参数传递给unittest.TestCase的setUp

32 投票
4 回答
44112 浏览
提问于 2025-04-15 16:39

我有一个脚本,它是一些使用Python的 unittest 模块编写的单元测试的包装器。除了清理一些文件、创建输出流和生成一些代码之外,它还会使用

unittest.TestLoader().loadTestsFromTestCase()

把测试用例加载到一个测试套件中。

我已经在使用 optparse 来提取几个命令行参数,这些参数用于确定输出位置、是否重新生成代码以及是否进行一些清理。我还想传递一个配置变量,也就是一个端点URI,以便在测试用例中使用。

我意识到我可以在测试用例的 setUp 方法中添加一个 OptionParser,但是我想直接把这个选项传递给 setUp。这样做可以吗?我能否使用 loadTestsFromTestCase() 来实现?我可以遍历返回的 TestSuite 中的 TestCases,但我能手动调用 TestCases 的 setUp 吗?

** 编辑 **

我想指出的是,如果我遍历测试并手动调用 setUp,我可以将参数传递给 setUp,像这样:

(options, args) = op.parse_args()
suite = unittest.TestLoader().loadTestsFromTestCase(MyTests.TestSOAPFunctions)
for test in suite:
    test.setUp(options.soap_uri)

不过,我正在使用 xmlrunner,它的 run 方法需要一个 TestSuite 作为参数。我假设它会自己运行 setUp 方法,所以我需要在 XMLTestRunner 中能够访问这些参数。

4 个回答

4

我绝对不建议像这样给setUp传递参数;setUp是为了在运行测试时自动调用的,所以你不应该像这样显式地去调用它。

你可以考虑通过设置环境变量或者在一个全局可访问的“上下文”模块中设置你需要的值,这样测试用例就可以根据需要访问这些值。我建议使用环境变量,因为这样在运行测试时更灵活(你就不需要依赖命令行参数了)。

8

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或者库的时候。这些问题可能会让我们感到困惑,尤其是当我们刚开始学习编程的时候。比如,有些错误信息可能看起来很复杂,但其实它们只是告诉我们哪里出了问题。

当你在编写代码时,可能会发现有些地方不太对劲,这时候你可以去网上查找解决方案。StackOverflow是一个很好的地方,很多程序员会在这里分享他们遇到的问题和解决办法。

如果你看到一个代码块,比如

if __name__ == '__main__':
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-z", "--zebra",
                      action="store_true", dest="zebra", default=False,
                      help="run like a zebra")    


    (options, args) = parser.parse_args()

    if options.zebra:
        zebrafy()


    # remove our args because we don't want to send them to unittest
    for x in sum([h._long_opts+h._short_opts for h in parser.option_list],[]):
        if x in sys.argv:
            sys.argv.remove(x)


    unittest.main()
,那通常是一些示例代码或者错误信息。你可以根据这些信息来理解问题的所在,或者找到解决方案。

总之,遇到问题时不要害怕,去寻找答案,慢慢你就会变得更加熟练。

52

好吧,我也想做同样的事情,原本打算自己问这个问题。我想改进下面的代码,因为它有重复的部分。不过,它确实让我可以传入参数来测试 TestCase:

import unittest
import helpspot

class TestHelpSpot(unittest.TestCase):
    "A few simple tests for HelpSpot"

    def __init__(self, testname, path, user, pword):
        super(TestHelpSpot, self).__init__(testname)
        self.hs = helpspot.HelpSpot(path, user, pword)

    def test_version(self):
        a = self.hs.version()
        b = self.hs.private_version()
        self.assertEqual(a, b)

    def test_get_with_param(self):
        a = self.hs.filter_get(xFilter=1)

    def test_unknown_method(self):
        self.assertRaises(helpspot.HelpSpotError, self.hs.private_wuggienorple)

if __name__ == '__main__':
    import sys
    user = sys.argv[1]
    pword = sys.argv[2]
    path = sys.argv[3]

    test_loader = unittest.TestLoader()
    test_names = test_loader.getTestCaseNames(TestHelpSpot)

    suite = unittest.TestSuite()
    for test_name in test_names:
        suite.addTest(TestHelpSpot(test_name, path, user, pword))

    result = unittest.TextTestRunner().run(suite)
    sys.exit(not result.wasSuccessful())

撰写回答