healthapp
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
dark 58e71ebcef test: 添加 Playwright 自动化测试脚本 2 days ago
..
screenshots test: 添加 Playwright 自动化测试脚本 2 days ago
README.md test: 添加 Playwright 自动化测试脚本 2 days ago
constitution.test.js test: 添加 Playwright 自动化测试脚本 2 days ago
health-profile-complete.test.js test: 添加 Playwright 自动化测试脚本 2 days ago
profile.test.js test: 添加 Playwright 自动化测试脚本 2 days ago

README.md

自动化测试文档

本目录包含基于 Playwright 的端到端 (E2E) 自动化测试脚本。

目录结构

tests/
├── README.md                         # 本文档
├── constitution.test.js              # 体质分析功能测试
├── profile.test.js                   # "我的"页面功能测试
├── health-profile-complete.test.js   # 健康档案完整功能测试(推荐)
└── screenshots/                      # 测试截图目录
    ├── constitution-result.png       # 体质测试结果截图
    ├── profile-page.png              # 我的页面截图
    ├── hp-basic-*.png                # 基础信息编辑截图
    ├── hp-lifestyle-*.png            # 生活习惯编辑截图
    ├── hp-medical-*.png              # 病史记录添加截图
    └── hp-allergy-*.png              # 过敏记录添加截图

环境准备

1. 安装依赖

# 安装 Playwright
npm install playwright

# 安装浏览器(首次运行)
npx playwright install chromium

2. 启动应用

测试前需要确保前端和后端服务都在运行:

# 终端1: 启动后端服务
cd server
go run main.go

# 终端2: 启动前端服务
cd app
npm start
# 或
npx expo start --web

确保应用可以通过 http://localhost:8081 访问。

运行测试

运行所有测试

# 从项目根目录运行
node tests/constitution.test.js              # 体质分析测试
node tests/profile.test.js                   # "我的"页面测试
node tests/health-profile-complete.test.js   # 健康档案完整测试(推荐)

运行体质分析测试

node tests/constitution.test.js

运行"我的"页面测试

node tests/profile.test.js

运行健康档案完整测试(推荐)

node tests/health-profile-complete.test.js

测试配置

测试脚本中的配置项(位于文件开头):

const APP_URL = "http://localhost:8081"; // 应用地址
const TEST_PHONE = "13800138000"; // 测试手机号
const TEST_CODE = "123456"; // 测试验证码

测试脚本说明

constitution.test.js - 体质分析功能测试

测试流程:

  1. 登录 - 使用测试账号登录应用
  2. 导航 - 进入"体质"Tab
  3. 开始测试 - 点击"开始测试"按钮
  4. 回答问题 - 自动回答 67 道体质问卷题目
  5. 提交 - 提交答案获取结果
  6. 验证结果 - 检查结果页面各元素
  7. 重新测评 - 测试重新测评功能

验证项目:

检查项 说明
登录 验证登录流程正常
导航到体质页面 验证 Tab 导航正常
进入测试页面 验证开始测试按钮可点击
回答所有问题 验证 67 道题目全部完成
提交并查看结果 验证提交后跳转到结果页
体质分析报告标题 验证结果页标题显示
主体质名称 验证显示体质类型名称
体质得分卡片 验证得分区域显示
体质特征卡片 验证特征区域显示
调理建议卡片 验证建议区域显示
咨询 AI 助手按钮 验证功能按钮显示
重新测评按钮 验证重新测评按钮显示
重新测评导航 验证重新测评功能正常

输出示例:

═══════════════════════════════════════════════════════════
          体质分析功能自动化测试
═══════════════════════════════════════════════════════════

打开应用...

【步骤1】检查登录状态...
   执行登录流程...
✓ 登录

【步骤2】导航到体质Tab...
✓ 导航到体质页面

【步骤3】开始体质测试...
✓ 进入测试页面

【步骤4】回答问题...
   回答第 1/67 题...
   回答第 2/67 题...
   ...
   回答第 67/67 题...
   所有题目已回答,准备提交...
✓ 回答所有问题: 共 67 题

【步骤5】提交测试...
✓ 提交并查看结果

【步骤6】验证结果页面内容...
✓ 体质分析报告标题
✓ 主体质名称
✓ 体质得分卡片
✓ 体质特征卡片
✓ 调理建议卡片
✓ 咨询AI助手按钮
✓ 重新测评按钮

   检测到体质类型: 特禀质

【步骤7】测试重新测评功能...
✓ 重新测评导航

═══════════════════════════════════════════════════════════
                    测试结果摘要
═══════════════════════════════════════════════════════════
通过: 13  失败: 0
───────────────────────────────────────────────────────────
✓ 登录
✓ 导航到体质页面
✓ 进入测试页面
✓ 回答所有问题 - 共 67 题
✓ 提交并查看结果
✓ 体质分析报告标题
✓ 主体质名称
✓ 体质得分卡片
✓ 体质特征卡片
✓ 调理建议卡片
✓ 咨询AI助手按钮
✓ 重新测评按钮
✓ 重新测评导航
═══════════════════════════════════════════════════════════

profile.test.js - "我的"页面功能测试

测试流程:

  1. 登录 - 使用测试账号登录
  2. 导航 - 进入"我的"Tab 页面
  3. 用户信息显示 - 验证昵称、手机号、编辑按钮
  4. 编辑昵称 - 打开弹窗、修改昵称、保存
  5. 适老模式 - 验证开关功能
  6. 健康管理菜单 - 验证四个菜单项显示
  7. 健康档案导航 - 跳转到健康档案页面
  8. 健康档案编辑功能 - 测试基础信息/生活习惯编辑、病史/家族病史/过敏记录新增
  9. 用药/治疗记录 - 打开弹窗查看
  10. 关于我们 - 打开弹窗查看
  11. 退出登录 - 点击并验证确认弹窗

验证项目:

检查项 说明
登录 使用测试账号登录
导航到"我的"页面 Tab 导航正常
用户昵称显示 显示用户昵称
手机号显示 显示手机号
编辑按钮显示 编辑图标可见
编辑弹窗打开 点击编辑打开弹窗
保存昵称 修改昵称并保存成功
适老模式卡片显示 适老模式开关可见
适老模式开关 开关可切换
健康档案菜单显示 健康档案菜单可见
用药记录菜单显示 用药记录菜单可见
体质报告菜单显示 体质报告菜单可见
对话历史菜单显示 对话历史菜单可见
健康档案页面打开 导航到健康档案页
基础信息卡片显示 基础信息卡片可见
基础信息编辑弹窗打开 点击编辑按钮打开弹窗
生活习惯卡片显示 生活习惯卡片可见
病史记录卡片显示 病史记录卡片可见
病史记录新增弹窗打开 点击新增按钮打开弹窗
家族病史卡片显示 家族病史卡片可见
过敏记录卡片显示 过敏记录卡片可见
用药记录弹窗打开 点击打开用药记录弹窗
退出登录按钮显示 退出按钮可见

运行命令:

node tests/profile.test.js

health-profile-complete.test.js - 健康档案完整功能测试(推荐)

这是最全面的健康档案测试脚本,覆盖所有可编辑字段的输入和保存验证。

测试范围:

功能模块 测试字段数 测试内容
基础信息 9 个字段 姓名、性别、出生日期、身高、体重、血型、职业、婚姻状况、地区
生活习惯 10 个字段 入睡时间、起床时间、睡眠质量、三餐规律、饮食偏好、日饮水量、运动频率、运动类型、吸烟、饮酒
病史记录 5 个字段 疾病名称、疾病类型、诊断日期、治疗状态、备注
家族病史 3 个字段 亲属关系、疾病名称、备注
过敏记录 4 个字段 过敏类型、过敏原、严重程度、过敏反应描述

测试流程:

  1. 登录 - 使用测试账号登录
  2. 导航 - 进入健康档案页面
  3. 基础信息编辑 - 测试所有 9 个字段的输入和保存
  4. 生活习惯编辑 - 测试所有 10 个字段的输入和保存
  5. 病史记录添加 - 测试添加新病史记录(5 个字段)
  6. 家族病史添加 - 测试添加新家族病史(3 个字段)
  7. 过敏记录添加 - 测试添加新过敏记录(4 个字段)
  8. 数据验证 - 刷新页面后验证所有数据是否正确保存

验证项目:

检查项 说明
导航到健康档案页面 Tab 和菜单导航正常
打开基础信息编辑弹窗 编辑按钮可点击
基础信息-姓名输入 TextInput 输入正常
基础信息-性别选择 SegmentedButtons 选择正常
基础信息-出生日期输入 日期格式输入正常
基础信息-身高/体重输入 数字输入正常
基础信息-血型输入 文本输入正常
基础信息-职业输入 文本输入正常
基础信息-婚姻状况选择 SegmentedButtons 选择正常
基础信息-地区输入 文本输入正常
基础信息-保存成功 API 调用成功,显示提示
基础信息-保存后数据显示 页面正确显示保存的数据
生活习惯-所有字段测试 同上,共 10 个字段
病史记录-添加新记录 弹窗、输入、添加、显示
家族病史-添加新记录 弹窗、输入、添加、显示
过敏记录-添加新记录 弹窗、输入、添加、显示
刷新后数据验证 页面刷新后数据仍然正确

输出示例:

═══════════════════════════════════════════════════════════
          健康档案完整功能自动化测试
═══════════════════════════════════════════════════════════

测试范围:
  - 基础信息: 9个字段(姓名、性别、出生日期、身高、体重、血型、职业、婚姻、地区)
  - 生活习惯: 10个字段(入睡时间、起床时间、睡眠质量、三餐规律、饮食偏好、
               日饮水量、运动频率、运动类型、吸烟、饮酒)
  - 病史记录: 5个字段(疾病名称、疾病类型、诊断日期、治疗状态、备注)
  - 家族病史: 3个字段(亲属关系、疾病名称、备注)
  - 过敏记录: 4个字段(过敏类型、过敏原、严重程度、过敏反应描述)

【步骤2】测试基础信息编辑(9个字段)...
✓ 打开基础信息编辑弹窗
✓ 基础信息-姓名输入
✓ 基础信息-性别选择
✓ 基础信息-出生日期输入
✓ 基础信息-身高输入
✓ 基础信息-体重输入
✓ 基础信息-血型输入
✓ 基础信息-职业输入
✓ 基础信息-婚姻状况选择
✓ 基础信息-地区输入
✓ 基础信息-保存成功 - 显示保存成功提示
✓ 基础信息-保存后姓名显示
✓ 基础信息-保存后地区显示
✓ 基础信息-保存后职业显示

... (更多测试输出)

═══════════════════════════════════════════════════════════
                    测试结果摘要
═══════════════════════════════════════════════════════════
通过: 58  失败: 0
═══════════════════════════════════════════════════════════

运行命令:

node tests/health-profile-complete.test.js

编写新测试

基础模板

const { chromium } = require("playwright");

const APP_URL = "http://localhost:8081";

// 测试结果统计
const testResults = { passed: 0, failed: 0, tests: [] };

function logTest(name, passed, detail = "") {
  const status = passed ? "✓" : "✗";
  console.log(`${status} ${name}${detail ? ": " + detail : ""}`);
  testResults.tests.push({ name, passed, detail });
  if (passed) testResults.passed++;
  else testResults.failed++;
}

async function runTests() {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();

  // 监听错误
  page.on("console", (msg) => {
    if (msg.type() === "error") {
      console.log("[Console Error]", msg.text());
    }
  });

  page.on("pageerror", (error) => {
    console.log("[Page Error]", error.message);
  });

  try {
    await page.goto(APP_URL);
    await page.waitForTimeout(2000);

    // 添加测试步骤...
  } catch (error) {
    console.error("测试中断:", error.message);
    await page.screenshot({ path: "tests/screenshots/error.png" });
  } finally {
    // 打印结果
    console.log(`\n通过: ${testResults.passed}  失败: ${testResults.failed}`);
    await browser.close();
    process.exit(testResults.failed > 0 ? 1 : 0);
  }
}

runTests();

常用操作

点击元素

// 方式1: 文本定位
await page.locator("text=按钮文字").click();

// 方式2: 角色定位
await page.getByRole("button", { name: "提交" }).click();

// 方式3: 坐标点击 (适用于 React Native Web)
const pos = await page.evaluate(() => {
  const el = document.querySelector("text=按钮");
  const rect = el.getBoundingClientRect();
  return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
});
await page.mouse.click(pos.x, pos.y);

// 强制点击 (忽略可见性检查)
await page.locator("text=按钮").click({ force: true });

输入文本

const input = page.locator("input").first();
await input.fill("输入内容");

等待元素

// 等待元素可见
await page.locator("text=内容").waitFor({ state: "visible", timeout: 5000 });

// 检查元素是否可见
const visible = await page
  .locator("text=内容")
  .isVisible({ timeout: 2000 })
  .catch(() => false);

截图

await page.screenshot({ path: "tests/screenshots/截图名.png" });

注意事项

React Native Web 特殊处理

由于 React Native Web 的渲染机制,某些标准选择器可能不起作用:

  1. 优先使用坐标点击 - 通过 evaluate 获取元素位置后用 mouse.click
  2. 使用 force 选项 - 某些元素可能被遮挡,使用 { force: true }
  3. 增加等待时间 - React Native 动画可能需要更长时间完成

测试账号

测试使用的账号:

  • 手机号: 13800138000
  • 验证码: 123456

截图目录

测试截图保存在 tests/screenshots/ 目录下,包括:

  • 测试过程截图
  • 错误截图(当测试失败时自动保存)

CI/CD 集成

可以在 CI/CD 流程中使用 headless 模式运行测试:

// 修改 browser launch 配置
const browser = await chromium.launch({
  headless: true, // 无头模式
});

退出码说明:

  • 0 - 所有测试通过
  • 1 - 存在测试失败