开源三合一自动化测试平台:Docker一键部署,统一Web、API、App测试

开源三合一自动化测试平台:Docker一键部署,统一Web、API、App测试
1. 项目概述一个全栈测试工程师的“瑞士军刀”干了十多年测试从手工点点点到脚本满天飞再到搞平台、带团队我最大的感受就是测试工具链太碎了。UI自动化用一套框架接口测试用另一套工具移动端App测试又是完全不同的生态。团队里新人上手成本高老手维护多套环境也头疼更别提测试报告分散、数据难以统一分析了。所以我一直想搞一个“大一统”的玩意儿能把UI、接口、App这三块最核心的自动化测试给揉到一起让部署和上手变得跟搭积木一样简单。这就是我开源这个自动化测试平台的初衷。你可以把它理解为一个测试领域的“瑞士军刀”核心目标就一个用一套平台解决Web UI、API接口、移动端AppAndroid/iOS三大主流自动化测试需求并且通过Docker实现真正意义上的“一键部署”。它不是为了替代那些顶级的、功能极其专精的商业工具而是为中小团队、个人开发者、或者想快速搭建内部测试能力的企业提供一个开箱即用、五脏俱全、且能自主掌控的解决方案。如果你正被Selenium、Postman、Appium、Jenkins等各种工具和它们的集成问题搞得焦头烂额那这个平台可能就是你要找的“降压药”。2. 平台核心架构与设计思路拆解2.1 为什么是“三合一”架构市面上优秀的单一领域测试工具很多比如做UI自动化的Selenium/Playwright做接口测试的Postman/Apifox做移动端测试的Appium。但问题在于一个完整的业务测试流程往往是跨端的一个电商下单流程可能涉及H5页面UI、调用支付接口API、在App内查看订单移动端。如果三个环节用三套独立的工具脚本语言可能不同Python/Java/JavaScript报告格式各异调度依赖需要额外集成比如用Jenkins串起来维护成本和复杂度呈指数级上升。我的设计思路是“平台化整合标准化输出”。平台本身不重复造轮子而是作为调度中枢和标准制定者去集成和封装这些领域内最成熟的开源引擎。UI测试层基于Selenium/Playwright封装。为什么选它们生态成熟、社区活跃、浏览器支持好。平台提供一套更上层的、面向业务的Page Object模式封装让测试脚本编写者不用太关心底层Driver的初始化、等待策略等繁琐细节更专注于业务逻辑和元素定位。同时平台统一管理浏览器驱动解决版本兼容性这个经典痛点。接口测试层核心引擎是HTTP客户端库如Requests但关键在于提供了比Postman更利于持续集成CI的协作模式。平台将接口用例、环境变量、前置/后置脚本如数据库操作、加解密、断言规则全部结构化存储支持从Swagger/OpenAPI直接导入并生成清晰的数据驱动测试用例。它解决了Postman用例难以版本化、团队共享协作不便的问题。App测试层坚定地站在Appium的肩膀上。Appium的“一次编写多端运行”Android/iOS理念与我们的平台目标高度一致。平台主要解决的是Appium环境搭建复杂的问题通过Docker镜像预置所有依赖Android SDK、模拟器、Appium Server等并提供统一的设备管理、应用安装卸载、Capabilities配置界面。平台的核心价值就在于用一个统一的Web界面来管理这三类测试资产用例、脚本、数据用一个统一的调度引擎来触发和执行它们最后用一个统一的报告系统来展示结果。技术栈上后端选用Python/Go这类生态好的语言前端用Vue/React数据库用MySQL/PostgreSQL消息队列用Redis/RabbitMQ处理异步任务所有组件最终通过Docker Compose编排。2.2 Docker化部署从“地狱”到“一键”的关键抉择“支持Docker一键部署”不是一句轻飘飘的口号而是这个平台能否真正被用起来的关键。传统测试环境搭建尤其是带UI和移动端模拟器的堪称“环境配置地狱”。不同操作系统、不同浏览器版本、不同JDK/Node.js/Python版本、不同Android SDK Build-Tools……任何一个环节出问题都足以让人崩溃半天。Docker化彻底解决了这个问题。我的做法是提供多个精心构建的Docker镜像核心服务镜像包含平台后端、前端、数据库、消息队列等基础服务。测试执行节点镜像这是一个关键设计。这个镜像里预装了完整的测试执行环境Python/Java运行环境、Chrome/Firefox浏览器、对应的WebDriver、Android模拟器或连接真机的所需工具、Appium Server等。平台可以动态扩展多个这样的执行节点。用户要做的仅仅是在宿主机上安装好Docker和Docker Compose然后执行我们提供的一个docker-compose up -d命令。剩下的所有依赖下载、服务启动、网络配置全部由Docker Compose文件定义好。这对于想快速体验的开发者、需要统一测试环境的团队、或者希望在CI/CD流水线中动态创建测试环境的场景是巨大的效率提升。注意由于Docker容器内运行UI测试特别是需要显示渲染的和Android模拟器涉及图形界面和硬件加速需要在docker run命令或Compose文件中添加特定的参数例如-e DISPLAY$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix用于X11转发或使用--privileged权限并安装xvfb虚拟帧缓冲区来模拟显示。这部分在平台的部署文档中会详细说明是初学者最容易踩坑的地方。3. 核心功能模块深度解析3.1 项目管理与测试资产组织平台以“项目”为最高维度进行隔离适合多个团队或产品线并行使用。在一个项目内测试资产被清晰地分层管理测试用例分为UI用例、接口用例、App用例。每个用例包含名称、描述、标签、所属模块等元信息。测试步骤对于UI和App测试步骤对应一系列原子操作点击、输入、断言等对于接口测试步骤对应单个API请求。测试数据支持全局变量、环境变量如测试/预发/生产环境的不同域名和数据驱动。数据驱动是亮点你可以准备一个CSV或JSON文件定义多组输入数据和预期结果一个用例模板就能自动运行多次极大提高覆盖率。页面对象/接口对象这是为了提升脚本可维护性。UI测试中将每个网页抽象成一个“页面对象”其中封装了该页面的所有元素定位器和常用操作方法。接口测试中可以将一个微服务的所有接口定义为一个“接口集合”统一管理Host、Header、Auth等信息。变更时只需修改一处。3.2 可视化用例编排与脚本编辑平台提供了两种用例创作模式兼顾了不同角色的需求低代码可视化编排通过拖拽方式将“打开浏览器”、“输入文本”、“点击元素”、“验证响应”等积木块组合成测试流程。这非常适合测试人员快速创建冒烟测试或简单流程测试无需编码。平台后台会将拖拽操作转化为对应的Python/JavaScript脚本。专业代码编辑器为开发者和资深测试提供完整的IDE体验支持语法高亮、代码补全、调试。你可以直接编写基于Page Object的UI脚本、灵活的接口请求脚本或Appium原生脚本。平台提供丰富的内置函数库比如数据库查询、Redis操作、文件读写、加解密工具等让你在脚本中能轻松处理各种测试前置和后置条件。一个接口测试的代码示例import requests from platform_sdk import assert_utils, db_utils # 从环境变量获取基础URL base_url env.get(API_BASE_URL) # 从数据驱动中获取本轮测试的username username data.get(username) # 1. 前置操作清理测试数据 db_utils.execute(DELETE FROM users WHERE username %s, (username,)) # 2. 执行接口请求 payload {username: username, password: Test123} headers {Content-Type: application/json} response requests.post(f{base_url}/auth/login, jsonpayload, headersheaders) # 3. 断言 assert_utils.equal(response.status_code, 200) assert_utils.json_path_exists(response.json(), $.token) token response.json()[token] # 4. 后置操作将token存入上下文供后续用例使用 context.set(auth_token, token)这个例子展示了如何在一次接口测试中串联起数据库操作、API调用、复杂断言和上下文传递这些都是实际项目中非常常见的需求。3.3 强大的调度与执行引擎测试用例写好了怎么跑平台提供了灵活的触发方式手动触发在Web界面上点选用例或套件立即执行。定时任务像Cron Job一样设置每天凌晨执行回归测试套件。CI/CD集成平台暴露了标准的RESTful API。你可以在Jenkins、GitLab CI、GitHub Actions的Pipeline中简单地调用一个API接口触发对应的测试任务并获取测试结果。这是实现“持续测试”的关键。测试套件与依赖可以将多个用例组合成测试套件并设置用例间的执行依赖关系。例如“登录”用例必须在“购物车结算”用例之前成功执行。执行引擎是异步的。当你触发一个任务后任务会被放入消息队列由空闲的“测试执行节点”Docker容器消费并执行。这意味着支持高并发可以启动多个执行节点同时跑不同的测试任务大幅缩短整体测试时间。资源隔离每个任务在独立的容器环境中运行互不干扰避免了环境污染。稳定性提升单个测试任务的失败甚至容器崩溃不会影响平台主服务和其他任务的执行。3.4 全景式测试报告与数据分析测试报告再也不是简单的“通过/失败”了。平台会收集每一次执行的完整数据生成多维度的报告概览仪表盘展示项目整体的通过率、失败率、执行趋势图、耗时最长的用例等。详尽的执行详情UI测试自动录制操作过程生成GIF或视频基于FFmpeg并附带每一步的截图。断言失败时高亮显示失败时的页面状态。接口测试展示完整的请求和响应信息Header、Body、断言详情、以及关联的日志。App测试同样提供操作录屏和关键步骤截图。日志聚合将测试脚本中的print日志、框架日志、服务端日志统一收集、分级INFO/DEBUG/ERROR展示方便排查问题。历史对比可以对比同一用例不同时间点的执行结果快速定位是代码变更还是环境问题导致的失败。这些数据不仅用于查看单次结果更重要的是能沉淀为测试资产。平台提供简单的数据分析功能比如“过去一个月哪个模块的失败率最高”、“哪些接口的响应时间在持续变慢”为产品质量和性能优化提供数据支撑。4. 从零到一的完整部署与配置实操4.1 基础环境准备与Docker部署假设你在一台干净的Linux服务器Ubuntu 20.04上部署。第一步安装Docker与Docker Compose# 安装Docker curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER # 将当前用户加入docker组避免每次sudo newgrp docker # 刷新用户组或重新登录 # 安装Docker Compose (v2) sudo apt-get update sudo apt-get install docker-compose-plugin # 验证安装 docker compose version第二步获取平台部署文件平台的所有部署配置都放在一个Git仓库里。git clone https://github.com/your-repo/auto-test-platform-deploy.git cd auto-test-platform-deploy这个仓库里最关键的文件是docker-compose.yml和.env环境配置文件。第三步配置环境变量编辑.env文件这是配置的核心。你需要关注几个关键项# 数据库配置 MYSQL_ROOT_PASSWORDyour_strong_password MYSQL_DATABASEtest_platform MYSQL_USERplatform_user MYSQL_PASSWORDuser_password # Redis配置用于缓存和消息队列 REDIS_PASSWORDredis_password # 平台访问地址用于报告中链接的生成 PLATFORM_URLhttp://your-server-ip:8080 # 测试节点相关如果需要执行UI/App测试 # 设置X11转发相关如果服务器无图形界面则使用XVFB ENABLE_XVFBtrue # 设置VNC端口方便远程查看执行情况可选 VNC_PORT5901 VNC_PASSWORDvncpassword第四步启动平台# 一键启动所有服务核心平台一个测试执行节点 docker compose up -d启动后用docker compose ps查看所有容器状态确保都是“Up”状态。首次启动会拉取镜像可能需要几分钟。第五步访问与初始化打开浏览器访问http://your-server-ip:8080。首次访问会进入初始化页面引导你创建管理员账号并配置数据库连接通常就是.env里配置的会自动填充。完成后你就进入了平台的主界面。实操心得部署看似简单但90%的问题出在.env配置和宿主机权限上。特别是涉及UI测试时如果ENABLE_XVFBtrue仍无法启动浏览器需要检查Docker容器是否以--privileged模式运行在Compose文件中已配置以及/tmp/.X11-unix的挂载是否正确。建议先在本地开发环境Mac/Windows Docker Desktop上部署测试再上服务器。4.2 第一个测试项目Web UI登录测试实战让我们创建一个实际的UI测试用例目标是测试一个登录页面。1. 创建项目与模块在平台中点击“新建项目”命名为“电商平台测试”。在项目内创建模块“用户认证”。2. 定义页面对象在“页面对象”仓库新建一个名为LoginPage的页面对象。URL:/login元素定位用户名输入框idusername密码输入框cssinput[typepassword]登录按钮xpath//button[text()登录]错误提示classalert-error操作方法平台可自动生成骨架def input_username(self, username): self.driver.find_element(By.ID, username).send_keys(username) def input_password(self, password): self.driver.find_element(By.CSS_SELECTOR, input[typepassword]).send_keys(password) def click_login_button(self): self.driver.find_element(By.XPATH, //button[text()登录]).click() def get_error_message(self): return self.driver.find_element(By.CLASS_NAME, alert-error).text3. 编写测试用例新建一个UI测试用例命名为“验证登录失败场景”。步骤1使用可视化编排拖入“打开浏览器”块选择ChromeURL填入{{BASE_URL}}/loginBASE_URL是环境变量。步骤2拖入“输入文本”块选择页面对象LoginPage的input_username方法参数填test_user。步骤3拖入“输入文本”块选择input_password参数填wrong_password。步骤4拖入“点击元素”块选择click_login_button。步骤5拖入“断言”块选择get_error_message的返回值“包含” “用户名或密码错误”。4. 配置环境与执行在“环境管理”中添加一个“测试环境”变量BASE_URL设置为http://test.your-app.com。 回到用例选择“测试环境”点击“执行”。平台会自动分配一个执行节点启动浏览器完成上述操作并生成报告。5. 进阶数据驱动如果我想测试多个错误的用户名密码组合呢在用例编辑界面切换到“数据驱动”标签上传一个CSV文件username,password,expected_error test_user,wrong_pass,用户名或密码错误 empty_user,,请输入用户名 test_user,short,密码长度不足然后在断言步骤中将硬编码的预期错误信息改为变量{{expected_error}}。平台会自动为CSV中的每一行数据运行一次用例。4.3 集成到CI/CD流水线以GitLab CI为例自动化测试只有集成到开发流程中才能发挥最大价值。以下是一个.gitlab-ci.yml的示例片段stages: - build - test - deploy ui_and_api_test: stage: test image: docker:latest services: - docker:dind variables: # 假设测试平台部署在 http://test-platform.internal PLATFORM_URL: http://test-platform.internal PROJECT_ID: 123 SUITE_ID: 456 API_TOKEN: $TEST_PLATFORM_TOKEN # Token在GitLab CI变量中设置 script: - | # 1. 调用平台API触发测试套件执行 RESPONSE$(curl -X POST ${PLATFORM_URL}/api/v1/task/trigger \ -H Authorization: Bearer ${API_TOKEN} \ -H Content-Type: application/json \ -d {\project_id\: ${PROJECT_ID}, \suite_id\: ${SUITE_ID}, \env\: \ci\}) TASK_ID$(echo $RESPONSE | jq -r .data.task_id) echo Triggered task: $TASK_ID # 2. 轮询任务状态直到完成超时设置300秒 for i in {1..30}; do STATUS$(curl -s ${PLATFORM_URL}/api/v1/task/${TASK_ID}/status \ -H Authorization: Bearer ${API_TOKEN} | jq -r .data.status) echo Task status: $STATUS if [ $STATUS FINISHED ]; then break elif [ $STATUS FAILED ] || [ $STATUS ERROR ]; then echo Task execution failed. exit 1 fi sleep 10 done # 3. 获取最终报告判断是否通过 REPORT$(curl -s ${PLATFORM_URL}/api/v1/task/${TASK_ID}/report/summary \ -H Authorization: Bearer ${API_TOKEN}) PASS_RATE$(echo $REPORT | jq -r .data.pass_rate) echo Test pass rate: ${PASS_RATE}% # 4. 如果通过率低于阈值如95%则标记CI任务失败 if (( $(echo $PASS_RATE 95 | bc -l) )); then echo Test pass rate is below threshold. Failing the pipeline. exit 1 fi only: - merge_requests # 仅在合并请求时触发 - main # 或在主干分支推送时触发这个配置实现了在每次合并请求或主干提交时自动触发平台的测试套件并根据测试结果决定CI流水线是否通过。API_TOKEN需要在平台的用户设置中生成并妥善保存在GitLab的CI/CD变量里。5. 避坑指南与效能提升技巧在实际使用和推广这个平台的过程中我积累了不少血泪教训这里分享几个最关键的点。5.1 环境与执行稳定性保障问题1UI测试在Docker中运行不稳定经常超时或无法启动浏览器。排查这通常是资源不足或显示问题。首先确保执行节点的Docker容器分配了足够的内存建议至少2GB和CPU。其次对于无头浏览器测试务必使用xvfb-run命令来启动浏览器或者使用Chrome/Firefox的--headless模式。我们的执行节点镜像已经内置了XVFB。技巧在测试脚本中一定要使用显式等待WebDriverWait而不是硬性的time.sleep()。网络波动或页面加载慢会导致元素找不到显式等待更健壮。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 不好的做法 time.sleep(5) element driver.find_element(By.ID, dynamic-element) # 好的做法 wait WebDriverWait(driver, 10) # 最多等10秒 element wait.until(EC.presence_of_element_located((By.ID, dynamic-element)))问题2并行执行测试时用例间相互干扰。排查这是测试隔离没做好。确保每个测试用例在执行前都处于一个干净的状态。例如通过API或数据库操作清理前一个测试创建的数据。技巧利用平台提供的setUp和tearDown钩子函数或注解。在setUp里初始化独立的数据如创建一个唯一的用户名在tearDown里清理。平台的设计是每个用例在一个独立的临时容器中执行文件系统和进程是隔离的但数据库和外部服务是共享的所以数据清理至关重要。5.2 测试脚本维护性优化问题页面元素一变动大量测试脚本报错维护成本高。解决方案严格执行Page Object Model (POM)设计模式。就像前面的LoginPage例子所有元素定位器和页面操作方法都集中定义在页面对象类中。当页面元素ID或CSS选择器变更时你只需要修改这一个页面对象文件所有引用该元素的测试用例都会自动生效。进阶技巧在页面对象中不要写死定位器字符串而是使用定位器字典或配置文件。这样甚至可以将元素定位信息交给非技术人员维护。# locators.py LOGIN_PAGE_LOCATORS { username_input: (id, username), password_input: (css, input[typepassword]), login_button: (xpath, //button[text()登录]) } # login_page.py from locators import LOGIN_PAGE_LOCATORS class LoginPage: def input_username(self, username): locator_type, locator_value LOGIN_PAGE_LOCATORS[username_input] self.driver.find_element(getattr(By, locator_type.upper()), locator_value).send_keys(username)5.3 平台性能与团队协作问题随着用例增多执行速度变慢报告查看卡顿。数据库优化测试执行记录、步骤详情、日志这些数据增长非常快。要定期如每月归档历史数据到备份表并对核心查询表如test_case,task的常用字段project_id,status,create_time建立索引。执行策略优化分片执行将大的测试套件拆分成多个小套件并行执行。增量测试与版本控制系统Git集成只运行与本次代码变更相关的测试用例。这需要平台能解析代码变更影响的范围实现起来较复杂但收益巨大。一个简单的起点是给用例打上标签如module_user然后根据提交信息中的关键词决定运行哪些标签的用例。团队协作平台支持基于角色的权限控制RBAC。可以为不同成员分配“浏览者”、“测试员”、“开发员”、“管理员”等角色控制其对项目、用例、执行任务的查看和操作权限。建立良好的用例评审和版本管理流程利用平台的“分支”或“版本”功能来管理测试资产的不同迭代。5.4 常见问题速查表问题现象可能原因解决方案Docker Compose启动失败端口冲突8080、3306、6379等端口被占用修改.env或docker-compose.yml中的端口映射如8080:8080改为8081:8080平台Web界面能打开但登录后无法加载项目前端静态资源加载失败或后端API服务未启动检查浏览器控制台(F12)网络请求错误docker compose logs backend查看后端日志UI测试执行失败提示“无法连接到Chrome”Chrome浏览器或Chromedriver版本不匹配Docker容器内显示问题确保执行节点镜像中的Chrome与Chromedriver版本兼容确认已启用XVFB或无头模式接口测试返回超时被测服务地址错误或网络不通平台执行节点无法访问该地址检查环境变量中的BASE_URL从执行节点容器内部curl一下被测服务地址App测试无法检测到手机/模拟器Appium服务未启动设备UDID未正确配置ADB连接问题查看执行节点容器日志中Appium的启动状态确认设备管理页面中设备状态为“在线”检查USB连接或模拟器端口映射测试报告中没有截图或录屏截图功能未开启存储路径权限不足FFmpeg未安装在平台设置中启用截图/录屏功能检查Docker卷挂载的目录权限在执行节点镜像中安装FFmpeg这个平台从构思到开源经历了无数次的迭代和踩坑。它可能不是功能最强大的但我坚信它在“开箱即用”、“降低门槛”、“统一体验”这几个点上做到了很好的平衡。对于想要快速搭建内部自动化测试体系又不想被繁杂的运维和集成困扰的团队来说它提供了一个可靠的起点。开源出来是希望它能帮助到更多有同样痛点的同行也期待社区的反馈能让它变得更好。