问题描述
我有一个脚本可以执行各种操作并使用 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
的子模块,一个名为 Hello
的 TestCase
类,一个测试用例中的测试用例方法名为 Hello
的类,或名为 Hello
的可调用对象,返回 TestCase
或 TestSuite
实例,所有这些都在您的模块中'脚本'.
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 theunittest.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 tounittest.main()
; that should keep it from trying to read yours.
这篇关于当 unittest 模块在脚本中时,sys.argv[1] 出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!