随着 AIGC 技术的飞速发展,越来越多的测试工程师希望借助大模型提升日常测试效率,例如辅助设计用例、答疑解惑、自动化生成测试建议等。LangChain 作为主流 LLM 应用开发框架,为多轮对话智能助手的研发提供了极大便利。本文不仅带你上手 LangChain 构建多轮对话测试机器人,还通过两个实际问答案例,深入展示其在测试用例设计场景下的实用价值和专业性。
pip install langchain-core langgraph>0.2.27
pip install -qU "langchain[openai]"
from langchain_core.messages import HumanMessage
import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_PROJECT"] = "pr-warmhearted-bassoon-71"
os.environ["LANGSMITH_API_KEY"] = "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"
os.environ["LANGSMITH_ENDPOINT"] = "https://api.smith.langchain.com"
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="deepseek-chat",
api_key="sk-e3f022d1746f415c9b0f4bc9a52a43xx", # todo 替换deepseek API Key https://platform.deepseek.com/api_keys
temperature=0.7,
max_tokens=512,
timeout=30,
max_retries=3,
base_url="https://api.deepseek.com"
)
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import START, MessagesState, StateGraph
# 定义一个graph
workflow = StateGraph(state_schema=MessagesState)
def call_model(state: MessagesState):
response = llm.invoke(state["messages"])
return {"messages": response}
workflow.add_edge(START, "model")
workflow.add_node("model", call_model)
# 记忆保存在内存中
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)
第一轮对话
config = {"configurable": {"thread_id": "test_case123"}}
query = "Hi, I`m Bob."
input_messages = [HumanMessage(query)]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
================================== Ai Message ==================================
Hi Bob! How can I help you today?
第二轮对话
query = "What`s my name?"
input_messages = [HumanMessage(query)]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
================================== Ai Message ==================================
Your name is **Bob**—you introduced yourself at the start! What’s up, Bob? Anything fun or interesting on your mind?
若更改config,则会开启一轮新的对话:
config = {"configurable": {"thread_id": "abc234"}} # config改变
input_messages = [HumanMessage(query)] # query不变
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
================================== Ai Message ==================================
I don’t have access to personal information about you unless you share it with me. If you’d like, you can tell me your name, and I’ll happily use it in our conversation!
当然可以!下面用通俗易懂的方式讲解一下 langgraph
关联对话的 config
原理,确保每一位测试工程师都能明白它的“道理”:
什么是 config?它有什么用?
在用 langgraph 做多轮对话时,你会发现每次和机器人聊天时,都需要传一个类似这样的参数:
config = {"configurable": {"thread_id": "test_case123"}}
你也许会疑惑:
thread_id
又是什么?打个比方:config 就像“对话房间号”
想象一下,你和几个同事在公司用微信群聊,每个群都有自己的聊天记录。你在“测试用例设计群”里聊过的话题,不会跑到“自动化脚本群”里去。同理:
为什么这样设计?
config 的用法举例
# 第一次和机器人聊“玻璃杯测试用例”
config1 = {"configurable": {"thread_id": "glass_case"}}
app.invoke({"messages": ...}, config1)
# 另一个同事聊“自动化脚本优化”
config2 = {"configurable": {"thread_id": "script_case"}}
app.invoke({"messages": ...}, config2)
# 你回到第一次的话题,只要 thread_id 一样,历史都还在
app.invoke({"messages": ...}, config1)
总结一句话
config 里的 thread_id,就是用来给“每一段独立对话”分配一个唯一编号。
只要 thread_id 一样,机器人就能记住你们之前聊过什么,真正实现多轮对话和上下文记忆。
这样一来,无论你是测试用例复盘、BUG 跟踪,还是知识问答,都能随时“断点续聊”,不会乱套!
希望这样你能一下子明白 langgraph 关联对话的 config 原理啦!
在实际面试和工作中,**“如何为玻璃杯设计测试用例”**是经典问题。让我们看看多轮对话机器人如何应答并帮助测试工程师形成结构化思路:
用户:
config = {"configurable": {"thread_id": "test_case123"}}
input_messages = [HumanMessage("测试工程师面试时,会被提问如何针对一个玻璃杯进行测试用例设计,帮我生成一个合理的回答?")]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
AI 聊天机器人答复:
================================== Ai Message ==================================
在面试中针对玻璃杯的测试用例设计问题,主要考察测试工程师的系统思维、场景覆盖能力和质量意识。以下是一个结构化的回答框架,既体现专业性又符合实际场景:
---
**回答示例:**
"我会从功能、性能、安全性、兼容性、用户体验和异常场景六个维度设计测试用例,同时考虑不同用户场景的需求:
**1. 功能测试**
- 基本功能:验证杯子能否正常盛装冷水/热水(不同容量)、液体是否泄漏
- 特殊功能:若为保温杯,测试保温时长是否符合标准(如100℃水6小时后≥68℃)
- 接口测试:杯盖与杯身的旋合密封性(可量化:旋转90°后倒置不漏水)
**2. 性能测试**
- 容量精度:标称300ml时,实测误差应≤±5%
- 耐温性:-20℃~120℃环境交替循环测试后无开裂
- 结构强度:1.5m高度自由落体到硬质地面的破损率(统计20次测试)
**3. 安全性测试**
- 材质检测:通过FDA认证的食品级材料验证
- 高温毒性:装入沸水后检测重金属析出量
- 边缘处理:杯口是否通过毛刺检测(如用丝绸摩擦测试)
**4. 兼容性测试**
- 液体兼容性:盛装酸性(柠檬汁)、碱性(苏打水)、油性液体的反应
- 设备兼容性:能否放入车载杯架/洗碗机等标准容器
**5. 用户体验测试**
- 人机工程:直径65mm的杯身是否适合亚洲人平均握距(70-90mm)
- 防滑设计:表面纹路在潮湿环境下的摩擦系数(≥0.4为合格)
- 视觉设计:印刷图案经过100次洗碗机循环后褪色率
**6. 异常场景测试**
- 极端填充:超过标称容量50%时的结构变形量
- 错误操作:空杯直接微波加热的后果
- 老化测试:UV加速老化500小时后材质黄变指数
**补充说明:**
- 会优先执行P0级用例(如盛装功能、基本安全性)
- 对保温杯等特殊类型会增加专项测试(如真空度检测)
- 建议建立标准测试环境(如23±2℃, RH50%)
---
**面试官考察点及应对技巧:**
1. **需求分析能力**:主动询问杯子类型(普通/保温/刻度杯)和用户群体(儿童/户外)
2. **测试思维完整性**:展示多维度覆盖(STAR法则:场景-方法-预期-结果)
3. **量化意识**:尽量给出可测量的标准(如"装100℃水"比"装热水"更专业)
4. **风险意识**:强调会优先测试高频使用场景和安全隐患
建议准备时结合具体案例,如:"在我之前的厨具测试项目中,就曾通过温度循环测试发现某玻璃杯在快速温差变化下存在5%的破裂率,推动供应商改进了退火工艺"
实际工作中,测试资源有限,常需优先级和用例精简。机器人支持多轮追问,自动根据历史上下文生成更合适的答复:
用户:
input_messages = [HumanMessage("如果测试工程师要求设计的精简一点,怎么实现")]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
AI 聊天机器人答复:
================================== Ai Message ==================================
如果面试官要求精简测试用例设计,可以聚焦**核心质量属性**和**高频使用场景**,用金字塔原则(先结论后细节)呈现。以下是精简版回答模板:
---
**精简回答(3层结构):**
"我会聚焦三个核心维度,用最少的用例覆盖最大风险:
**1. 基础功能(必测)**
- **盛装能力**:常温/100℃水装入标称容量,静置1小时无泄漏
- **结构完整性**:1m高度自由落体测试(硬质地面,3次重复)
- **使用安全**:杯口无锐边(用棉签擦拭检测)、盛热水时杯身温度≤50℃
**2. 关键异常场景**
- **过载测试**:装入120%容量液体后杯口变形量<2mm
- **冷热冲击**:5℃冰水立即倒入100℃沸水,观察是否开裂
**3. 核心用户体验**
- **握持舒适度**:杯身直径65-75mm(亚洲人手握舒适区间)
- **防滑验证**:湿手状态下倾斜45°保持5秒不滑落
**精简原则说明**:
- 优先覆盖《GB/T 11416-2002》日用玻璃杯基础标准要求
- 排除低频场景(如微波炉使用、极端酸碱液体)
- 用边界值法(最小/标称/最大)替代重复性测试"
---
**为什么这样精简?**
1. **满足80/20法则**:上述用例可发现80%以上的潜在缺陷
2. **体现测试策略**:
- 优先保障安全性和基本功能(P0级)
- 用边界值/最坏场景代替 exhaustive testing
3. **依然保持专业性**:
- 引用国标体现标准意识
- 量化标准(如"变形量<2mm")比定性描述更专业
**应对追问的技巧**:
如果面试官问"这样会漏测什么?",可以补充:
_"根据资源情况,第二步会补充材质安全性检测(如铅镉迁移量)和长期耐用性测试(如500次开合盖),但初步验证阶段会优先执行上述精简用例"_
这种回答既符合精简要求,又展示了你的优先级判断能力。
结语:
无论你是初入行的测试新人,还是资深测试架构师,借助 LangChain 多轮对话机器人,既能高效获得权威答案,也能持续优化自己的测试思维和表达能力。期待你把它用到更多测试场景,助力测试智能化升级!