unittest模块位于scrip中时sys.argv[1]出现问题

2024-04-26 12:40:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个脚本,它可以使用sys.argv执行各种操作并访问参数,但是当脚本到达代码的unittest部分时,它会说没有这个模块。我的剧本是:

class MyScript():

    def __init__(self):
        self.value = sys.argv[1]

    def hello(self):
        print self.value

    def suite(self):
        modules_to_test = ('external_sanity_onvif', 'starttest')
        alltests = unittest.TestSuite()
        for module in map(__import__, modules_to_test):
            alltests.addTest(unittest.findTestCases(module))
        return alltests


if __name__ == '__main__': 
    Run = MyScript()
    Run.hello()
    log_file = 'log_file.txt'
    test_file = open(log_file, "w") 
    runner = unittest.TextTestRunner(test_file)
    unittest.main(defaultTest='Run.suite', testRunner=runner)

假设我在命令行中输入./script.py Hello。我得到的错误是:

AttributeError: 'module' object has no attribute 'Hello'

如果我移除unittest模块,它就会工作。另外,如果删除testrunner日志并将其保留在:

unittest.main(defaultTest='Run.suite')

这仍然不起作用。

有人能帮忙吗。

谢谢

我试过这个方法,但它仍然试图读取sys.argv

project = sys.argv[4:]
sys.argv = sys.argv[0:4]

我只尝试过argv但是它仍然会厌倦读取额外的参数。


Tags: runtestself脚本log参数maindef
3条回答

一般来说,单元测试背后的思想是测试运行时没有外部驱动程序。E、 你不想依赖命令行的一些输入。你要找的解决办法可能是使用固定装置?

import sys
import unittest

class MyScript(unittest.TestCase):
    def setUp(self):
        self.value = "Default Value"

    def setHello(self, value):
        self.value = value

    def hello(self):
        return self.value

class UserA(MyScript):
    def setUp(self):
        self.setHello("UserA")

    def testMyName(self):
        self.failUnlessEqual(self.hello(), "UserA")

class UserB(MyScript):
    def setUp(self):
        self.setHello("UserB")

    def testMyName(self):
        self.failUnlessEqual(self.hello(), "UserB")

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

问题是unittest.main()想要您宝贵的argv供自己使用!它要么使用您给它的argv作为函数参数,要么使用sys.argv如果您不显式地给它argv,并尝试加载名为您给的参数的测试。在本例中,这意味着它要查找名为Hello的子模块、名为HelloTestCase类、名为Hello的测试用例类中的测试用例方法,或返回TestCaseTestSuite实例的名为Hello的可调用对象,所有这些都在模块“脚本”中。

有几种方法可以解决此问题:

  • 绕过unittest.main(),自己调用较低级别的unittest函数来设置和运行您想要的测试用例。
  • 删除代码对sys.argv的依赖关系,并使用unittest.main()行为以获得优势。如果您的模块不是作为单元测试单独运行的,那么这可能是有意义的,因为您的模块的调用方可能不希望您从他们的argv中读取数据!
  • 将测试代码和主例程分离到一个单独的测试模块中。您仍然需要找出如何从测试模块中获得正确的argv到您的代码中。
  • 指定argv=[sys.argv[0]]作为unittest.main()的参数;这样可以防止它试图读取您的参数。

如果不需要unittest模块的命令行特性,可以在调用unittest.main()之前修改sys.argv,使optparse和unittest模块能够很好地协同工作

在您的unittest.main()呼叫之前尝试此操作:

del sys.argv[1:]

这将在unittest看到命令行参数之前删除它们。

如果不使用optparse模块,则可以执行以下操作:

my_args = sys.argv[1:]
del sys.argv[1:]
# do_stuff(my_args)
unittest.main()

相关问题 更多 >