最终验证和AI重点测试:项目开发周期的最终环节

现在,我们确认开发已经到了最终阶段。经过我们同大模型的确认,有关任务除寻找测试数据存在困难外已全部完成。但这并不影响我们执行功能性测试。我们大量使用脚本进行了自动化测试,对于重中之重的AI模块我们用了一点真实数据进行了单独的手动测试。


确认开发全部完毕

由于任务书中明确,HTML和PDF两种形式我们预计只实现一种,时间原因我们没有找到大量的可测试数据,因此现在可以宣告开发任务已经顺利结束。

AI相关功能验证

涉AI功能作为整个项目的亮点,我们选择了用一些真实的截图、图片进行手动验证。不再多说,放截图。

AI日报

AI月报(支持手动生成,周报略)

AI饮食记录图片识别

AI运动记录截图识别

AI睡眠记录截图识别

自动化测试文档

我们的队友可能也进行了一些测试,但这一测试工作我们之间独立进行,以求尽可能多地发现漏洞和问题。

📋 目录

  1. 测试架构概览
  2. 后端测试
  3. 前端测试
  4. E2E 端到端测试
  5. 如何运行测试
  6. CI/CD 流水线
  7. 测试覆盖率

测试架构概览

AI-HEALTH/ ├── backend/ │ └── src/test/java/com/aihealth/ │ ├── BaseServiceTest.java # Service 层测试基类 │ ├── BaseControllerTest.java # Controller 层测试基类 │ ├── TestDataFactory.java # 测试数据工厂 │ ├── service/ # Service 层单元测试 │ │ ├── UserServiceTest.java │ │ ├── WeightRecordServiceTest.java │ │ ├── SleepRecordServiceTest.java │ │ ├── FoodRecordServiceTest.java │ │ ├── MoodRecordServiceTest.java │ │ ├── WorkoutServiceTest.java │ │ └── NotificationServiceTest.java │ ├── repository/ # Repository 集成测试 │ │ ├── UserRepositoryTest.java │ │ ├── WeightRecordRepositoryTest.java │ │ ├── SleepRecordRepositoryTest.java │ │ └── FoodRecordRepositoryTest.java │ ├── controller/ # Controller 集成测试 │ │ ├── UserControllerTest.java │ │ └── WeightRecordControllerTest.java │ └── util/ │ └── JwtUtilTest.java # JWT 工具测试 ├── frontend/ │ ├── src/__tests__/ │ │ ├── setup.js # Vitest 全局设置 │ │ ├── stores/ # Pinia Store 测试 │ │ │ ├── userStore.test.js │ │ │ ├── themeStore.test.js │ │ │ └── healthStore.test.js │ │ ├── components/ # Vue 组件测试 │ │ │ ├── StatCard.test.js │ │ │ └── Login.test.js │ │ ├── services/ # API 服务测试 │ │ │ └── api.test.js │ │ ├── router/ # 路由测试 │ │ │ └── router.test.js │ │ └── utils/ # 工具函数测试 │ │ └── commonUtils.test.js │ ├── e2e/ # Playwright E2E 测试 │ │ ├── auth.spec.js │ │ ├── health-records.spec.js │ │ └── settings.spec.js │ ├── vitest.config.js # Vitest 配置 │ └── playwright.config.js # Playwright 配置 ├── .github/workflows/ci.yml # GitHub Actions CI ├── run-tests.bat # Windows 一键测试脚本 └── run-tests.sh # Linux/Mac 一键测试脚本

后端测试

技术栈

组件用途
JUnit 5测试框架
MockitoService 层 Mock
AssertJ流式断言
Spring Boot Test集成测试上下文
H2 Database内存数据库
MockMvcREST 端点测试
REST AssuredAPI 集成测试

测试层次

┌──────────────────────────────────────┐ │ Controller 集成测试 │ ← @SpringBootTest + MockMvc │ (UserControllerTest, etc.) │ 完整 Spring 上下文 + H2 ├──────────────────────────────────────┤ │ Service 单元测试 │ ← @ExtendWith(MockitoExtension) │ (UserServiceTest, etc.) │ Mock Repository,测业务逻辑 ├──────────────────────────────────────┤ │ Repository 集成测试 │ ← @DataJpaTest + H2 │ (UserRepositoryTest, etc.) │ 测 JPA 查询正确性 ├──────────────────────────────────────┤ │ Util 单元测试 │ ← 纯 JUnit 5 │ (JwtUtilTest) │ 无 Spring 依赖 └──────────────────────────────────────┘

测试覆盖的功能

  • ✅ 用户注册/登录/信息获取/更新/修改密码
  • ✅ JWT 令牌生成/解析/验证
  • ✅ 体重记录 CRUD + 批量删除 + 日期范围查询
  • ✅ 睡眠记录 CRUD + 年月筛选 + 时间范围查询
  • ✅ 食物记录 CRUD + FoodItem 级联 + 批量删除
  • ✅ 情绪记录 CRUD + 批量操作
  • ✅ 锻炼记录 CRUD + WorkoutItem 级联
  • ✅ 通知创建/获取/标记已读
  • ✅ 异常处理与错误码

前端测试

技术栈

组件用途
Vitest测试运行器(兼容 Vite)
@vue/test-utilsVue 组件挂载与交互
happy-dom轻量 DOM 模拟
Pinia状态管理测试

测试覆盖的功能

  • Pinia Stores: userStore(认证)、themeStore(主题)、healthStore(健康数据)
  • Vue 组件: StatCard(统计卡片)、Login(登录表单)
  • API 服务层: 所有 API 调用函数(food/exercise/sleep/weight/mood)
  • 路由配置: 所有 12 条路由映射验证
  • 工具函数: 日期格式化、Base64 转换、ID 清理、照片解析

E2E 端到端测试

技术栈

组件用途
Playwright跨浏览器 E2E 测试
Chromium / Firefox / Mobile Chrome多平台覆盖

测试覆盖的功能

  • 认证流程: 登录页面加载、未登录重定向
  • 页面可访问性: 所有 12 个页面能否正常加载
  • 健康记录管理: 食物/运动/睡眠/体重/情绪页面
  • 用户设置: 设置页、个人资料页
  • 仪表盘: 欢迎信息展示
  • 响应式设计: 移动端(375px)、平板(768px)、桌面(1920px)

如何运行测试

前置条件

  • Java 21+ Maven(后端)
  • Node.js 20+(前端)
  • 前端依赖已安装:cd frontend && npm install

运行全部测试(推荐)

Windows:

.\run-tests.bat

Linux/Mac:

chmod+x run-tests.sh ./run-tests.sh

分别运行

后端测试
# 运行所有后端测试cdbackend mvntest-Dspring.profiles.active=test# 只运行 Service 层测试mvntest-Dtest="com.aihealth.service.*"# 只运行 Controller 集成测试mvntest-Dtest="com.aihealth.controller.*"# 只运行 Repository 测试mvntest-Dtest="com.aihealth.repository.*"# 运行特定测试类mvntest-Dtest="UserServiceTest"
前端单元测试
cdfrontend# 运行所有测试npmtest# 监听模式(开发时推荐)npmrun test:watch# 生成覆盖率报告npmrun test:coverage# 运行特定测试文件npx vitest run src/__tests__/stores/userStore.test.js
E2E 测试
cdfrontend# 确保前端 dev server 已启动npmrun dev# 另一个终端中运行 E2Enpx playwrighttest# UI 模式(可视化调试)npmrun test:e2e:ui# 只运行特定 specnpx playwrighttestauth.spec.js

CI/CD 流水线

GitHub Actions

推送代码到maindevelop分支时自动触发。

流水线阶段:

  1. 后端测试— Maven 运行单元 + 集成测试
  2. 前端测试— Vitest 运行组件 + Store + 工具测试
  3. E2E 测试— Playwright 多浏览器测试
  4. 测试摘要— 汇总所有结果

配置文件:.github/workflows/ci.yml

测试结果制品

  • 📊 后端:backend/target/surefire-reports/
  • 📊 前端:frontend/coverage/
  • 📊 E2E:frontend/playwright-report/
  • 🖼️ 失败截图:frontend/test-results/

测试覆盖率

后端覆盖率

cdbackend mvntestjacoco:report# 报告位置: backend/target/site/jacoco/index.html

前端覆盖率

cdfrontendnpmrun test:coverage# 报告位置: frontend/coverage/index.html

这是其中一次测试的运行结果,尽管有鲜红的1 failed,大模型还是宣告测试是通过的,相信是存在一些人为控制不了的因素,经查不影响正常使用,不排除是脚本问题


编写新测试的最佳实践

  1. 命名规范:{ClassName}Test.java(后端) 或{name}.test.js(前端)
  2. 使用 TestDataFactory: 复用测试数据构建方法
  3. 每个测试只验证一个行为: 遵循 AAA 模式 (Arrange → Act → Assert)
  4. @DisplayName / describe: 使用中文描述测试意图
  5. Mock 外部依赖: Service 测试 Mock Repository; API 测试 Mock Axios
  6. 清理测试数据: 使用@BeforeEachbeforeEach重置状态

由此,开发测试工作结束,但愿验收可以通过。