我在Python中使用unittest编写了一些单元测试。但是,它们不是简单地以传统方式测试对象 - 而是通过使用Popen调用它来调用另一个Python脚本。这是设计 - 它是一个命令行实用程序,所以我想以用户的身份进行测试,其中包括命令行选项等内容。需要说明的是,单元测试和要测试的脚本都是用Python编写的(准确地说是v3)。
我正在测试的脚本大量使用datetime.now(),理想情况下我想以某种方式模拟该值,以便我可以保持它不变。不过我所看到的所有这些例子(例如this one使用mock)都假设某种形式的白盒测试。
我有办法做到这一点吗?
答案 0 :(得分:1)
在没有使用Popen
的情况下,没有什么可以阻止您测试CLI。您只需要构建代码以使其成为可能:
而不是这个:
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
# ... Add args
ns = parser.parse_args()
这样做:
import argparse
def main(argv):
parser = argparse.ArgumentParser()
# ... Add args
parser.parse_args(argv[1:]) # This is the default for argparse
ns = parser.parse_args()
if __name__ == "__main__":
import sys
main(sys.argv)
然后,您可以单独测试main
函数(只需使用您指定的一组args调用main([...])
)。请注意,对于其他CLI框架,这也应该起作用(对其进行一些调整)。
另请注意,如果您确实使用argparse
,则需要修补ArgumentParser()
,以便在解析失败时不会调用sys.exit
。
一种简单的方法是声明ParsingError
例外,并使用以下代码修补ArgumentParser.error(self, message)
:
def error(self, message):
raise ParsingError(message)
然后,您可以在测试中使用assertRaises
。