taro-test.md 6.2 KB

Taro小程序测试规范

版本:4.x (已更新为实际使用的测试框架)

概述

本文档定义了出行服务项目中Taro小程序的测试规范。Taro测试使用独立的测试体系,与主项目的Vitest测试框架分离。

测试框架: Jest + @testing-library/react + 自定义Taro组件mock 测试位置: mini/tests/ 目录 测试范围: 组件测试、页面测试、应用级测试、多端测试

安装

在Taro项目根目录(mini/)下安装测试依赖:

# 进入mini目录
cd mini

# 安装测试框架
npm i jest @testing-library/react @testing-library/jest-dom --save-dev
npm i @types/jest jest-environment-jsdom ts-jest --save-dev

注意: Taro 4 项目使用 Jest + @testing-library/react 进行测试,无需安装 @tarojs/test-utils-react

配置

Jest配置

在Taro项目根目录(mini/)添加文件 jest.config.js

// mini/jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],
  moduleNameMapping: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\.(css|less|scss|sass)$': 'identity-obj-proxy',
    '\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/tests/__mocks__/fileMock.js'
  },
  testMatch: [
    '<rootDir>/tests/**/*.spec.{ts,tsx}',
    '<rootDir>/tests/**/*.test.{ts,tsx}'
  ],
  collectCoverageFrom: [
    'src/**/*.{ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/index.{ts,tsx}',
    '!src/**/*.stories.{ts,tsx}'
  ],
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov', 'html'],
  testPathIgnorePatterns: [
    '/node_modules/',
    '/dist/',
    '/coverage/'
  ],
  transform: {
    '^.+\\.(ts|tsx)$': 'babel-jest',
    '^.+\\.(js|jsx)$': 'babel-jest'
  },
  transformIgnorePatterns: [
    '/node_modules/(?!(swiper|@tarojs)/)'
  ],
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json']
}

package.json脚本配置

mini/package.json 中添加测试脚本:

{
  "scripts": {
    "test": "jest",
    "test:h5": "export TARO_ENV_JEST=h5 && jest",
    "test:weapp": "export TARO_ENV_JEST=weapp && jest",
    "test:coverage": "jest --coverage"
  }
}

配置文件参考 Jest官网

编写测试用例

组件级别测试

// tests/components/button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import Button from '../../src/components/Button'

describe('Button Component', () => {
  it('应该渲染按钮并响应点击事件', () => {
    const handleClick = jest.fn()

    render(<Button onClick={handleClick}>点击我</Button>)

    const button = screen.getByRole('button', { name: '点击我' })
    expect(button).toBeInTheDocument()

    fireEvent.click(button)
    expect(handleClick).toHaveBeenCalledTimes(1)
  })
})

页面级别测试

// tests/pages/index.test.tsx
import { render, screen } from '@testing-library/react'
import Index from '../../src/pages/index'

describe('Index Page', () => {
  it('应该渲染首页内容', () => {
    render(<Index />)

    expect(screen.getByText('欢迎使用出行服务')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: '开始使用' })).toBeInTheDocument()
  })
})

运行测试

# 在mini目录下执行
npm run test

多端测试

对于小程序的测试,我们提供了环境变量对 Jest 环境进行区分:TARO_ENV_JEST,我们可以在调用 jest 测试时设置对应的环境变量

// package.json
{
  "scripts": {
    "test": "jest",
    "test:h5": "export TARO_ENV_JEST=h5 && jest",
    "test:weapp": "export TARO_ENV_JEST=weapp && jest"
  }
}

这里会有几点差异:

环境差异

这里会将运行代码中的 process.env.TARO_ENV 切换为 TARO_ENV_JEST 的值,主要用于一些"环境判断",比如下面的代码将会在 test:weapp 执行:

if (process.env.TARO_ENV === 'weapp') {
  // ....setState(....)
  console.log('this is weapp')
}

标签差异

Taro 组件会根据环境变量渲染不同的标签,例如:

// 在 H5 环境中
<View className="cls">
  <Image src="xxx" />
</View>

// 在微信小程序环境中会渲染为
<view class="cls">
  <image src="xxx" />
</view>

模拟小程序 API

对于小程序特有的生命周期和 API,我们推荐以下做法:

// 模拟 Taro API
jest.mock('@tarojs/taro', () => ({
  navigateTo: jest.fn(),
  request: jest.fn(),
  getStorage: jest.fn(),
  setStorage: jest.fn(),
}))

// 在测试中使用模拟的 API
import Taro from '@tarojs/taro'

describe('小程序功能', () => {
  it('应该调用导航API', () => {
    Taro.navigateTo({ url: '/pages/index' })
    expect(Taro.navigateTo).toHaveBeenCalledWith({ url: '/pages/index' })
  })
})

项目特定测试指导

测试目录结构

mini/
├── tests/
│   ├── setup.ts                    # 测试设置文件
│   ├── components/                 # 组件测试
│   │   ├── ui/                    # UI组件测试
│   │   │   ├── button.test.tsx
│   │   │   ├── form.test.tsx
│   │   │   └── tab-bar.test.tsx
│   ├── pages/                      # 页面测试
│   │   ├── index.test.tsx         # 首页测试
│   │   ├── login.test.tsx         # 登录页测试
│   │   ├── profile.test.tsx       # 个人中心测试
│   │   └── explore.test.tsx       # 探索页测试
│   └── utils/                      # 工具函数测试
│       ├── auth.test.ts
│       └── minio.test.ts

测试覆盖率目标

  • 组件测试: ≥ 70%
  • 页面测试: ≥ 60%
  • 工具函数: ≥ 80%
  • 关键业务逻辑: 100%

测试执行

# 在mini目录下执行
cd mini

# 运行所有测试
npm test

# 运行H5环境测试
npm run test:h5

# 运行微信小程序环境测试
npm run test:weapp

# 生成覆盖率报告
npm run test:coverage

与主项目的关系

  • Taro测试体系完全独立于主项目的Vitest测试
  • 两者使用不同的测试框架和配置
  • 测试执行需要分别进入对应目录
  • CI/CD流水线需要分别配置两个项目的测试任务