Python 如何将黑盒测试与stdin/stdout结合使用

Python 如何将黑盒测试与stdin/stdout结合使用,python,testing,black-box,Python,Testing,Black Box,我喜欢TDD,所以我首先尝试编写我的黑盒测试 这是一个python程序,处理stdin并像这样输出到stdout(我尝试编写自己的语言,只处理stdin和stdout): 但我不能嘲笑标准和标准。我尝试在Python中使用子进程,但是Popen.stdout.read()挂起了一个EOF,需要终止程序。或者communicate(),但它会杀死我的程序,并且无法处理两个或多个输入 这让我心烦意乱了2天多,我找不到任何关于使用stdin/stdout进行模拟或黑盒测试的有用信息(我可以使用浏览器进

我喜欢TDD,所以我首先尝试编写我的
黑盒测试

这是一个python程序,处理
stdin
并像这样输出到
stdout
(我尝试编写自己的语言,只处理stdin和stdout):

但我不能嘲笑标准和标准。我尝试在Python中使用
子进程
,但是
Popen.stdout.read()
挂起了一个
EOF,需要终止程序。或者
communicate()
,但它会杀死我的程序,并且无法处理两个或多个输入

这让我心烦意乱了2天多,我找不到任何关于使用stdin/stdout进行模拟或黑盒测试的有用信息(我可以使用浏览器进行测试,但无法轻松使用stdin/stdout,这看起来很奇怪)

谢谢

*** First Editing ***
我创建了一个新的unittest类来处理我的类。它具有创建新Popen对象的功能

我尝试写入
stdin
并断言
stdout
。。。但是它挂起只是因为它找不到
EOF

我应该如何处理才能成功?谢谢你的帮助

类TestFunc(unittest.TestCase): def运行_小调(自): 返回Popen(['python3','./minor.py'], stdin=管道, stdout=管道, stderr=管道, text=True, ) def测试_打印(自): 道具=自我运行(小调) self.assertEqual(prop.stdout.read(),“>>”) 书写(“打印‘此’”) self.assertEqual(prop.stdout.read(),“…this\n>>”) 属性标准写入($quit) self.assertEqual(prop.stdout.read(),“”) 道具杀死
我创建了一个帮助器类来帮助。。。我不知道这是否是最好的主意,但它非常有效:

class MinorMock(对象):
"""
小调节目的模拟。
使用'input'和'assertOutput'方法设置所需的输入和输出。使用
`assertInputMeetOutput`检查unittest对象的输入是否满足其输出。
"""
定义初始(自我,测试对象):
self.popen=popen(['python3','minor.py'],stdin=PIPE,stdout=PIPE,stderr=PIPE,text=True)
self.input_text=“”
self.output_text=“”
self.err_text=“”
self.test_obj=test_obj
def输入(自身,文本):
self.input_text+=文本
回归自我
def assertOutput(自身,文本):
self.output_text+=文本
回归自我
def assertError(自身,文本):
self.err_text+=文本
回归自我
def断言InputMeetOutput(自):
(out,err)=self.popen.communication(self.input\u text)
self.test\u obj.assertEqual(输出,self.output\u文本)
self.test\u obj.assertEqual(错误,self.err\u文本)
self.popen.kill()

欢迎您提供其他答案…

我不确定我是否理解您所说的不能模拟stdin和stdout的意思--
sys.stdin
sys.stdout
都是类似文件的对象,您可以用其他类似文件的对象替换它们,这些对象的行为与您的测试要求一致。有些情况下,您需要实际重写FD 0和FD 1,但
os.dup2()
对这些情况的处理时间很短……那么,您能告诉我们您是如何尝试模拟stdin或stdout的,以及您在尝试时遇到的显式故障模式吗?@CharlesDuffy好的,我正在编辑……这是否回答了您的问题@埃夫根尼,不,是的。。。我想是因为你的评论,我不能用另一个函数来嘲笑它!只是因为我需要测试它,而不是嘲笑它。我想模拟的是
输入/输出
。顺便说一下,我在想,如果使用一个函数像字符串一样处理输入/输出对我来说是可以的。。。输入,然后将其转换为字符串并返回字符串,然后输出。。。或者用state构建一个类。
*** First Editing ***