WeKnora自动化测试实践:基于Selenium的UI测试框架
1.

为什么需要为WeKnora构建UI自动化测试
WeKnora作为一款面向企业级知识管理的智能系统,界面功能丰富且交互逻辑复杂。
从文档上传、知识库配置到多轮对话问答,每个环节都直接影响用户对知识检索质量的体验。
当团队开始频繁迭代新功能——比如v0.2.0引入的ReACT
Agent模式、FAQ知识库类型或MCP工具集成时,手动回归测试很快就会成为瓶颈。
我经历过这样的场景:一次前端组件微调后,看似无关的“知识库创建”流程突然失败,排查发现是表单验证逻辑与后端API响应格式发生了隐性不兼容。
这种问题在WeKnora这类前后端分离、多服务协同的系统中尤为常见。
而Selenium恰好能模拟真实用户行为,覆盖从登录、上传PDF、配置Ollama模型到发起多轮问答的完整链路。
更重要的是,WeKnora的部署形态多样——飞牛NAS、本地Docker、私有云环境,不同环境下的浏览器兼容性、资源加载延迟、异步渲染表现各不相同。
一套可复用的Selenium测试脚本,能让我们在每次start_all.sh启动后快速验证核心路径是否依然健壮,把人力从重复点击中解放出来,专注在真正需要人工判断的语义准确性上。
2.UI基于Vue
3和TDesign构建,对现代浏览器特性依赖较强。
我们推荐使用Chrome
120+配合最新版ChromeDriver,避免因浏览器内核升级导致的定位失效。
安装过程简洁明了:
#安装Python依赖(建议使用虚拟环境)
pip
或使用webdriver-manager自动管理(推荐新手)
pip
webdriver-manager
关键点在于不要追求最新版Selenium。
当前WeKnora的DOM结构稳定,Selenium
4.15.0已足够可靠。
过新版本有时会因WebDriver协议变更引发意外行为,反而增加维护成本。
2.2
项目结构设计
一个清晰的目录结构能让测试代码像WeKnora源码一样易于维护。
我们摒弃了传统“页面对象模型”的过度抽象,采用更轻量的分层方式:
tests/├──
全局fixture:driver初始化、日志配置
├──
读取.env中的测试配置(如base_url、test_user)
└──
自定义等待:等待知识库状态变为"已完成"
└──
核心冒烟测试:登录→创建知识库→上传PDF→问答
这种结构的好处是:当WeKnora
UI发生局部调整(比如TDesign组件升级),你只需修改对应pages/下的定位器,业务测试用例完全不受影响。
2.3
配置驱动的灵活性
WeKnora支持多种部署模式(本地Docker、飞牛NAS、K8s),测试脚本必须能适配不同环境。
我们在config_loader.py中实现动态配置:
importfrom
os.getenv("TEST_BASE_URL",
FRONTEND_PORT
os.getenv("FRONTEND_PORT",
"80")
os.getenv("ADMIN_USER",
"admin@example.com")
ADMIN_PASS
os.getenv("ADMIN_PASS",
TIMEOUT
int(os.getenv("TEST_TIMEOUT",
"30"))
这样,测试执行时只需切换.env.test文件内容,就能无缝对接开发、测试、预发布环境,无需修改任何测试代码。
3.
知识库创建与配置验证
WeKnora的知识库创建是后续所有功能的基础,但实际部署中常因数据库初始化失败、PostgreSQL连接超时等问题导致页面卡在“创建中”。
我们的测试用例不仅验证UI按钮点击,更深入检查后台状态:
importpytest
test_create_knowledge_base(driver):
"""验证知识库创建流程及状态更新"""
page
步骤2:填写基本信息(避开动态ID,用标签文本定位)
page.enter_knowledge_name("自动化测试知识库")
page.select_knowledge_type("文档")
支持下拉选项
步骤3:提交并等待状态变更(关键!)
page.submit_form()
步骤4:等待后台处理完成(调用wait_utils)
assert
expected_status="已完成",
timeout=120
"知识库未在预期时间内完成初始化"
这里的关键创新点在于wait_for_knowledge_status函数。
它不依赖前端轮询,而是直接调用WeKnora的REST
API/api/v1/knowledge-bases获取知识库实时状态,确保测试反映的是真实系统健康度,而非UI渲染假象。
3.2
多模态文档上传与解析验证
WeKnora支持PDF、Word、Markdown甚至带OCR的图片,但不同格式的解析成功率差异很大。
我们设计了分层验证策略:
- 第一层:上传成功
/>检查文件选择框是否接受目标文件,上传进度条是否出现
- 第二层:解析状态
/>通过API确认
knowledge.status字段是否从"处理中"变为"已完成" - 第三层:内容可用性
/>发起一个简单问题(如"本文档包含几个章节?"),验证回答是否非空且含合理信息
deftest_upload_pdf_document(driver):
"""验证PDF上传及基础问答能力"""
page
上传测试PDF(使用绝对路径避免相对路径问题)
test_pdf
等待解析完成(重用之前的状态等待逻辑)
wait_for_knowledge_status(driver,
"自动化测试知识库",
chat_page.navigate_to_chat("自动化测试知识库")
chat_page.send_question("文档中提到的核心技术有哪些?")
验证回答非空且不含错误提示
f"回答过短:{answer[:50]}"
assert
f"回答含错误信息:{answer}"
这种三层验证让测试结果更具说服力——它不仅证明“按钮能点”,更证明“系统真能理解文档”。
3.3ReACT
Agent模式下的复杂任务流测试
v0.2.0新增的ReACT
Agent模式是WeKnora的重大升级,其测试不能停留在单次问答。
我们需要验证Agent能否自主拆解任务、调用工具、整合信息。
为此,我们设计了一个轻量级的“任务链”断言:
deftest_react_agent_workflow(driver):
chat_page
启用Agent模式(通过UI开关)
question
"对比WeKnora和RAGFlow在知识图谱支持上的差异"
chat_page.send_question(question)
检查Agent是否展示规划步骤(UI上可见的子任务列表)
planning_steps
f"规划步骤不足:{planning_steps}"
assert
验证最终输出为结构化报告(非零散句子)
final_report
f"报告未包含预期结构:{final_report[:100]}"
这个用例的价值在于:它把WeKnora最前沿的能力转化为可量化的测试指标,帮助团队在迭代中守住AI智能的底线。
4.
Docker化测试环境
为消除“在我机器上能跑”的陷阱,我们将Selenium测试容器化。
关键不是运行浏览器,而是复现WeKnora的真实依赖环境:
#Dockerfile.test
https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
&&
./google-chrome-stable_current_amd64.deb
&&
google-chrome-stable_current_amd64.deb
复制测试代码和依赖
运行测试(需链接WeKnora网络)
CMD
"--html=report.html",
"--self-contained-html"]
CI流水线中,我们先docker
compose
-d启动WeKnora全栈,再docker
run
test-image执行测试。
这种网络直连比host.docker.internal更稳定,避免DNS解析失败。
4.2
失败诊断与日志增强
Selenium测试失败时,截图和页面源码是黄金线索。
但我们更进一步,在conftest.py中注入WeKnora特有的诊断信息:
@pytest.hookimpl(tryfirst=True,def
pytest_runtest_makereport(item,
call):
item.funcargs.get("driver")
driver:
driver.save_screenshot(f"screenshots/{item.name}_fail.png")
try:
driver.execute_script("""
return
fetch('/health').***n(r
=>
open(f"logs/{item.name}_health.json",
"w")
driver.get_log("browser")
with
open(f"logs/{item.name}_console.log",
"w")
f.write(f"{log['level']}:
{log['message']}\n")
当测试失败时,工程师拿到的不仅是截图,还有WeKnora的健康状态、前端报错详情,极大缩短根因分析时间。
4.3
测试数据管理策略
WeKnora的测试数据需兼顾隔离性与真实性:
- 隔离性:每个测试用例创建唯一命名的知识库(如
test_kbase_20241205_1423),执行后自动清理 - 真实性:使用真实业务文档片段(脱敏后的PDF样例、技术白皮书节选),而非Lorem
Ipsum
我们在conftest.py中实现自动清理钩子:
@pytest.fixturedef
"""生成唯一知识库名,并在测试后自动删除"""
name
f"test_kbase_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
yield
测试结束后清理(即使测试失败也执行)
try:
print(f"清理知识库{name}时出错:{e}")
这种策略让测试既干净又贴近生产,避免数据污染导致的偶发失败。
5.
WeKnora特有的稳定性挑战
在真实项目中,我们遇到过三类典型问题,解决方案已被验证有效:
问题1:异步加载导致的元素定位失败
/>WeKnora大量使用Vue的异步组件和懒加载,find_element常因元素尚未渲染而抛异常。
/>解法:放弃time.sleep(),改用显式等待+自定义条件:
fromimport
wait.until_not(EC.presence_of_element_located(("css
selector",
".t-loading")))
问题2:gRPC服务延迟影响测试节奏
/>文档解析服务docreader的gRPC调用可能耗时数秒,若测试过早检查状态会误判。
/>解法:在测试前主动触发一次“热身”解析:
#@pytest.fixture(scope="session",
autouse=True)
"""在所有测试前,用小文件触发docreader服务就绪"""
调用一次轻量级解析API
requests.post("http://localhost:50051/parse",
"test"})
问题3:Docker环境下Chrome渲染异常
/>在CI服务器上,无头Chrome常因缺少字体或GPU支持导致PDF预览乱码。
/>解法:在Chrome选项中添加稳定参数:
chrome_options=
chrome_options.add_argument("--headless=new")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
关键:强制软件渲染
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--font-render-hinting=none")
5.2
何时该写自动化测试,何时该手动
并非所有WeKnora功能都适合Selenium覆盖。
我们的决策树很务实:
- 必测:核心用户旅程(登录→创建知识库→上传文档→首次问答)、高频操作(知识库配置保存、多轮对话上下文保持)、易出错集成点(Ollama模型切换、Embedding维度配置)
- 慎测:UI样式细节(按钮颜色、间距)、低频边缘场景(上传200MB扫描版PDF)、纯前端动画效果
- 不测:LLM回答质量(需人工评估语义合理性)、向量检索精度(应由单元测试覆盖算法)
记住:自动化测试的目标是守护交付节奏,不是替代人工探索。
我们每周仍保留30分钟手动探索测试,专门寻找那些脚本永远无法发现的体验裂缝。
/>
获取更多AI镜像
想探索更多AI镜像和应用场景?访问
CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。


