11

我有一个脚本,它使用 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')

这仍然行不通。

任何人都可以帮忙。

谢谢

我尝试了这个 hack,但它仍然尝试读取sys.argv.

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

我已经尝试过了,argv但它仍然无法读取额外的参数。

4

4 回答 4

19

问题是unittest.main()想要您宝贵的 argv 供自己使用!它使用你给它的 argv 作为函数参数,或者sys.argv如果你没有明确地给它 argv,并尝试加载命名你给的参数的测试。在这种情况下,这意味着它正在寻找一个名为 的子模块Hello、一个名为 的TestCaseHello、一个名为 的测试用例类中的测试用例方法,或者一个称为返回或实例Hello的可调用对象,所有这些都在您的模块“脚本”中。HelloTestCaseTestSuite

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

  • 自己绕过unittest.main()并调用较低级别的单元测试函数来设置和运行您想到的测试用例。
  • 删除您的代码对 的依赖sys.argv,并利用该unittest.main()行为对您有利。如果您的模块不打算独立运行,除非作为单元测试,这可能是有道理的,因为您的模块的调用者可能不希望您从他们的 argv 中读取!
  • 将测试代码和主程序分离到一个单独的测试模块中。您仍然需要弄清楚如何从测试模块中将正确的 argv 放入您的代码中。
  • 指定argv=[sys.argv[0]]unittest.main(); 这应该可以防止它试图阅读你的。
于 2010-05-15T05:19:23.937 回答
9

如果你不需要 unittest 模块的命令行特性,你可以通过在调用之前修改 sys.argv 来让 optparse 和 unittest 模块一起玩得很好unittest.main()

unittest.main()在你打电话之前试试这个:

del sys.argv[1:]

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

如果你不使用 optparse 模块,你可以这样做:

my_args = sys.argv[1:]
del sys.argv[1:]
# do_stuff(my_args)
unittest.main()
于 2011-08-13T17:50:29.527 回答
1

一般来说,单元测试背后的想法是测试在没有外部驱动程序的情况下运行。例如,您不想依赖命令行的某些输入。您正在寻找的解决方案可能是通过使用夹具?

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()
于 2010-05-11T16:45:51.950 回答
-1

Python 为您提供了它所能提供的所有信息,除非您想发布您尝试测试的全部内容,否则我们只能猜测您要完成的工作。该错误表示没有名为“Hello”的属性,因此您尝试测试的模块可能应该获得这样的变量、函数或其他。

你有什么理由不只是使用unittest.main()

于 2010-05-11T16:13:32.917 回答