如何对依赖input()的Python函数进行多场景测试
如何对依赖
input()的Python函数进行多场景测试? 当然有办法!要测试这种依赖用户输入的函数,核心是替换掉原生的input()函数,让它返回我们预设的测试数据,而不是真的等待控制台输入。下面我会给出两种可行的方案,适配你想要的测试逻辑:
方案1:不修改原函数,用unittest.mock模拟输入
Python标准库的unittest.mock模块可以轻松替换全局的input(),让它按我们的预设返回值。先修正一下原函数的小问题(你的测试用例断言的是字符串,但原函数返回的是列表,需要把返回值转为字符串),然后编写测试:
from unittest.mock import patch def get_inputs(): str_from_user = input() list_of_marks = [] while str_from_user != "exit": list_of_marks.append('!') str_from_user = input() return ''.join(list_of_marks) # 转换为字符串,匹配你的测试用例 def test_get_inputs(): # 场景1:多次输入后退出 with patch('builtins.input', side_effect=["hey", "coco", "milo", "exit"]): assert get_inputs() == "!!!" # 场景2:直接输入exit with patch('builtins.input', side_effect=["exit"]): assert get_inputs() == "" # 场景3:单次输入后退出 with patch('builtins.input', side_effect=["horses have long faces", "exit"]): assert get_inputs() == "!"
原理说明
patch('builtins.input')会临时替换全局的input()函数;side_effect参数接受一个可迭代对象,每次调用input()时,会依次返回里面的元素;with语句保证测试结束后,input()会恢复成原生函数,不会影响其他代码。
方案2:修改原函数,增加测试友好性
如果你愿意对原函数做微小改动(完全不影响生产环境使用),可以给它加一个可选参数,默认使用原生input(),测试时传入自定义的输入生成器:
def get_inputs(input_func=input): str_from_user = input_func() list_of_marks = [] while str_from_user != "exit": list_of_marks.append('!') str_from_user = input_func() return ''.join(list_of_marks) def test_get_inputs(): # 定义一个生成mock输入的工具函数 def mock_input_generator(sequence): iter_sequence = iter(sequence) def inner(): return next(iter_sequence) return inner # 直接传入预设的输入序列即可测试 assert get_inputs(mock_input_generator(["hey", "coco", "milo", "exit"])) == "!!!" assert get_inputs(mock_input_generator(["exit"])) == "" assert get_inputs(mock_input_generator(["horses have long faces", "exit"])) == "!"
优势
这种方式不需要依赖mock库,代码更直观,而且原函数的扩展性更好——以后如果需要从其他来源获取输入(比如文件、API),只需要传入对应的输入函数即可。
内容的提问来源于stack exchange,提问作者firstgaurd
相关产品推荐
相关产品推荐

