Commit 2c5d7b6a authored by Cai Wei's avatar Cai Wei

feat(*): 集成测试框架

parent 2dc8968a
Pipeline #1309 failed with stages
# DC-TOM API接口测试集成说明
## 📋 概述
已成功在本地CI脚本中集成了首页API接口正确性测试,现在支持独立运行API接口测试并在测试报告中展示结果。
## 🎯 API测试覆盖范围
### 测试的接口
- **健康度概览接口** (`/api/home/health/overview`)
- **健康度统计接口** (`/api/home/health/statistic`)
- **异常监控接口** (`/api/home/exception/monitor`)
- **除尘器告警接口** (`/api/home/duster/alarm`)
### 测试类型
- ✅ 基础功能测试(状态码、响应结构、数据类型)
- ✅ 错误处理测试(服务器错误、认证错误、网络错误)
- ✅ 性能测试(响应时间验证)
- ✅ 并发测试(同时访问多个接口)
- ✅ 数据一致性测试(多次调用数据一致性)
## 🚀 使用方法
### 1. 独立运行API测试
```bash
# 只运行API接口测试
./local-ci.sh api
# 或使用npm脚本
npm run ci:api
```
### 2. 作为完整测试的一部分
```bash
# 运行所有测试(包含API测试)
./local-ci.sh all
# 或
./local-ci.sh
```
### 3. 直接运行Cypress API测试
```bash
# 使用Cypress直接运行
npx cypress run --spec "cypress/e2e/dashboard-api.cy.js"
# 或使用npm脚本
npm run cy:run:api
```
## 📊 测试报告
### 报告结构
API测试结果会包含在以下报告中:
1. **完整测试报告** (`public/reports/merged-report.html`)
- 包含所有测试类型的汇总结果
2. **API专项报告** (`public/reports/api/`)
- 专门的API接口测试报告
- 详细展示每个接口的测试结果
3. **分类报告入口** (`public/index.html`)
- 提供各类测试报告的快速入口
- 包含API测试专项链接
### 报告访问
测试完成后,报告会自动在浏览器中打开,您可以:
- 点击"🔗 API接口测试"查看专项API测试结果
- 点击"📊 完整测试报告"查看所有测试的汇总
## 🔧 技术实现
### 文件结构
```
cypress/e2e/
├── dashboard-api.cy.js # API接口测试脚本
├── login.cy.js # 基础测试
├── dashboard.cy.js # 基础测试
└── ...
cypress/reports/
├── api/ # API测试报告目录
├── basic/ # 基础测试报告目录
├── business/ # 业务测试报告目录
└── data/ # 数据测试报告目录
public/
├── reports/
│ ├── merged-report.html # 汇总报告
│ ├── api/ # API专项报告
│ └── ...
└── index.html # 报告入口页面
```
### 脚本集成
- **local-ci.sh**: 添加了`api_tests()`函数和`api`测试类型
- **package.json**: 添加了`cy:run:api``ci:api`脚本命令
## 🎯 测试验证
API测试会验证以下内容:
### 响应验证
- HTTP状态码正确性
- 响应体结构完整性
- 数据类型正确性
- 业务数据合理性(如健康度0-100%)
### 错误处理
- 服务器错误响应处理
- 认证失败处理
- 网络错误处理
- 超时情况处理
### 性能监控
- 接口响应时间(< 5秒)
- 并发访问性能
- 数据一致性检查
## 📝 使用示例
```bash
# 1. 快速运行API测试
npm run ci:api
# 2. 运行完整测试套件
npm run ci:local
# 3. 查看测试帮助
./local-ci.sh help
# 4. 运行特定类型测试
./local-ci.sh basic # 基础功能测试
./local-ci.sh api # API接口测试
./local-ci.sh business # 业务功能测试
./local-ci.sh data # 数据管理测试
```
## 🔍 故障排除
如果API测试失败,请检查:
1. 应用服务器是否正常启动(端口3000)
2. 接口是否正常响应
3. 认证TOKEN是否有效
4. 网络连接是否正常
测试报告中会详细记录失败原因和截图,便于问题定位。
\ No newline at end of file
# 本地 CI 测试使用指南
## 概述
由于 GitLab 环境缺乏 Runner,我们提供了一个本地 CI 脚本来模拟 GitLab CI 流程,可以在本地环境运行完整的测试并生成测试报告。
## 快速开始
### 1. 环境要求
- **Node.js**: 18+
- **npm**: 最新版本
- **Chrome浏览器**: 用于 Cypress 测试
- **操作系统**: macOS, Linux 或 Windows (WSL)
### 2. 使用方法
#### 方法一: 使用 Bash 脚本 (推荐)
```bash
# 运行所有测试类型
./local-ci.sh
# 只运行基础测试 (登录、仪表盘、导航)
./local-ci.sh basic
# 只运行完整测试套件
./local-ci.sh full
# 只运行业务功能测试 (除尘器、设备管理、监控)
./local-ci.sh business
# 只运行数据管理测试 (采集器、闭环管理、告警)
./local-ci.sh data
# 查看帮助
./local-ci.sh help
```
#### 方法二: 使用 npm 脚本
```bash
# 运行所有测试
npm run ci:local
# 运行基础测试
npm run ci:basic
# 运行完整测试
npm run ci:full
# 运行业务功能测试
npm run ci:business
# 运行数据管理测试
npm run ci:data
```
## 执行流程
本地 CI 脚本会按以下顺序执行:
```
1. 🔍 环境依赖检查
├── Node.js 版本验证
├── npm 可用性检查
└── 项目文件存在性验证
2. 📦 构建阶段
├── 安装项目依赖 (npm ci)
├── 构建生产版本 (npm run build)
└── 验证构建结果
3. 🚀 启动应用服务器
├── 启动预览服务器 (npm run preview)
├── 健康检查 (curl localhost:3000)
└── 确认服务器可用
4. 🧪 执行 Cypress 测试
├── 运行指定的测试套件
├── 生成测试视频和截图
└── 生成 mochawesome 报告
5. 📊 生成测试报告
├── 安装报告生成工具
├── 合并所有测试报告
├── 生成 HTML 格式报告
├── 复制媒体文件 (视频/截图)
└── 生成索引页面
6. 🌐 打开测试报告
└── 自动在浏览器中打开报告
```
## 测试分类
### 基础测试 (basic)
- **范围**: 核心功能验证
- **包含**: 登录、仪表盘、导航
- **执行时间**: ~5-10分钟
- **用途**: 快速验证核心功能
### 完整测试 (full)
- **范围**: 所有测试用例
- **包含**: cypress/e2e/*.cy.js
- **执行时间**: ~20-30分钟
- **用途**: 全面功能验证
### 业务功能测试 (business)
- **范围**: 业务核心功能
- **包含**: 除尘器概览、设备管理、监控
- **执行时间**: ~10-15分钟
- **用途**: 业务逻辑验证
### 数据管理测试 (data)
- **范围**: 数据相关功能
- **包含**: 采集器、闭环管理、告警
- **执行时间**: ~10-15分钟
- **用途**: 数据流程验证
## 生成的报告
### 报告结构
```
public/
├── index.html # 主报告页面
├── reports/
│ ├── merged-report.html # 详细测试报告
│ └── merged-report.json # 报告数据
└── assets/
├── videos/ # 测试执行视频
└── screenshots/ # 失败时截图
```
### 报告内容
- **测试概览**: 通过率、失败率、执行时间
- **详细结果**: 每个测试用例的执行状态
- **失败分析**: 失败用例的错误信息和截图
- **执行视频**: 完整的测试执行过程录像
- **环境信息**: 浏览器版本、测试配置等
## 故障排除
### 常见问题
#### 1. 权限错误
```bash
# 解决方案: 给脚本添加执行权限
chmod +x local-ci.sh
```
#### 2. 端口被占用
```bash
# 解决方案: 关闭占用3000端口的进程
lsof -ti:3000 | xargs kill
```
#### 3. Chrome浏览器未找到
```bash
# macOS 解决方案
brew install --cask google-chrome
# Ubuntu 解决方案
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo apt-get update && sudo apt-get install google-chrome-stable
```
#### 4. 依赖安装失败
```bash
# 清除缓存重新安装
rm -rf node_modules package-lock.json
npm install
```
#### 5. 测试超时
```bash
# 增加 Cypress 超时时间 (在 cypress.config.js 中)
defaultCommandTimeout: 20000
pageLoadTimeout: 60000
```
### 调试模式
如果需要调试特定测试,可以:
```bash
# 1. 手动启动服务器
npm run preview
# 2. 在另一个终端打开 Cypress GUI
npm run cy:open
# 3. 在 GUI 中选择要调试的测试
```
## 与 GitLab CI 的对比
| 功能 | GitLab CI | 本地 CI | 说明 |
|------|-----------|---------|------|
| 环境隔离 | ✅ Docker容器 | ❌ 本地环境 | 本地可能受环境影响 |
| 并行执行 | ✅ 多Runner并行 | ❌ 单线程执行 | 本地执行时间较长 |
| 缓存机制 | ✅ 分布式缓存 | ✅ 本地缓存 | 两者都支持依赖缓存 |
| 报告存储 | ✅ Artifacts+Pages | ✅ 本地文件 | 功能基本相同 |
| 自动触发 | ✅ Git事件触发 | ❌ 手动执行 | 本地需要手动运行 |
| 调试便利性 | ❌ 远程调试困难 | ✅ 本地调试方便 | 本地更便于调试 |
## 最佳实践
### 1. 开发阶段
- 使用 `npm run ci:basic` 进行快速验证
- 修复问题后使用 `npm run ci:full` 进行全面测试
### 2. 发布前
- 运行 `./local-ci.sh` 执行完整的测试流程
- 检查生成的报告确认所有测试通过
### 3. 持续改进
- 定期检查测试执行时间,优化慢速测试
- 分析失败模式,改进测试用例
- 根据项目发展调整测试分组策略
## 自动化增强
可以考虑添加以下自动化功能:
### 1. 定时执行
```bash
# 使用 cron 定时执行
0 2 * * * cd /path/to/project && ./local-ci.sh full
```
### 2. Git Hook 集成
```bash
# 在 .git/hooks/pre-push 中添加
#!/bin/sh
./local-ci.sh basic
```
### 3. Slack 通知
```bash
# 在脚本末尾添加通知
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"测试完成: '"$test_result"'"}' \
YOUR_SLACK_WEBHOOK_URL
```
---
## 总结
本地 CI 脚本提供了一个完整的解决方案,可以在 GitLab Runner 不可用的情况下:
**完整模拟 GitLab CI 流程**
**生成专业的测试报告**
**支持多种测试策略**
**提供详细的调试信息**
**易于使用和扩展**
现在您可以在本地环境获得与 GitLab CI 相同的测试体验!
\ No newline at end of file
# 本地 CI 解决方案总结
## 问题背景
由于 GitLab 环境缺乏 Runner,无法正常执行 CI/CD 流水线,需要一个本地解决方案来:
- 运行 Cypress E2E 测试
- 生成测试报告
- 模拟 GitLab CI 流程
## 解决方案
### 🎯 创建的文件
1. **`local-ci.sh`** - 主要的本地 CI 脚本
- 完整模拟 GitLab CI 流程
- 支持多种测试策略
- 自动生成测试报告
2. **`quick-test.sh`** - 快速测试脚本
- 用于单个测试文件验证
- 快速调试和开发
3. **`LOCAL_CI_GUIDE.md`** - 详细使用指南
- 完整的使用说明
- 故障排除指南
- 最佳实践建议
4. **更新的 `package.json`** - 新增 npm 脚本
- 便于使用的 npm 命令
- 统一的脚本管理
### 🚀 使用方法
#### 完整测试流程
```bash
# 运行所有测试 (推荐用于发布前验证)
./local-ci.sh
# 只运行基础测试 (快速验证)
./local-ci.sh basic
npm run ci:basic
# 运行特定测试类型
./local-ci.sh business # 业务功能测试
./local-ci.sh data # 数据管理测试
./local-ci.sh full # 完整测试套件
```
#### 快速测试 (开发调试)
```bash
# 快速测试单个文件
./quick-test.sh cypress/e2e/login.cy.js
npm run test:login
# 快速测试仪表盘
npm run test:dashboard
# 默认快速测试
npm run test:quick
```
### 📊 生成的报告
#### 完整报告 (local-ci.sh)
```
public/
├── index.html # 主报告页面
├── reports/
│ ├── merged-report.html # 详细测试报告
│ └── merged-report.json # 报告数据
└── assets/
├── videos/ # 测试执行视频
└── screenshots/ # 失败时截图
```
#### 快速报告 (quick-test.sh)
```
public/quick-reports/
├── index.html # 简单报告索引
└── *.html # 单个测试报告
```
### 🔧 技术特性
#### 自动化流程
1. **环境检查** - Node.js、npm、项目文件验证
2. **依赖管理** - 自动安装和缓存依赖
3. **应用构建** - 自动构建和验证
4. **服务启动** - 自动启动预览服务器并健康检查
5. **测试执行** - 运行 Cypress 测试并生成报告
6. **报告生成** - 合并报告并生成 HTML 格式
7. **结果展示** - 自动打开浏览器查看报告
#### 错误处理
- **服务器启动失败**: 自动重试和错误提示
- **测试失败**: 继续执行并记录失败信息
- **依赖问题**: 自动安装缺失的全局工具
- **端口占用**: 清晰的错误提示和解决建议
#### 兼容性
- **操作系统**: macOS, Linux, Windows (WSL)
- **浏览器**: Chrome (主要), Firefox (备选)
- **Node.js**: 18+ (与项目要求一致)
### 📈 优势对比
| 功能 | GitLab CI | 本地 CI 脚本 | 快速测试脚本 |
|------|-----------|-------------|-------------|
| **环境隔离** | ✅ Docker | ❌ 本地环境 | ❌ 本地环境 |
| **执行速度** | 中等 | 快 (本地) | 最快 |
| **调试便利** | 困难 | ✅ 容易 | ✅ 最容易 |
| **报告质量** | ✅ 完整 | ✅ 完整 | 简单 |
| **并行执行** | ✅ 支持 | ❌ 单线程 | ❌ 单线程 |
| **自动触发** | ✅ Git事件 | ❌ 手动 | ❌ 手动 |
| **依赖管理** | ✅ 自动 | ✅ 自动 | ✅ 智能缓存 |
| **适用场景** | 生产环境 | 开发/测试 | 开发调试 |
### 🎨 使用场景建议
#### 开发阶段
```bash
# 修改代码后快速验证
npm run test:quick
# 验证特定功能
npm run test:login
npm run test:dashboard
```
#### 测试阶段
```bash
# 运行基础测试验证主要功能
npm run ci:basic
# 运行特定模块测试
npm run ci:business
npm run ci:data
```
#### 发布前
```bash
# 运行完整测试流程
npm run ci:local
# 或
./local-ci.sh
```
### 🔍 监控和改进
#### 性能监控
- 监控测试执行时间
- 识别慢速测试用例
- 优化测试顺序和分组
#### 质量提升
- 分析失败模式
- 改进测试用例覆盖率
- 优化测试数据和环境
#### 自动化增强
- 考虑添加 Git hooks 集成
- 实现定时测试执行
- 添加测试结果通知
### 📋 维护清单
#### 定期检查
- [ ] 更新 Cypress 和相关依赖
- [ ] 验证测试用例的有效性
- [ ] 检查报告生成工具版本
- [ ] 优化脚本性能和错误处理
#### 扩展功能
- [ ] 添加性能测试集成
- [ ] 实现多浏览器测试支持
- [ ] 添加测试覆盖率报告
- [ ] 集成代码质量检查
---
## 🎉 总结
本地 CI 解决方案提供了一个完整的替代方案,在 GitLab Runner 不可用的情况下:
**完全模拟 GitLab CI 流程**
**生成专业级测试报告**
**支持灵活的测试策略**
**提供便捷的调试能力**
**易于使用和维护**
现在您可以在本地环境获得与 GitLab CI 相同的测试体验,确保代码质量和功能稳定性!
**下一步建议**:
1. 先运行 `npm run ci:basic` 验证基本功能
2. 成功后运行 `npm run ci:local` 执行完整测试
3. 查看生成的报告了解项目测试状况
4. 根据需要调整测试策略和配置
\ No newline at end of file
# 自然语言测试描述指南
## 🎯 概述
DC-TOM项目现在支持使用中文自然语言描述来生成Cypress测试代码,让测试编写变得更加直观和易懂。
## 📝 语法格式
### 基本结构
```
目标页面:[页面名称]
测试内容:
1,[测试步骤描述]
2,[测试步骤描述]
3,[测试步骤描述]
...
```
### 支持的页面模块
| 页面名称 | 对应路由 | 说明 |
|---------|---------|------|
| 首页 | dashboard | 仪表盘主页 |
| 仪表盘 | dashboard | 仪表盘页面 |
| 告警总览 | alerts | 告警管理页面 |
| 设备管理 | management/device-management | 设备管理页面 |
| 布袋周期 | collectorList | 布袋周期管理页面 |
| 除尘器总览 | dust-overview | 除尘器管理页面 |
| 除尘监测 | monitor | 实时监测页面 |
| 闭环管理 | my-loop | 工作流管理页面 |
### 支持的操作动词
| 动词 | 说明 | 生成的Cypress操作 |
|------|------|------------------|
| 查询/搜索/检索 | 搜索操作 | `cy.get().click()` (搜索按钮) |
| 查看/检查/验证 | 验证操作 | `cy.get().should('be.visible')` |
| 点击/单击 | 点击操作 | `cy.get().click()` |
| 输入/填写 | 输入操作 | `cy.get().type()` |
| 选择 | 选择操作 | `cy.get().select()` |
### 支持的数据对象
| 对象名称 | 生成的选择器 | 说明 |
|---------|-------------|------|
| 布袋健康度 | `[data-testid="dashboard-bag-progress"]` | 布袋健康度指标 |
| 综合健康度 | `[data-testid="dashboard-health-score"]` | 综合健康度评分 |
| 布袋总数 | `[data-testid*="bag-total"]` | 布袋总数统计 |
| 告警数据 | `[data-testid*="alert-table"]` | 告警数据表格 |
| 顶部区域 | `.top-area, .header-area` | 页面顶部区域 |
### 支持的时间范围
| 时间描述 | 处理方式 | 说明 |
|---------|----------|------|
| 今日/今天 | 选择今天日期 | 自动点击日期选择器选择今日 |
| 昨日/昨天 | 选择昨天日期 | 选择昨天的日期 |
| 本周 | 选择本周范围 | 选择本周时间范围 |
| 本月 | 选择本月范围 | 选择本月时间范围 |
## 📖 使用示例
### 示例1:仪表盘综合测试
```
目标页面:首页
测试内容:
1,在告警总览内查询今日布袋告警数据。
2,查询布袋总数
3,在首页查看顶部区域综合健康度的布袋健康度
```
**生成的测试代码:**
```javascript
/// <reference types="cypress" />
describe('首页功能测试', () => {
beforeEach(() => {
cy.mockLogin()
cy.visit('/#/dashboard')
cy.get('[data-testid="dashboard-container"]').should('be.visible')
})
it('应该能够在告警总览内查询今日布袋告警数据', () => {
// 切换到alerts模块
cy.visit('/#/alerts')
cy.wait(1000)
// 在告警总览内查询今日布袋告警数据
cy.get('[data-testid*="date-picker"]').click()
cy.get('.el-picker-panel').should('be.visible')
// 选择今日日期
cy.get('.el-date-table td.today').click()
cy.get('[data-testid*="search-button"]').click()
cy.wait(1000)
// 验证结果
cy.get('[data-testid*="alert-table"]').should('be.visible')
})
it('应该能够查询布袋总数', () => {
// 查询布袋总数
// 验证结果
cy.get('[data-testid*="bag-total"]').should('be.visible')
})
it('应该能够在首页查看顶部区域综合健康度的布袋健康度', () => {
// 在首页查看顶部区域综合健康度的布袋健康度
cy.get('[data-testid="dashboard-bag-progress"]').should('be.visible')
// 验证结果
cy.get('[data-testid="dashboard-bag-progress"]').should('be.visible')
})
})
```
### 示例2:设备管理测试
```
目标页面:设备管理
测试内容:
1,搜索设备名称为"除尘器001"的设备
2,验证搜索结果表格显示正常
3,点击重置按钮清空搜索条件
```
### 示例3:布袋周期测试
```
目标页面:布袋周期
测试内容:
1,在仓室输入框中输入"A仓室"
2,在除尘器名称输入框中输入"1#除尘器"
3,点击查询按钮执行搜索
4,验证表格显示搜索结果
5,点击更换周期分析按钮打开对话框
```
## 🚀 使用方法
### 方法1:Web界面(推荐)
1. 启动Web界面:`npm run test-gen:web`
2. 点击"自然语言"标签页
3. 输入中文描述
4. 点击"解析生成测试代码"
5. 复制或下载生成的代码
### 方法2:命令行工具
```bash
# 1. 创建自然语言描述文件(.txt格式)
echo "目标页面:首页
测试内容:
1,查看布袋健康度指标
2,验证数据加载正常" > my-test.txt
# 2. 使用CLI工具解析
cd cypress/test-generator
node cli.js parse my-test.txt
# 3. 或使用集成脚本
./test-generator.sh parse test-descriptions/my-test.txt
```
### 方法3:npm脚本
```bash
# 生成自然语言示例
npm run test-gen:nl-example
# 批量解析所有.txt文件
npm run test-gen:parse
```
## 🎨 高级用法
### 1. 跨模块测试
```
目标页面:首页
测试内容:
1,在首页查看健康度指标
2,切换到告警总览查询告警数据
3,返回首页验证数据一致性
```
### 2. 条件测试
```
目标页面:设备管理
测试内容:
1,如果设备列表为空,显示空状态提示
2,搜索不存在的设备名称
3,验证显示"无数据"提示
```
### 3. 工作流测试
```
目标页面:布袋周期
测试内容:
1,查询即将到期的布袋
2,选择需要更换的布袋
3,提交更换申请
4,验证状态更新
```
## 🔧 自定义扩展
### 添加新的操作动词
`natural-language-parser.js` 中的 `actionPatterns` 数组添加:
```javascript
{
pattern: /拖拽|拖动/,
action: 'drag',
description: '拖拽操作'
}
```
### 添加新的数据对象
`dataPatterns` 数组添加:
```javascript
{
pattern: /新的数据类型/,
type: 'new_data_type',
selector: '[data-testid="new-data-selector"]'
}
```
### 添加新的页面模块
`moduleMapping` 对象添加:
```javascript
'新页面': {
route: 'new-page',
testId: 'new-page',
moduleName: '新页面'
}
```
## 📋 最佳实践
### 1. 描述要清晰具体
✅ 好的描述:
```
在布袋健康度指标中查看当前状态
```
❌ 模糊的描述:
```
看看页面
```
### 2. 使用标准的操作动词
✅ 推荐:
```
1,查询今日告警数据
2,验证表格显示正常
3,点击重置按钮
```
❌ 不推荐:
```
1,弄一下告警数据
2,看看表格对不对
3,搞一下重置
```
### 3. 保持逻辑顺序
✅ 有逻辑的顺序:
```
1,输入搜索条件
2,点击搜索按钮
3,验证搜索结果
4,重置搜索条件
```
### 4. 指定具体的目标
✅ 具体的目标:
```
在仓室输入框中输入"A仓室"
```
❌ 模糊的目标:
```
输入一些内容
```
## 🐛 常见问题
### Q: 解析失败怎么办?
A: 检查以下几点:
- 是否使用了支持的页面名称
- 是否使用了支持的操作动词
- 描述格式是否正确
- 是否包含"目标页面"和"测试内容"
### Q: 生成的选择器不准确?
A: 可以在自然语言解析器中添加更具体的选择器映射,或者在生成后手动调整选择器。
### Q: 如何测试复杂的交互流程?
A: 将复杂流程分解为多个简单步骤,每个步骤使用一个具体的操作动词。
### Q: 支持英文描述吗?
A: 目前主要支持中文描述,英文支持需要扩展解析器的模式匹配。
## 🔮 未来计划
- [ ] 支持更多复杂的条件逻辑
- [ ] 添加更多Element Plus组件的智能识别
- [ ] 支持测试数据的动态生成
- [ ] 集成AI模型提升解析准确度
- [ ] 支持多语言描述(英文、日文等)
---
通过这种自然语言描述方式,您可以用最直观的中文来描述测试需求,系统会自动生成符合项目规范的Cypress测试代码,大大降低了测试编写的技术门槛!
\ No newline at end of file
# Vue 3 + Vite
# DC-TOM 项目
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
基于 Vue 3 + Vite + Element Plus 的现代化前端项目,专为除尘器监控和管理系统设计。
## 🚀 快速开始
### 安装依赖
```bash
npm install
```
### 开发模式
```bash
npm run dev
```
### 构建生产版本
```bash
npm run build
```
## 🧪 测试
### Cypress 端到端测试
```bash
# 打开 Cypress 测试界面
npm run cy:open
# 运行所有测试
npm run cy:run
# 运行特定测试套件
npm run cy:run:basic # 基础测试
npm run cy:run:business # 业务测试
npm run cy:run:data # 数据测试
```
### 本地 CI 测试
```bash
# 运行完整的本地 CI 流程
npm run ci:local
# 快速测试
npm run test:quick
```
## 🔧 测试生成器
### 自动化测试生成工具
项目包含了一个强大的测试生成器,可以从JSON描述自动生成Cypress测试代码。
#### 初始化测试生成器
```bash
npm run test-gen:setup
```
#### 生成示例文件
```bash
# JSON格式示例
npm run test-gen:example
# 自然语言描述示例
npm run test-gen:nl-example
```
#### 验证测试描述
```bash
npm run test-gen:validate
```
#### 生成测试代码
```bash
# 从JSON文件生成
npm run test-gen:generate
# 从自然语言描述生成
npm run test-gen:parse
```
#### 运行生成的测试
```bash
npm run test-gen:run
```
#### 启动Web界面
```bash
npm run test-gen:web
```
### 测试描述格式
项目支持两种测试描述方式:
#### 1. 自然语言描述(推荐)
使用中文自然语言直接描述测试场景:
```
目标页面:首页
测试内容:
1,在告警总览内查询今日布袋告警数据。
2,查询布袋总数
3,在首页查看顶部区域综合健康度的布袋健康度
```
支持的操作:查询、查看、点击、输入、验证等
支持的模块:首页、告警总览、设备管理、布袋周期等
支持的时间:今日、昨日、本周、本月等
#### 2. JSON格式描述
使用JSON格式描述测试场景,支持多种测试类型:
- UI验证测试
- 交互功能测试
- 数据验证测试
- 错误处理测试
- 性能测试
- 响应式设计测试
详细使用说明请参考:
- [测试生成器文档](cypress/test-generator/README.md)
- [自然语言测试指南](NATURAL_LANGUAGE_TESTING_GUIDE.md)
## 📁 项目结构
```
src/
├── components/ # 公共组件
├── layout/ # 布局组件
├── views/ # 页面组件
├── pinia/ # 状态管理
├── router/ # 路由配置
├── request/ # API 请求
└── utils/ # 工具函数
cypress/
├── e2e/ # 端到端测试
├── test-generator/ # 测试生成器
├── support/ # 测试支持文件
└── fixtures/ # 测试数据
```
## 🛠️ 技术栈
- **前端框架**: Vue 3.5+ (Composition API + `<script setup>`)
- **构建工具**: Vite 6.3+
- **UI组件库**: Element Plus 2.9+
- **状态管理**: Pinia 3.0+
- **路由**: Vue Router 4.5+
- **图表库**: ECharts 5.6+
- **HTTP客户端**: Axios 1.9+
- **测试框架**: Cypress 13.6+
- **样式预处理**: Sass 1.88+
## 📖 开发指南
### 代码规范
- 使用 Vue 3 Composition API
- 遵循 `<script setup>` 语法
- 使用 TypeScript (可选)
- 统一的代码格式化
### 测试策略
- 分层测试:基础、业务、数据
- 自动化测试生成
- CI/CD 集成
- 测试报告生成
## 🔗 相关链接
- [Vue 3 文档](https://vuejs.org/)
- [Vite 文档](https://vitejs.dev/)
- [Element Plus 文档](https://element-plus.org/)
- [Cypress 文档](https://docs.cypress.io/)
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
# DC-TOM 测试描述转测试脚本流程架构实施总结
## 🎯 项目目标
在 DC-TOM 项目基础上构建一个完整的测试描述转测试脚本的流程架构,使用JSON输入格式,实现自动化测试代码生成。
## 🏗️ 系统架构
### 整体架构图
```mermaid
graph TB
A[JSON测试描述] --> B[Schema验证]
B --> C[测试代码生成器]
C --> D[模板引擎]
D --> E[Cypress测试代码]
E --> F[测试执行]
F --> G[测试报告]
H[Web界面] --> A
I[CLI工具] --> A
J[示例文件] --> A
subgraph "核心组件"
B
C
D
end
subgraph "用户界面"
H
I
J
end
```
### 目录结构
```
cypress/test-generator/
├── config.js # 核心配置文件
├── schema.json # JSON Schema验证规范
├── template-engine.js # 模板引擎
├── test-code-generator.js # 代码生成器
├── cli.js # 命令行工具
├── web-interface.html # Web可视化界面
└── README.md # 详细文档
test-descriptions/ # JSON测试描述目录
├── collector-test-complete.json
├── dashboard-test.json
└── device-management-test.json
cypress/e2e/generated/ # 生成的测试文件目录
test-generator.sh # 集成脚本
```
## 🔧 核心组件
### 1. 配置管理 (config.js)
- **功能**: 集中管理项目配置、模块映射、选择器模板
- **特性**:
- 模块路由映射 (登录→login, 仪表盘→dashboard等)
- 测试ID前缀映射
- 通用选择器模板
- Element Plus组件选择器
### 2. JSON Schema验证 (schema.json)
- **功能**: 定义JSON测试描述的标准格式
- **支持的测试类型**: ui, interaction, data, error, performance, responsive
- **操作类型**: click, type, select, verify, wait, intercept, custom
- **断言类型**: be.visible, exist, contain, have.attr等
### 3. 模板引擎 (template-engine.js)
- **功能**: 管理和渲染测试代码模板
- **模板类型**:
- 基础模板 (base)
- beforeEach模板
- UI验证模板
- 交互测试模板
- 数据验证模板
- 错误处理模板
- 响应式设计模板
- 性能测试模板
### 4. 代码生成器 (test-code-generator.js)
- **功能**: 将JSON描述转换为Cypress测试代码
- **核心方法**:
- `generateFromJSON()`: 主生成方法
- `validateTestDescription()`: JSON验证
- `buildTemplateContext()`: 构建模板上下文
- `processSteps()`: 处理测试步骤
- `generateTestFile()`: 生成文件
### 5. CLI工具 (cli.js)
- **功能**: 命令行操作界面
- **支持命令**:
- `generate`: 生成测试代码
- `validate`: 验证JSON格式
- `example`: 生成示例文件
- `help`: 显示帮助
### 6. Web界面 (web-interface.html)
- **功能**: 可视化测试生成界面
- **特性**:
- 实时JSON验证
- 代码预览
- 示例加载
- 代码复制和下载
## 📋 JSON测试描述格式
### 基本结构
```json
{
"testSuite": {
"name": "测试套件名称",
"module": "模块名称",
"description": "测试描述",
"beforeEach": {
"login": true,
"visit": "页面路径",
"waitFor": ["选择器数组"]
},
"scenarios": [
{
"name": "测试场景名称",
"type": "测试类型",
"steps": [],
"expectedResults": []
}
]
}
}
```
### 支持的模块
- 登录、仪表盘、除尘器总览、布袋周期
- 除尘监测、设备管理、闭环管理、告警总览
### 测试类型
- **ui**: UI组件验证
- **interaction**: 用户交互测试
- **data**: 数据验证测试
- **error**: 错误处理测试
- **performance**: 性能测试
- **responsive**: 响应式设计测试
## 🚀 使用流程
### 1. 环境初始化
```bash
npm run test-gen:setup
```
### 2. 生成示例文件
```bash
npm run test-gen:example
```
### 3. 创建JSON测试描述
- 使用Web界面: `npm run test-gen:web`
- 手动编写JSON文件放入 `test-descriptions/` 目录
### 4. 验证JSON格式
```bash
npm run test-gen:validate
```
### 5. 生成测试代码
```bash
npm run test-gen:generate
```
### 6. 运行生成的测试
```bash
npm run test-gen:run
```
## 🎨 选择器占位符系统
为简化选择器编写,系统提供占位符:
| 占位符 | 替换结果 | 说明 |
|--------|----------|------|
| `{module}` | 模块ID | 当前模块的testid前缀 |
| `{container}` | `[data-testid="{module}-container"]` | 主容器 |
| `{searchForm}` | `[data-testid="{module}-search-form"]` | 搜索表单 |
| `{table}` | `[data-testid="{module}-common-table"]` | 数据表格 |
| `{searchButton}` | `[data-testid="{module}-search-button"]` | 搜索按钮 |
| `{resetButton}` | `[data-testid="{module}-reset-button"]` | 重置按钮 |
## 📊 生成的测试代码特点
### 1. 标准化结构
```javascript
/// <reference types="cypress" />
describe('测试套件名称', () => {
beforeEach(() => {
cy.mockLogin()
cy.visit('/#/路径')
cy.get('[data-testid="容器"]').should('be.visible')
})
it('测试场景名称', () => {
// 测试步骤
// 结果验证
})
})
```
### 2. 智能选择器处理
- 自动替换占位符
- 支持Element Plus组件选择器
- 兼容现有项目的data-testid规范
### 3. 错误处理支持
- API拦截和模拟
- 网络错误模拟
- 超时处理
### 4. 性能和响应式测试
- 页面加载时间验证
- 多视口尺寸测试
- 自动化性能监控
## 🔗 集成到现有CI/CD
### 本地CI集成
生成的测试自动集成到现有的本地CI脚本:
```bash
./local-ci.sh generated # 运行生成的测试
```
### package.json脚本
新增的npm脚本:
- `test-gen:setup`: 环境初始化
- `test-gen:example`: 生成示例
- `test-gen:validate`: 验证JSON
- `test-gen:generate`: 生成测试
- `test-gen:run`: 运行测试
- `test-gen:web`: Web界面
- `cy:run:generated`: 运行生成的测试
## 📈 扩展性设计
### 1. 模块扩展
```javascript
// config.js中添加新模块
moduleRoutes: {
'新模块': 'new-module-route'
},
moduleTestIds: {
'新模块': 'new-module'
}
```
### 2. 测试类型扩展
```javascript
// template-engine.js中添加新模板
createNewTestTemplate() {
return `新测试类型的模板`;
}
```
### 3. 操作类型扩展
```javascript
// test-code-generator.js中添加新操作
case 'newAction':
stepCode += `cy.newCustomAction('${step.value}')\n`;
break;
```
## ✅ 已完成功能
### 核心功能
- ✅ JSON Schema定义和验证
- ✅ 多种测试类型支持
- ✅ 模板引擎系统
- ✅ 代码生成器
- ✅ CLI工具
- ✅ Web可视化界面
- ✅ 集成脚本
### 测试支持
- ✅ UI验证测试
- ✅ 交互功能测试
- ✅ 数据验证测试
- ✅ 错误处理测试
- ✅ 性能测试
- ✅ 响应式设计测试
### 项目集成
- ✅ package.json脚本集成
- ✅ 现有CI/CD兼容
- ✅ 目录结构规范
- ✅ 文档完整性
## 🎯 技术亮点
### 1. 架构设计
- **模块化设计**: 各组件职责清晰,便于维护扩展
- **配置驱动**: 通过配置文件管理项目特定设置
- **模板化生成**: 使用模板引擎确保代码一致性
### 2. 用户体验
- **多种使用方式**: CLI、Web界面、脚本集成
- **实时验证**: JSON格式实时检查和错误提示
- **示例驱动**: 丰富的示例帮助快速上手
### 3. 代码质量
- **标准化输出**: 生成的测试代码符合Cypress最佳实践
- **错误处理**: 完善的错误检查和用户友好提示
- **文档完整**: 详细的使用说明和API文档
### 4. 项目兼容性
- **无侵入性**: 不影响现有测试代码
- **向后兼容**: 兼容现有的CI/CD流程
- **渐进增强**: 可以逐步迁移现有测试
## 🔮 未来规划
### 短期优化
- [ ] 增加更多Element Plus组件支持
- [ ] 优化模板引擎性能
- [ ] 添加测试覆盖率统计
### 中期发展
- [ ] 支持Visual Testing
- [ ] API测试自动生成
- [ ] 性能基准测试集成
### 长期愿景
- [ ] AI驱动的测试生成
- [ ] 跨项目模板共享
- [ ] 云端测试生成服务
## 🏆 总结
本次实施成功构建了一个完整的测试描述转测试脚本的流程架构,具备以下核心价值:
1. **提升效率**: 从手动编写测试到JSON驱动自动生成,大幅提升测试开发效率
2. **保证质量**: 标准化的模板确保生成的测试代码质量和一致性
3. **降低门槛**: 通过JSON描述和Web界面,降低测试编写的技术门槛
4. **易于维护**: 模块化设计和配置驱动,便于后续维护和扩展
5. **无缝集成**: 与现有项目CI/CD流程完美集成,不影响现有工作流
这套系统为DC-TOM项目的测试自动化奠定了坚实基础,同时也为其他类似项目提供了可复用的解决方案。
\ No newline at end of file
......@@ -13,7 +13,11 @@ export default defineConfig({
requestTimeout: 15000,
responseTimeout: 15000,
pageLoadTimeout: 30000,
// Cypress Studio配置
experimentalStudio: true,
experimentalInteractiveRunEvents: true,
chromeWebSecurity: false, // 允许Studio跨域交互
modifyObstructiveCode: false,
retries: {
runMode: 2, // CI环境重试2次
openMode: 0 // 开发环境不重试
......
This diff is collapsed.
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
})
/* ==== Test Created with Cypress Studio ==== */
it('test1', function() {
/* ==== Generated with Cypress Studio ==== */
cy.visit('http://localhost:3000/#/login');
cy.get('[data-testid="login-username-input"]').clear('z');
cy.get('[data-testid="login-username-input"]').type('zongheng_admin');
cy.get('[data-testid="login-password-input"]').clear('9%#F46vt');
cy.get('[data-testid="login-password-input"]').type('9%#F46vt');
cy.get('[data-testid="login-captcha-input"]').clear('8');
cy.get('[data-testid="login-captcha-input"]').type('8888');
cy.get('[data-testid="login-submit-button"]').click();
cy.get('[data-testid="menu-item-collectorList"]').click();
cy.get('[data-testid="menu-item-monitor"] > span').click();
cy.get('[data-testid="dust-monitoring-status-matrix"] > .left > :nth-child(1) > :nth-child(1)').click();
cy.get(':nth-child(1) > span > .el-icon').click();
cy.get(':nth-child(1) > span > .el-icon').click();
/* ==== End Cypress Studio ==== */
});
})
\ No newline at end of file
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
})
/* ==== Test Created with Cypress Studio ==== */
it('test4', function() {
/* ==== Generated with Cypress Studio ==== */
cy.visit('http://localhost:3000');
cy.get('[data-testid="login-username-input"]').click();
cy.get('[data-testid="login-username-input"]').clear('z');
cy.get('[data-testid="login-username-input"]').type('zongheng_admin');
cy.get('[data-testid="login-password-input"]').click();
cy.get('[data-testid="login-password-input"]').click();
cy.get('[data-testid="login-password-input"]').clear('9%#F46vt');
cy.get('[data-testid="login-password-input"]').type('9%#F46vt');
cy.get('[data-testid="login-captcha-input"]').clear('8');
cy.get('[data-testid="login-captcha-input"]').type('8888');
cy.get('[data-testid="login-submit-button"]').click();
cy.get('[data-testid="menu-item-dust-overview"] > span').click();
cy.get('[data-testid="menu-item-monitor"] > span').click();
cy.get('.el-date-editor > [placeholder="开始日期"]').click();
cy.get('.is-left > .el-date-table > tbody > :nth-child(5) > :nth-child(5) > .el-date-table-cell > .el-date-table-cell__text').click();
cy.get('.end-date > .el-date-table-cell > .el-date-table-cell__text').click();
cy.get('.is-plain > span').click();
cy.get('[data-testid="menu-item-collectorList"]').click();
cy.get('[data-testid="menu-item-monitor"] > span').click();
/* ==== End Cypress Studio ==== */
});
})
\ No newline at end of file
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
})
/* ==== Test Created with Cypress Studio ==== */
it('test1', function() {
/* ==== Generated with Cypress Studio ==== */
cy.visit('http://localhost:3000/');
cy.get('[data-testid="login-username-input"]').clear('z');
cy.get('[data-testid="login-username-input"]').type('zongheng_admin');
cy.get('[data-testid="login-password-input"]').click();
cy.get('[data-testid="login-password-input"]').clear('9%#F46vt');
cy.get('[data-testid="login-password-input"]').type('9%#F46vt');
cy.get('[data-testid="login-captcha-input"]').clear('8');
cy.get('[data-testid="login-captcha-input"]').type('8888');
cy.get('.el-checkbox__label').click();
cy.get('.el-checkbox__original').check();
cy.get('[data-testid="login-submit-button"]').click();
cy.get('[data-testid="menu-item-dust-overview"] > span').click();
cy.get('[data-testid="dust-add-button"] > span').click();
cy.get('#el-id-7502-285').click();
cy.get('#el-id-7502-97 > span').click();
cy.get('#el-id-7502-286').clear('1');
cy.get('#el-id-7502-286').type('1');
cy.get('#el-id-7502-287').clear('2');
cy.get('#el-id-7502-287').type('2');
cy.get('#el-id-7502-289').click();
cy.get('.el-dialog__headerbtn > .el-icon > svg').click();
cy.get('[data-testid="dust-search-button"] > span').click();
cy.get(':nth-child(1) > .el-table_1_column_10 > .cell > [data-testid="dust-view-button"]').click();
cy.get('[data-testid="dust-monitoring-status-matrix"] > .left > :nth-child(1) > :nth-child(1)').click();
cy.get('.el-select__suffix > .el-icon > svg').click();
cy.get('#el-id-7502-313 > span').click();
/* ==== End Cypress Studio ==== */
});
})
\ No newline at end of file
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
})
/* ==== Test Created with Cypress Studio ==== */
it('test3', function() {
/* ==== Generated with Cypress Studio ==== */
cy.visit('http://localhost:3000/');
cy.get('[data-testid="login-username-input"]').click();
cy.get('[data-testid="login-username-input"]').click();
cy.get('[data-testid="login-username-input"]').clear('zo');
cy.get('[data-testid="login-username-input"]').type('zongheng_admin');
cy.get('[data-testid="login-password-input"]').click();
cy.get('[data-testid="login-password-input"]').clear('9%#F46vt ');
cy.get('[data-testid="login-password-input"]').type('9%#F46vt ');
cy.get('[data-testid="login-captcha-input"]').clear('8');
cy.get('[data-testid="login-captcha-input"]').type('8888');
cy.get('.el-form').click();
cy.get('.el-form').click();
cy.get('.el-form').click();
cy.get('[data-testid="login-submit-button"]').click();
cy.get('.el-input__suffix-inner > .el-icon > svg').click();
cy.get('[data-testid="login-password-input"]').clear();
cy.get('[data-testid="login-password-input"]').type('9%#F46vt');
cy.get('[data-testid="login-submit-button"] > span').click();
cy.get('[data-testid="menu-item-collectorList"] > span').click();
cy.get('[data-testid="menu-item-dust-overview"] > span').click();
cy.get('[data-testid="menu-item-collectorList"]').click();
cy.get('[data-testid="menu-item-monitor"]').click();
cy.get('.left > :nth-child(1) > :nth-child(11)').click();
cy.get(':nth-child(1) > span > .el-icon').click();
cy.get(':nth-child(2) > span > .el-icon').click();
cy.get(':nth-child(2) > :nth-child(6) > span').click();
cy.get('.el-select__suffix > .el-icon > svg').click();
cy.get('#el-id-3043-155 > span').click();
/* ==== End Cypress Studio ==== */
});
})
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2017 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/*! mochawesome-report-generator 6.2.0 | https://github.com/adamgruber/mochawesome-report-generator */
/** @license React v0.19.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment