Gitlab CI中用pytest测试InquirerPy交互提示的自动传参方法
InquirerPy无交互单元测试实现方案
CI环境下做这类交互逻辑的单元测试,最稳定、兼容性最好的方式是直接mock交互输入的返回值,完全绕开真实的终端交互流程,不需要CI额外配置TTY,也不会出现卡住等待输入的问题。
核心原理
你代码里inquirer.filepath(...).execute()的返回值就是用户最终输入的路径,只要在测试执行时把这个execute方法的返回值替换成你预设的测试参数,就能跳过交互步骤,直接跑后续业务逻辑。可以直接用Python标准库自带的unittest.mock实现,不需要额外安装依赖。
具体实现步骤
- 首先补全原业务代码的缺失导入(原示例漏了必要模块导入,跑测试前先补上):
# 业务文件头部补全导入 import os import json from InquirerPy import inquirer # 假设dir_path是你业务里已经定义好的全局路径变量 dir_path = os.path.dirname(os.path.abspath(__file__))
- 编写pytest测试用例,用
patch替换交互提示的返回值,推荐搭配pytest自带的tmp_path夹具生成临时测试目录,避免污染本地文件、规避CI路径权限问题:
import json import os from unittest.mock import patch # 导入你自己写的业务函数,假设业务文件名叫config_util.py from config_util import set_path def test_set_path(tmp_path): # 预设测试用的配置路径 test_config_path = str(tmp_path / "test_config") test_dir_path = str(tmp_path) # 打补丁:替换业务代码里的inquirer交互、全局dir_path变量 # 注意patch的路径要写你业务代码里的对应变量位置,不要直接写InquirerPy的导入路径 with patch("config_util.inquirer.filepath") as mock_prompt, \ patch("config_util.dir_path", test_dir_path): # 配置mock:调用execute()时直接返回预设的测试路径 mock_prompt.return_value.execute.return_value = test_config_path # 执行被测函数,全程不会弹出交互提示 set_path() # 校验结果 # 1. 校验配置目录是否被正确创建 assert os.path.isdir(test_config_path) # 2. 校验path.json是否正确写入 json_file_path = os.path.join(test_dir_path, "path.json") assert os.path.exists(json_file_path) with open(json_file_path, "r", encoding="utf-8") as f: saved_config = json.load(f) assert saved_config["path"] == test_config_path
注意事项
- patch的目标路径必须对应你业务代码里的引用位置:比如你的
set_path写在config_util.py里,里面是from InquirerPy import inquirer,那patch路径就写config_util.inquirer.filepath,如果路径写错mock不会生效,测试还是会卡住等待输入。 - 不推荐用模拟终端输入(比如pexpect、pyte类库)的方案做单元测试:这类方案要求Gitlab CI作业配置
tty: true开启伪终端,不同CI环境兼容性差,而且单元测试本身就应该隔离外部交互依赖,mock是更符合单元测试规范的方案。 - 如果有多个连续的交互提示(比如先选路径、再选参数、再确认),只要给对应
execute方法按顺序配置返回值就行,比如mock_prompt.return_value.execute.side_effect = [test_path, "param1", True],就会按调用顺序依次返回预设值。
内容的提问来源于stack exchange,提问作者legendenomgeorg
相关产品推荐
相关产品推荐

