我正在开发一个使用unittest进行测试的软件包。测试都在一个称为测试的子模块中。在子模块的底部是:
if __name__ == '__main__':
unittest.main()
但是如果你运行模块,Windows会关闭命令窗口,然后才能读取输出。好的,这不是一个新问题。有很多方法可以解决这个问题,例如制作一个类似于:
的快捷方式cmd /k "python -m mypackage.tests"
这有效,现在你可以看到输出了。但是然后您将被转发回C:\Windows\System32
命令提示符。能够仍然在Python解释器中会更好,所以我可以在Python中玩,如果我看到测试后发生了某些事情要检查。所以你尝试这样的事情:
cmd /k "python -i -m mypackage.tests"
但是,哇,这是什么?在测试输出之后,你会看到
Traceback (most recent call last):
File "C:\Python33\lib\runpy.py", line 160, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python33\lib\runpy.py", line 73, in _run_code
exec(code, run_globals)
File "D:\Docs\programs\python\mypackage\tests.py", line 274, in <module>
unittest.main()
File "C:\Python33\lib\unittest\main.py", line 125, in __init__
self.runTests()
File "C:\Python33\lib\unittest\main.py", line 267, in runTests
sys.exit(not self.result.wasSuccessful())
SystemExit: True
>>>
你仍然在Python解释器中,但由于某种原因,在测试结果和新提示之间存在几行哑音。没有人想看到这一点。这可能是因为unittest.main()
试图退出解释器,但解释器不会让它发生,因为你使用了-i
选项。这在某种程度上是好的,但不需要追溯。
你看看the documentation for unittest,看看是否有办法让Python在运行测试后坚持不懈。对于具有此效果的unittest,没有命令行开关,但是有一个关键字参数exit
可用于阻止unittest尝试关闭Python。所以我们可以将tests.py的结尾更改为:
if __name__ == '__main__':
unittest.main(exit = False)
问题在于,有时您可能需要关闭解释器的默认行为,例如,如果您的版本控制软件自动运行测试模块。所以最好有条件禁用退出的某种方式。好吧,似乎通过对命令行选项进行初步检查,可以做到这一点。所以我们尝试将其改为
if __name__ == '__main__':
import sys
unittest.main(exit = 'noexit' not in ''.join(sys.argv[1:]))
和
的快捷方式cmd /k "python -i -m mypackage.tests --noexit"
但是现在当你运行它时,测试甚至都没有运行,相反,你会看到一大堆关于如何没有“noexit”选项的抱怨:
Usage: tests.py [options]
tests.py: error: no such option: --noexit
Traceback (most recent call last):
File "C:\Python33\lib\optparse.py", line 1391, in parse_args
stop = self._process_args(largs, rargs, values)
File "C:\Python33\lib\optparse.py", line 1431, in _process_args
self._process_long_opt(rargs, values)
File "C:\Python33\lib\optparse.py", line 1484, in _process_long_opt
opt = self._match_long_opt(opt)
File "C:\Python33\lib\optparse.py", line 1469, in _match_long_opt
return _match_abbrev(opt, self._long_opt)
File "C:\Python33\lib\optparse.py", line 1674, in _match_abbrev
raise BadOptionError(s)
optparse.BadOptionError: no such option: --noexit
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python33\lib\runpy.py", line 160, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python33\lib\runpy.py", line 73, in _run_code
exec(code, run_globals)
File "D:\Docs\programs\python\mypackage\tests.py", line 275, in <module>
unittest.main(exit = 'noexit' not in ''.join(sys.argv[1:]))
File "C:\Python33\lib\unittest\main.py", line 124, in __init__
self.parseArgs(argv)
File "C:\Python33\lib\unittest\main.py", line 148, in parseArgs
options, args = parser.parse_args(argv[1:])
File "C:\Python33\lib\optparse.py", line 1393, in parse_args
self.error(str(err))
File "C:\Python33\lib\optparse.py", line 1573, in error
self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
File "C:\Python33\lib\optparse.py", line 1563, in exit
sys.exit(status)
SystemExit: 2
我认为我应该是决定命令行选项的人,但也许我没有通过正确的手续来声明我接受的命令行选项。但实际上,不,不是这样,因为如果我注释掉调用unittest.main()的行:
if __name__ == '__main__':
import sys
#unittest.main(exit = 'noexit' not in ''.join(sys.argv[1:]))
然后根本没有抱怨,只是>>>
提示!从中我只能推断unittest.main()
是出于某种原因检查我的脚本的命令行参数,并在它们不符合其标准时抛出一个合适的东西 - 尽管它们并非针对它首先。如果有一个命令行开关使其挂起而不是退出(如exit
关键字参数那样),那么这不会是一个问题,但是没有。
答案是什么?每种选择似乎都不尽如人意。