---
title: 测试文档
order: 1
category: sub-component
---

# ToolBar 测试文档

## 测试概述

本文档描述 ToolBar 组件的测试策略和测试用例。

## 测试框架

- **测试框架**: Jest
- **测试工具**: React Testing Library
- **快照测试**: Jest Snapshot

## 测试策略

### 1. 单元测试

测试组件的基本功能和边界情况。

### 2. 快照测试

确保组件渲染结果的一致性。

### 3. 集成测试

测试组件与父组件 PisellGridPro 的集成情况。

## 测试用例

### 基础渲染测试

#### TC-001: 默认渲染

**测试目的**: 验证组件可以正常渲染

```
import { render } from '@testing-library/react';
import Toolbar from '../index';

test('TC-001: should render without crash', () => {
  const { container } = render(<Toolbar />);
  expect(container.querySelector('.pisell-grid-pro-toolbar')).toBeInTheDocument();
});
```

**预期结果**: 组件正常渲染，不抛出错误

---

#### TC-002: 渲染 tabs 插槽

**测试目的**: 验证 tabs 插槽内容正确渲染

```
test('TC-002: should render tabs slot', () => {
  const { getByText } = render(
    <Toolbar tabs={<div>Tab Content</div>} />
  );
  expect(getByText('Tab Content')).toBeInTheDocument();
});
```

**预期结果**: tabs 内容正确显示

---

#### TC-003: 渲染 topLeft 和 topRight

**测试目的**: 验证上方左右插槽内容正确渲染

```
test('TC-003: should render topLeft and topRight', () => {
  const { getByText } = render(
    <Toolbar
      topLeft={<div>Left Content</div>}
      topRight={<div>Right Content</div>}
    />
  );
  expect(getByText('Left Content')).toBeInTheDocument();
  expect(getByText('Right Content')).toBeInTheDocument();
});
```

**预期结果**: 左右内容都正确显示

---

#### TC-004: 渲染 bottomLeft 和 bottomRight

**测试目的**: 验证下方左右插槽内容正确渲染

```
test('TC-004: should render bottomLeft and bottomRight', () => {
  const { getByText } = render(
    <Toolbar
      bottomLeft={<div>Bottom Left</div>}
      bottomRight={<div>Bottom Right</div>}
    />
  );
  expect(getByText('Bottom Left')).toBeInTheDocument();
  expect(getByText('Bottom Right')).toBeInTheDocument();
});
```

**预期结果**: 下方左右内容都正确显示

---

#### TC-005: 渲染所有插槽

**测试目的**: 验证所有插槽可以同时渲染

```
test('TC-005: should render all slots', () => {
  const { getByText } = render(
    <Toolbar
      tabs={<div>Tabs</div>}
      topLeft={<div>Top Left</div>}
      topRight={<div>Top Right</div>}
      bottomLeft={<div>Bottom Left</div>}
      bottomRight={<div>Bottom Right</div>}
    />
  );
  expect(getByText('Tabs')).toBeInTheDocument();
  expect(getByText('Top Left')).toBeInTheDocument();
  expect(getByText('Top Right')).toBeInTheDocument();
  expect(getByText('Bottom Left')).toBeInTheDocument();
  expect(getByText('Bottom Right')).toBeInTheDocument();
});
```

**预期结果**: 所有插槽内容都正确显示

---

### 条件渲染测试

#### TC-006: 不渲染空行（tabs）

**测试目的**: 验证 tabs 为空时不渲染对应行

```
test('TC-006: should not render tabs row when tabs is empty', () => {
  const { container } = render(<Toolbar />);
  const rows = container.querySelectorAll('.pisell-grid-pro-toolbar-row');
  expect(rows.length).toBe(0);
});
```

**预期结果**: 没有渲染任何行

---

#### TC-007: 不渲染空行（top）

**测试目的**: 验证 topLeft 和 topRight 都为空时不渲染对应行

```
test('TC-007: should not render top row when both topLeft and topRight are empty', () => {
  const { container } = render(<Toolbar />);
  const toolbarRows = container.querySelectorAll('.toolbar-row');
  expect(toolbarRows.length).toBe(0);
});
```

**预期结果**: 不渲染 top 行

---

#### TC-008: 只有 topLeft 时渲染 top 行

**测试目的**: 验证只有 topLeft 有内容时也会渲染 top 行

```
test('TC-008: should render top row when only topLeft has content', () => {
  const { getByText } = render(
    <Toolbar topLeft={<div>Left Only</div>} />
  );
  expect(getByText('Left Only')).toBeInTheDocument();
});
```

**预期结果**: top 行正常渲染

---

#### TC-009: 只有 topRight 时渲染 top 行

**测试目的**: 验证只有 topRight 有内容时也会渲染 top 行

```
test('TC-009: should render top row when only topRight has content', () => {
  const { getByText } = render(
    <Toolbar topRight={<div>Right Only</div>} />
  );
  expect(getByText('Right Only')).toBeInTheDocument();
});
```

**预期结果**: top 行正常渲染

---

### 样式测试

#### TC-010: 自定义 className

**测试目的**: 验证自定义 className 正确应用

```
test('TC-010: should apply custom className', () => {
  const { container } = render(<Toolbar className="custom-class" />);
  expect(container.querySelector('.custom-class')).toBeInTheDocument();
  expect(container.querySelector('.pisell-grid-pro-toolbar')).toBeInTheDocument();
});
```

**预期结果**: 同时包含默认类名和自定义类名

---

#### TC-011: 自定义 style

**测试目的**: 验证自定义 style 正确应用

```
test('TC-011: should apply custom style', () => {
  const customStyle = { backgroundColor: 'red', padding: '20px' };
  const { container } = render(<Toolbar style={customStyle} />);
  const toolbar = container.querySelector('.pisell-grid-pro-toolbar');
  expect(toolbar).toHaveStyle('background-color: red');
  expect(toolbar).toHaveStyle('padding: 20px');
});
```

**预期结果**: 自定义样式正确应用

---

### 复杂内容测试

#### TC-012: 渲染复杂 ReactNode

**测试目的**: 验证可以渲染复杂的 React 元素

```
test('TC-012: should render complex ReactNode', () => {
  const ComplexNode = () => (
    <div>
      <button>Button 1</button>
      <button>Button 2</button>
      <input placeholder="Search" />
    </div>
  );

  const { getByPlaceholderText, getByText } = render(
    <Toolbar topLeft={<ComplexNode />} />
  );

  expect(getByText('Button 1')).toBeInTheDocument();
  expect(getByText('Button 2')).toBeInTheDocument();
  expect(getByPlaceholderText('Search')).toBeInTheDocument();
});
```

**预期结果**: 复杂内容正确渲染

---

### 快照测试

#### TC-013: 空组件快照

**测试目的**: 确保空组件渲染结果一致性

```
test('TC-013: should match snapshot when empty', () => {
  const { container } = render(<Toolbar />);
  expect(container).toMatchSnapshot();
});
```

---

#### TC-014: 完整组件快照

**测试目的**: 确保完整组件渲染结果一致性

```
test('TC-014: should match snapshot with all slots', () => {
  const { container } = render(
    <Toolbar
      tabs={<div>Tabs</div>}
      topLeft={<div>Top Left</div>}
      topRight={<div>Top Right</div>}
      bottomLeft={<div>Bottom Left</div>}
      bottomRight={<div>Bottom Right</div>}
    />
  );
  expect(container).toMatchSnapshot();
});
```

---

## 测试覆盖率要求

- **语句覆盖率**: ≥ 90%
- **分支覆盖率**: ≥ 85%
- **函数覆盖率**: 100%
- **行覆盖率**: ≥ 90%

## 运行测试

### 运行所有测试

```bash
pnpm test ToolBar
```

### 运行单个测试文件

```bash
pnpm test ToolBar/index.test.tsx
```

### 查看测试覆盖率

```bash
pnpm test:coverage ToolBar
```

### 更新快照

```bash
pnpm test:update-snapshot ToolBar
```

## 测试清单

在提交代码前，请确保：

- [ ] 所有测试用例通过
- [ ] 代码覆盖率达标
- [ ] 快照测试通过
- [ ] 没有 console 警告或错误
- [ ] TypeScript 类型检查通过
- [ ] ESLint 检查通过

## 手动测试

除了自动化测试，还需要进行以下手动测试：

### 1. 视觉测试

- [ ] 在不同浏览器下渲染正常（Chrome、Firefox、Safari）
- [ ] 在不同屏幕尺寸下布局正常
- [ ] 间距符合设计稿要求

### 2. 交互测试

- [ ] 插槽内的按钮可以正常点击
- [ ] 插槽内的输入框可以正常输入
- [ ] 插槽内的下拉框可以正常展开

### 3. 集成测试

- [ ] 在 PisellGridPro 中使用正常
- [ ] 与其他组件配合使用正常
- [ ] 在实际业务场景中使用正常

## 常见问题

### Q1: 测试用例失败怎么办？

1. 检查测试代码是否正确
2. 检查组件实现是否有问题
3. 查看错误信息，定位问题
4. 必要时更新快照

### Q2: 如何提高测试覆盖率？

1. 添加边界情况测试
2. 测试所有条件分支
3. 测试异常情况
4. 使用覆盖率报告定位未覆盖代码

### Q3: 快照测试经常失败怎么办？

1. 检查是否有意修改了组件渲染结果
2. 确认修改是预期的
3. 更新快照：`pnpm test:update-snapshot`

## 参考资料

- [Jest 官方文档](https://jestjs.io/)
- [React Testing Library 官方文档](https://testing-library.com/react)
- [测试最佳实践](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)

## 版本历史

- v1.0.0: 初始测试文档
  - 包含 14 个测试用例
  - 覆盖基础渲染、条件渲染、样式、复杂内容等场景
