我有一个从sys.stdin
读取的Python程序,所以我可以用./foo.py < bar.png
来调用它。如何在另一个Python模块中测试此代码?也就是说,如何在运行测试脚本时将stdin设置为指向文件的内容?我不想做像./test.py < test.png
这样的事情。我不认为我可以使用fileinput
,因为输入是二进制的,我只想处理一个文件。该文件是使用PIL中的Image.open(sys.stdin)
打开的。
答案 0 :(得分:3)
除了用作独立程序之外,您应该对脚本进行概括,以便可以从测试脚本调用它。这是一个执行此操作的示例脚本:
#! /usr/bin/python
import sys
def read_input_from(file):
print file.read(),
if __name__ == "__main__":
if len(sys.argv) > 1:
# filename supplied, so read input from that
filename = sys.argv[1]
file = open(filename)
else:
# no filename supplied, so read from stdin
file = sys.stdin
read_input_from(file)
如果使用文件名调用,则会显示该文件的内容。否则,将显示从stdin读取的输入。 (能够在命令行上传递文件名可能是对foo.py
脚本的有用改进。)
在测试脚本中,您现在可以使用文件调用foo.py
中的函数,例如:
#! /usr/bin/python
import foo
file = open("testfile", "rb")
foo.read_input_from(file)
答案 1 :(得分:2)
main
函数会选择sys.stdin
。StringIO
实例或测试文件。该计划:
# foo.py
import sys
from PIL import Image
def foo(stream):
im = Image.open(stream)
# ...
def main():
foo(sys.stdin)
if __name__ == "__main__":
main()
测试:
# test.py
import StringIO, unittest
import foo
class FooTest(unittest.TestCase):
def test_foo(self):
input_data = "...."
input_stream = StringIO.StringIO(input_data)
# can use a test file instead:
# input_stream = open("test_file", "rb")
result = foo.foo(input_stream)
# asserts on result
if __name__ == "__main__":
unittest.main()
答案 2 :(得分:1)
comp.lang.python post显示方式:替换sys.stdout的StringIO()对象,然后使用getvalue()
获取输出:
def setUp(self):
"""Set stdin and stdout."""
self.stdin_backup = sys.stdin
self.stdout_backup = sys.stdout
self.output_stream = StringIO()
sys.stdout = self.output_stream
self.output_file = None
def test_standard_file(self):
sys.stdin = open(EXAMPLE_PATH)
foo.main()
self.assertNotEqual(
self.output_stream.getvalue(),
'')
def tearDown(self):
"""Restore stdin and stdout."""
sys.stdin = self.stdin_backup
sys.stdout = self.stdout_backup
答案 3 :(得分:0)
你可以随时修补你的stdin
。但这是非常丑陋的方式。如理查德建议的那样,更好地概括你的脚本。
import sys
import StringIO
mockin = StringIO.StringIO()
mockin.write("foo")
mockin.flush()
mockin.seek(0)
setattr(sys, 'stdin', mockin)
def read_stdin():
f = sys.stdin
result = f.read()
f.close()
return result
print read_stdin()
此外,请勿忘记在拆除考试时恢复stdin
。