如何创建运行unittest.main()的模块的快捷方式,然后允许Python解释器保持打开状态?

时间:2014-04-03 22:27:39

标签: python unit-testing command-line-arguments python-unittest

我正在开发一个使用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关键字参数那样),那么这不会是一个问题,但是没有。

答案是什么?每种选择似乎都不尽如人意。

0 个答案:

没有答案