ソースを参照

📝 docs(testing): 更新Taro小程序测试策略文档

- 添加版本4.0记录,更新日期为2025-10-31
- 重构Taro小程序测试体系结构,新增单元测试类别
- 详细说明测试基础设施,包括配置、工具和Mock文件
- 更新测试命令为pnpm,添加特定测试文件运行方式
- 添加最新测试模式和最佳实践,包含代码示例
- 完善测试代码规范,更新测试命名约定
- 更新测试依赖版本和下次评审日期至2025-12-31
yourname 3 ヶ月 前
コミット
1807c1c9e2
1 ファイル変更142 行追加46 行削除
  1. 142 46
      docs/architecture/testing-strategy.md

+ 142 - 46
docs/architecture/testing-strategy.md

@@ -3,6 +3,7 @@
 ## 版本信息
 ## 版本信息
 | 版本 | 日期 | 描述 | 作者 |
 | 版本 | 日期 | 描述 | 作者 |
 |------|------|------|------|
 |------|------|------|------|
+| 4.0 | 2025-10-31 | 基于实际测试结构更新Taro小程序测试策略,添加最新测试模式 | Winston |
 | 3.2 | 2025-10-20 | 修正Taro测试工具引用,更新为实际使用的测试框架 | Winston |
 | 3.2 | 2025-10-20 | 修正Taro测试工具引用,更新为实际使用的测试框架 | Winston |
 | 3.1 | 2025-10-16 | 修正测试路径描述,更新Taro测试说明 | Winston |
 | 3.1 | 2025-10-16 | 修正测试路径描述,更新Taro测试说明 | Winston |
 | 3.0 | 2025-10-15 | 更新为出行服务项目测试策略 | Winston |
 | 3.0 | 2025-10-15 | 更新为出行服务项目测试策略 | Winston |
@@ -50,31 +51,44 @@
 
 
 ### Taro小程序测试体系 (独立项目)
 ### Taro小程序测试体系 (独立项目)
 
 
-**注意**: Taro小程序项目位于 `mini/` 目录,是独立的项目结构,拥有自己的测试配置和运行方式。
+**注意**: Taro小程序项目位于 `mini/` 目录,是独立的项目结构,拥有自己的测试配置和运行方式。基于实际测试结构分析,当前测试体系如下:
 
 
 #### 组件测试 (Component Tests)
 #### 组件测试 (Component Tests)
 - **范围**: Taro小程序组件
 - **范围**: Taro小程序组件
 - **目标**: 验证组件渲染和交互行为
 - **目标**: 验证组件渲染和交互行为
-- **位置**: `mini/tests/**/*.test.{ts,tsx}`
+- **位置**: `mini/tests/components/**/*.test.{ts,tsx}`
 - **框架**: Jest + @testing-library/react + 自定义Taro组件mock
 - **框架**: Jest + @testing-library/react + 自定义Taro组件mock
 - **覆盖率目标**: ≥ 70%
 - **覆盖率目标**: ≥ 70%
 - **执行频率**: 每次组件变更
 - **执行频率**: 每次组件变更
+- **示例文件**: [Button.test.tsx](mini/tests/components/Button.test.tsx)
 
 
 #### 页面测试 (Page Tests)
 #### 页面测试 (Page Tests)
-- **范围**: 小程序页面级测试
-- **目标**: 验证页面生命周期和路由
+- **范围**: 小程序页面级测试,包含完整业务逻辑
+- **目标**: 验证页面生命周期、路由、状态管理和API集成
 - **位置**: `mini/tests/pages/**/*.test.{ts,tsx}`
 - **位置**: `mini/tests/pages/**/*.test.{ts,tsx}`
-- **框架**: Jest + @testing-library/react + 自定义Taro组件mock
+- **框架**: Jest + @testing-library/react + React Query + Taro API mock
 - **覆盖率目标**: ≥ 60%
 - **覆盖率目标**: ≥ 60%
 - **执行频率**: 每次页面变更
 - **执行频率**: 每次页面变更
+- **最新示例**:
+  - [order-page.test.tsx](mini/tests/pages/order-page.test.tsx) - 订单页面完整测试
+  - [profile.test.tsx](mini/tests/pages/profile.test.tsx) - 个人中心页面测试
+
+#### 单元测试 (Unit Tests)
+- **范围**: 工具函数、业务逻辑、状态管理
+- **目标**: 验证独立业务逻辑单元的正确性
+- **位置**: `mini/tests/unit/**/*.test.{ts,tsx}`
+- **框架**: Jest + 自定义测试工具
+- **覆盖率目标**: ≥ 80%
+- **执行频率**: 每次业务逻辑变更
+- **示例文件**: [payment.test.ts](mini/tests/unit/payment.test.ts)
 
 
-#### 多端测试 (Multi-Platform Tests)
-- **范围**: 不同小程序平台测试
-- **目标**: 验证多端兼容性
-- **位置**: `mini/tests/platforms/**/*.test.{ts,tsx}`
-- **框架**: Jest + 环境变量区分平台
-- **覆盖率目标**: 关键功能100%
-- **执行频率**: 每次平台相关变更
+#### 测试基础设施
+- **测试配置**: `mini/tests/setup.ts` - 完整的Taro组件和API mock
+- **测试工具**: `mini/tests/utils.ts` - 测试辅助函数和mock数据生成器
+- **Mock文件**: `mini/tests/__mocks__/` - Taro API和组件mock
+  - `taroMock.ts` - 统一的Taro API mock,包含所有常用API
+  - `taroMock.ts` - 通过jest.config.js的moduleNameMapper重定向@tarojs/taro
+- **快照**: `mini/tests/__snapshots__/` - UI快照测试
 
 
 ## 测试环境配置
 ## 测试环境配置
 
 
@@ -211,16 +225,20 @@ npm run test:coverage
 cd mini
 cd mini
 
 
 # 运行所有Taro测试
 # 运行所有Taro测试
-npm test
+pnpm test
 
 
 # 运行H5环境测试
 # 运行H5环境测试
-npm run test:h5
+pnpm run test:h5
 
 
 # 运行微信小程序环境测试
 # 运行微信小程序环境测试
-npm run test:weapp
+pnpm run test:weapp
 
 
 # 生成覆盖率报告
 # 生成覆盖率报告
-npm run test:coverage
+pnpm run test:coverage
+
+# 运行特定测试文件
+pnpm test -- order-page.test.tsx
+pnpm test -- profile.test.tsx
 ```
 ```
 
 
 ### CI/CD流水线测试
 ### CI/CD流水线测试
@@ -274,43 +292,117 @@ npm run test:coverage
 - **autocannon**: API性能测试
 - **autocannon**: API性能测试
 - **Playwright**: E2E性能监控
 - **Playwright**: E2E性能监控
 
 
-## 测试文档标准
+## 最新测试模式和最佳实践
+
+### Taro小程序测试模式
+
+#### 页面级集成测试模式
+基于最新的 [order-page.test.tsx](mini/tests/pages/order-page.test.tsx) 和 [profile.test.tsx](mini/tests/pages/profile.test.tsx) 测试文件,推荐以下测试模式:
+
+```typescript
+// 1. 完整的测试环境设置
+const createTestQueryClient = () => new QueryClient({
+  defaultOptions: {
+    queries: { retry: false },
+  },
+})
+
+// 2. 组件包装器
+const Wrapper = ({ children }: { children: React.ReactNode }) => (
+  <QueryClientProvider client={createTestQueryClient()}>
+    {children}
+  </QueryClientProvider>
+)
+
+// 3. 完整的Mock策略 - 使用统一的taroMock
+import taroMock from '../../tests/__mocks__/taroMock'
+
+// 在测试中直接使用导入的mock函数
+taroMock.showToast.mockClear()
+taroMock.navigateTo.mockClear()
+
+// 4. 测试数据工厂
+const mockRouteData = {
+  id: 1,
+  name: '测试路线',
+  price: 100,
+  vehicleType: '商务车'
+}
+```
+
+#### 业务逻辑测试覆盖
+- **订单流程**: 支付验证、乘客管理、价格计算
+- **用户交互**: 按钮点击、表单验证、状态切换
+- **API集成**: React Query hooks、错误处理、加载状态
+- **多端兼容**: H5和小程序环境适配
+
+#### Mock策略说明
+- **统一Mock**: 使用 `taroMock.ts` 统一管理所有Taro API mock
+- **模块重定向**: 通过jest.config.js的moduleNameMapper将@tarojs/taro重定向到taroMock
+- **函数级控制**: 每个mock函数都可以独立控制和验证调用情况
 
 
 ### 测试代码规范
 ### 测试代码规范
 ```typescript
 ```typescript
-// 良好的测试示例
-describe('UserService', () => {
-  describe('createUser()', () => {
-    it('应该创建新用户并返回用户对象', async () => {
-      // Arrange
-      const userData = { username: 'testuser', email: 'test@example.com' };
-
-      // Act
-      const result = await userService.createUser(userData);
-
-      // Assert
-      expect(result).toHaveProperty('id');
-      expect(result.username).toBe('testuser');
-      expect(result.email).toBe('test@example.com');
-    });
-
-    it('应该拒绝重复的用户名', async () => {
-      // Arrange
-      const existingUser = await createTestUser({ username: 'existing' });
-
-      // Act & Assert
-      await expect(
-        userService.createUser({ username: 'existing', email: 'new@example.com' })
-      ).rejects.toThrow('用户名已存在');
-    });
-  });
-});
+// 良好的测试示例 - 基于最新测试文件
+describe('OrderPage', () => {
+  beforeEach(() => {
+    jest.clearAllMocks()
+    // 设置测试数据
+  })
+
+  it('应该正确渲染订单页面', () => {
+    render(
+      <Wrapper>
+        <OrderPage />
+      </Wrapper>
+    )
+
+    expect(screen.getByTestId('order-navbar')).toBeInTheDocument()
+    expect(screen.getByTestId('activity-name')).toHaveTextContent('测试活动')
+  })
+
+  it('应该处理支付验证逻辑', async () => {
+    render(
+      <Wrapper>
+        <OrderPage />
+      </Wrapper>
+    )
+
+    const payButton = screen.getByTestId('pay-button')
+    fireEvent.click(payButton)
+
+    await waitFor(() => {
+      expect(taroMock.showToast).toHaveBeenCalledWith({
+        title: '请先获取手机号',
+        icon: 'none',
+        duration: 2000
+      })
+    })
+  })
+
+  it('应该处理不同出行模式', () => {
+    // 测试拼车和包车模式
+    mockUseRouter.mockReturnValue({
+      params: { type: 'carpool' }
+    })
+
+    render(
+      <Wrapper>
+        <OrderPage />
+      </Wrapper>
+    )
+
+    expect(screen.getByTestId('service-type')).toHaveTextContent('班次信息')
+  })
+})
 ```
 ```
 
 
 ### 测试命名约定
 ### 测试命名约定
-- **文件名**: `[module].test.ts` 或 `[module].integration.test.ts`
+- **文件名**: `[page/component].test.tsx` 或 `[feature].test.ts`
 - **描述**: 使用「应该...」格式描述测试行为
 - **描述**: 使用「应该...」格式描述测试行为
 - **用例**: 明确描述测试场景和预期结果
 - **用例**: 明确描述测试场景和预期结果
+- **测试数据**: 使用工厂函数创建测试数据
+- **Mock策略**: 完整的API和组件mock覆盖
 
 
 ## 监控和报告
 ## 监控和报告
 
 
@@ -338,10 +430,14 @@ describe('UserService', () => {
 - **Testing Library**: 16.3.0
 - **Testing Library**: 16.3.0
 - **Playwright**: 1.55.0
 - **Playwright**: 1.55.0
 - **hono/testing**: 内置(Hono 4.8.5)
 - **hono/testing**: 内置(Hono 4.8.5)
+- **Jest**: 29.7.0 (Taro小程序)
+- **React Testing Library**: 16.3.0 (Taro小程序)
+- **React Query**: 5.8.4 (Taro小程序)
 
 
 ### 更新日志
 ### 更新日志
 | 日期 | 版本 | 描述 |
 | 日期 | 版本 | 描述 |
 |------|------|------|
 |------|------|------|
+| 2025-10-31 | 4.0 | 基于实际测试结构更新Taro小程序测试策略,添加最新测试模式 |
 | 2025-10-20 | 3.2 | 修正Taro测试工具引用,更新为实际使用的测试框架 |
 | 2025-10-20 | 3.2 | 修正Taro测试工具引用,更新为实际使用的测试框架 |
 | 2025-10-16 | 3.1 | 修正测试路径描述,更新Taro测试说明 |
 | 2025-10-16 | 3.1 | 修正测试路径描述,更新Taro测试说明 |
 | 2025-10-15 | 3.0 | 更新为出行服务项目测试策略 |
 | 2025-10-15 | 3.0 | 更新为出行服务项目测试策略 |
@@ -353,4 +449,4 @@ describe('UserService', () => {
 ---
 ---
 
 
 **文档状态**: 正式版
 **文档状态**: 正式版
-**下次评审**: 2025-12-19
+**下次评审**: 2025-12-31