本文介绍了当 unittest 模块在脚本中时,sys.argv[1] 出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本可以执行各种操作并使用 sys.argv 访问参数,但是当脚本到达代码的单元测试部分时,它说没有用于此的模块.我拥有的脚本是:

I have a script that does various things and access paramenters using sys.argv but when the script gets to the unittest part of the code it says there is no module for this. The script that I have is:

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.我得到的错误是:

Say I enter ./script.py Hello in the command line. The error I get is:

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

如果我删除了 unittest 模块,它就可以工作.此外,如果我删除 testrunner 日志并将其保留在:

If I remove the unittest module it works. Also if I remove the testrunner log and leave it at:

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

这仍然不起作用.

谁能帮忙.

谢谢

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

I tried this hack but it still tries to read the sys.argv.

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

我只用 argv 尝试过这个,但读取额外的参数仍然很累.

I have tried this with just argv but it still tires to read the extra parameters.

推荐答案

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

The problem is that unittest.main() wants your precious argv for its own use! It uses either the argv you give it as a function parameter, or sys.argv if you don't give it argv explicitly, and tries to load tests named the arguments you give. In this case, this means it's looking for either a submodule called Hello, a TestCase class named Hello, a test case method within a test case class named Hello, or a callable object called Hello that returns a TestCase or TestSuite instance, all within your module 'script'.

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

There are several ways to fix this:

  • 绕过 unittest.main() 并自己调用较低级别的单元测试函数来设置和运行您想到的测试用例.
  • 消除您的代码对 sys.argv 的依赖,并利用 unittest.main() 行为对您有利.如果您的模块不打算独立运行除了作为单元测试,这可能是有道理的,因为您的模块的调用者可能不希望您从他们的 argv 中读取!
  • 将测试代码和主程序分离到一个单独的测试模块中.尽管从测试模块中,您仍然需要弄清楚如何将正确的 argv 放入您的代码中.
  • 指定argv=[sys.argv[0]] 作为unittest.main() 的参数;这应该可以防止它试图阅读你的.
  • Bypass unittest.main() and call lower-level unittest functions yourself to set up and run the test cases you have in mind.
  • Remove your code's dependency on sys.argv, and use the unittest.main() behavior to your advantage. If your module isn't meant to be run independently except as a unit test, this probably makes sense, since callers of your module may not be expecting you to read from their argv!
  • Separate the test code and main routine into a separate test module. You'd still have to figure out how to get the right argv into your code though from the test module.
  • Specify argv=[sys.argv[0]] as an argument to unittest.main(); that should keep it from trying to read yours.

这篇关于当 unittest 模块在脚本中时,sys.argv[1] 出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 18:02