我有一个Python脚本,它接受一个输入(一个文本文件):./myprog.py file.txt。脚本根据给定的输入输出一个字符串。
我有一套测试文件,我想用它来测试我的程序。我知道每个文件的预期输出,并希望确保我的脚本为每个文件生成正确的输出。
,做这种测试的普遍接受的方法是什么?
我考虑使用Python的unittest模块作为测试框架,然后通过subprocess.check_output(stderr=subprocess.STDOUT)运行我的脚本,捕获stdout和stderr,然后执行unittest assertEqual来比较实际字符串和预期字符串。我想确保我不会错过更好的解决方案。
发布于 2017-01-23 02:59:34
这里有两个问题。测试程序,而不是函数库,测试打印的东西,而不是函数返回的值。两者都使测试变得更加困难,所以最好尽可能地解决这些问题。
通常的技术是创建一个函数库,然后让您的程序成为一个瘦包装器。这些函数返回它们的结果,只有程序才进行打印。这意味着您可以对大多数代码使用正常的单元测试技术。
您可以有一个文件,它既是一个库,也是一个程序。下面是一个简单的例子,如hello.py。
def hello(greeting, place):
return greeting + ", " + place + "!"
def main():
print(hello("Hello", "World"))
if __name__ == '__main__':
main()最后一点是文件是作为程序运行,还是作为库导入。它允许使用import hello访问各个函数,还允许文件作为程序运行。See this answer for more information。
然后,您可以编写一个基本正常的单元测试。
import hello
import unittest
import sys
from StringIO import StringIO
import subprocess
class TestHello(unittest.TestCase):
def test_hello(self):
self.assertEqual(
hello.hello("foo", "bar"),
"foo, bar!"
)
def test_main(self):
saved_stdout = sys.stdout
try:
out = StringIO()
sys.stdout = out
hello.main()
output = out.getvalue()
self.assertEqual(output, "Hello, World!\n")
finally:
sys.stdout = saved_stdout
def test_as_program(self):
self.assertEqual(
subprocess.check_output(["python", "hello.py"]),
"Hello, World!\n"
)
if __name__ == '__main__':
unittest.main()这里,test_hello是作为一个函数直接对hello进行单元测试;在一个更复杂的程序中,需要测试更多的函数。我们还使用test_main对main进行单元测试,使用StringIO捕获其输出。最后,我们确保该程序将作为一个程序运行与test_as_program。
重要的是尽可能多地测试函数返回数据的功能,尽可能少地测试打印和格式化的字符串,并且通过运行程序本身几乎什么都不做。当我们实际测试程序时,我们所需要做的就是检查它是否调用了main。
https://stackoverflow.com/questions/41797606
复制相似问题