---
title: 测试文档
order: 4
category: pro
---

# PisellSingleLineText 组件测试用例文档

## 1 测试概述

### 1.1 测试目标

确保 PisellSingleLineText 组件的功能完整性、稳定性和用户体验，覆盖所有使用场景和边界情况。

### 1.2 测试范围

- 三种状态模式（只读、编辑、禁用）
- 受控/非受控模式
- 校验功能（5种校验规则）
- 事件回调
- 样式配置
- 边界情况处理

### 1.3 测试方法

- 单元测试：覆盖核心逻辑和边界情况
- 人工测试：UI 交互、视觉效果验证

## 2 单元测试用例

### 2.1 基础功能测试

#### 测试点 1：组件正常渲染

- **测试描述**：组件应该能够正常渲染
- **预期结果**：组件渲染成功，无报错
- **测试代码**：
  ```
  it('should render without crashing', () => {
    const { container } = render(<PisellSingleLineText />);
    expect(container).toBeInTheDocument();
  });
  ```

#### 测试点 2：默认为编辑态

- **测试描述**：不传 mode 时，默认应为编辑态
- **预期结果**：渲染 Input 组件
- **测试代码**：
  ```
  it('should default to edit mode', () => {
    const { container } = render(<PisellSingleLineText />);
    expect(container.querySelector('input')).toBeInTheDocument();
  });
  ```

### 2.2 状态模式测试

#### 测试点 3：只读态渲染

- **测试描述**：mode="read" 时应渲染只读态
- **预期结果**：渲染 Typography.Text，不渲染 Input
- **测试代码**：
  ```
  it('should render read mode correctly', () => {
    const { container } = render(
      <PisellSingleLineText mode="read" value="测试内容" />
    );
    expect(container.querySelector('input')).not.toBeInTheDocument();
    expect(container.textContent).toBe('测试内容');
  });
  ```

#### 测试点 4：编辑态渲染

- **测试描述**：mode="edit" 时应渲染编辑态
- **预期结果**：渲染 Input 组件
- **测试代码**：
  ```
  it('should render edit mode correctly', () => {
    const { container } = render(<PisellSingleLineText mode="edit" />);
    expect(container.querySelector('input')).toBeInTheDocument();
  });
  ```

#### 测试点 5：禁用态渲染

- **测试描述**：disabled=true 时应渲染禁用态
- **预期结果**：组件禁用，透明度 0.4
- **测试代码**：
  ```
  it('should render disabled state correctly', () => {
    const { container } = render(<PisellSingleLineText disabled />);
    const disabledDiv = container.querySelector('.pisell-single-line-text-disabled');
    expect(disabledDiv).toHaveStyle({ opacity: 0.4 });
  });
  ```

#### 测试点 6：disabled 优先级高于 mode

- **测试描述**：disabled=true 时，无论 mode 是什么都应该显示禁用态
- **预期结果**：显示禁用态
- **测试代码**：
  ```
  it('should prioritize disabled over mode', () => {
    const { container } = render(
      <PisellSingleLineText mode="edit" disabled />
    );
    const disabledDiv = container.querySelector('.pisell-single-line-text-disabled');
    expect(disabledDiv).toBeInTheDocument();
  });
  ```

### 2.3 受控/非受控模式测试

#### 测试点 7：受控模式

- **测试描述**：传入 value 时为受控模式，值由外部控制
- **预期结果**：显示的值为 props.value
- **测试代码**：
  ```
  it('should work in controlled mode', () => {
    const { rerender, container } = render(
      <PisellSingleLineText value="初始值" />
    );
    const input = container.querySelector('input');
    expect(input?.value).toBe('初始值');
    
    rerender(<PisellSingleLineText value="新值" />);
    expect(input?.value).toBe('新值');
  });
  ```

#### 测试点 8：非受控模式

- **测试描述**：传入 defaultValue 时为非受控模式，组件内部管理值
- **预期结果**：显示默认值，可以修改
- **测试代码**：
  ```
  it('should work in uncontrolled mode', () => {
    const { container } = render(
      <PisellSingleLineText defaultValue="默认值" />
    );
    const input = container.querySelector('input');
    expect(input?.value).toBe('默认值');
  });
  ```

#### 测试点 9：受控模式值更新

- **测试描述**：受控模式下，外部修改 value 应该反映到组件
- **预期结果**：组件显示最新的 value
- **测试代码**：同测试点 7

### 2.4 校验功能测试

#### 测试点 10：必填校验

- **测试描述**：required=true 时，空值应校验失败
- **预期结果**：显示错误提示 "此字段为必填项"
- **测试代码**：
  ```
  it('should validate required field', () => {
    const { container } = render(
      <PisellSingleLineText required validateTrigger="onChange" />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: '' } });
    
    const error = container.querySelector('.pisell-single-line-text-error');
    expect(error?.textContent).toBe('此字段为必填项');
  });
  ```

#### 测试点 11：最小长度校验

- **测试描述**：minLength=5 时，少于5个字符应校验失败
- **预期结果**：显示错误提示 "最少需要 5 个字符"
- **测试代码**：
  ```
  it('should validate minLength', () => {
    const { container } = render(
      <PisellSingleLineText minLength={5} validateTrigger="onChange" />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: 'abc' } });
    
    const error = container.querySelector('.pisell-single-line-text-error');
    expect(error?.textContent).toBe('最少需要 5 个字符');
  });
  ```

#### 测试点 12：最大长度校验

- **测试描述**：maxLength=10 时，超过10个字符应校验失败（兜底）
- **预期结果**：显示错误提示
- **测试代码**：类似测试点 11

#### 测试点 13：正则校验

- **测试描述**：pattern 正则校验应生效
- **预期结果**：不匹配时显示错误提示
- **测试代码**：
  ```
  it('should validate pattern', () => {
    const { container } = render(
      <PisellSingleLineText 
        pattern="^[0-9]+$" 
        errorMessage="只能输入数字"
        validateTrigger="onChange"
      />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: 'abc' } });
    
    const error = container.querySelector('.pisell-single-line-text-error');
    expect(error?.textContent).toBe('只能输入数字');
  });
  ```

#### 测试点 14：自定义校验函数

- **测试描述**：validator 自定义校验应生效
- **预期结果**：返回字符串时显示该错误信息
- **测试代码**：
  ```
  it('should validate with custom validator', () => {
    const validator = (value: string) => {
      if (value.includes('禁止')) {
        return '包含禁止词汇';
      }
      return true;
    };
    
    const { container } = render(
      <PisellSingleLineText validator={validator} validateTrigger="onChange" />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: '这是禁止的内容' } });
    
    const error = container.querySelector('.pisell-single-line-text-error');
    expect(error?.textContent).toBe('包含禁止词汇');
  });
  ```

#### 测试点 15：校验时机 - onChange

- **测试描述**：validateTrigger="onChange" 时，输入时立即校验
- **预期结果**：输入时即显示错误
- **测试代码**：
  ```
  it('should validate onChange when validateTrigger is onChange', () => {
    const onValidate = jest.fn();
    const { container } = render(
      <PisellSingleLineText 
        required 
        validateTrigger="onChange"
        onValidate={onValidate}
      />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: '' } });
    
    expect(onValidate).toHaveBeenCalledWith(false, ['此字段为必填项']);
  });
  ```

#### 测试点 16：校验时机 - onBlur

- **测试描述**：validateTrigger="onBlur" 时，失焦时校验
- **预期结果**：失焦时显示错误
- **测试代码**：
  ```
  it('should validate onBlur when validateTrigger is onBlur', () => {
    const onValidate = jest.fn();
    const { container } = render(
      <PisellSingleLineText 
        required 
        validateTrigger="onBlur"
        onValidate={onValidate}
      />
    );
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: '' } });
    expect(onValidate).not.toHaveBeenCalled();
    
    fireEvent.blur(input!);
    expect(onValidate).toHaveBeenCalledWith(false, ['此字段为必填项']);
  });
  ```

### 2.5 事件回调测试

#### 测试点 17：onChange 回调

- **测试描述**：输入时应触发 onChange 回调
- **预期结果**：回调被调用，参数正确
- **测试代码**：
  ```
  it('should call onChange when value changes', () => {
    const onChange = jest.fn();
    const { container } = render(<PisellSingleLineText onChange={onChange} />);
    const input = container.querySelector('input');
    fireEvent.change(input!, { target: { value: '新内容' } });
    
    expect(onChange).toHaveBeenCalledWith('新内容');
  });
  ```

#### 测试点 18：onBlur 回调

- **测试描述**：失焦时应触发 onBlur 回调
- **预期结果**：回调被调用，参数正确

#### 测试点 19：onFocus 回调

- **测试描述**：聚焦时应触发 onFocus 回调
- **预期结果**：回调被调用

#### 测试点 20：onPressEnter 回调

- **测试描述**：按下回车键时应触发 onPressEnter 回调
- **预期结果**：回调被调用，参数为当前值
- **测试代码**：
  ```
  it('should call onPressEnter when Enter key is pressed', () => {
    const onPressEnter = jest.fn();
    const { container } = render(
      <PisellSingleLineText value="测试" onPressEnter={onPressEnter} />
    );
    const input = container.querySelector('input');
    fireEvent.keyDown(input!, { key: 'Enter' });
    
    expect(onPressEnter).toHaveBeenCalledWith('测试');
  });
  ```

### 2.6 展示配置测试（只读态）

#### 测试点 21：文本截断

- **测试描述**：ellipsis=true 时，文本应该支持截断
- **预期结果**：Typography.Text 的 ellipsis 属性为 true

#### 测试点 22：Tooltip 显示

- **测试描述**：showTooltip=true 且 ellipsis=true 时，应显示 Tooltip
- **预期结果**：Tooltip 组件被渲染

#### 测试点 23：自定义样式

- **测试描述**：传入 fontSize、fontWeight、color 等样式配置
- **预期结果**：样式正确应用

### 2.7 编辑配置测试

#### 测试点 24：最大长度限制

- **测试描述**：maxLength 应限制输入长度
- **预期结果**：Input 的 maxLength 属性正确设置

#### 测试点 25：字数统计

- **测试描述**：showCount=true 时应显示字数统计
- **预期结果**：显示字数统计

#### 测试点 26：清空按钮

- **测试描述**：allowClear=true 时应显示清空按钮
- **预期结果**：点击清空按钮后值被清空

#### 测试点 27：前后缀

- **测试描述**：prefix 和 suffix 应正确渲染
- **预期结果**：前后缀图标/文本显示

#### 测试点 28：前后置标签

- **测试描述**：addonBefore 和 addonAfter 应正确渲染
- **预期结果**：前后置标签显示

### 2.8 边界情况测试

#### 测试点 29：空值处理

- **测试描述**：value 为 undefined、null、'' 时应正常处理
- **预期结果**：不报错，显示为空

#### 测试点 30：特殊字符处理

- **测试描述**：输入特殊字符（emoji、换行符等）
- **预期结果**：正常显示和处理

#### 测试点 31：超长文本处理

- **测试描述**：输入超长文本（如 10000 字符）
- **预期结果**：不崩溃，maxLength 生效

### 2.9 性能测试

#### 测试点 32：React.memo 生效

- **测试描述**：props 未变化时不应重新渲染
- **预期结果**：组件不重新渲染

#### 测试点 33：大量组件渲染

- **测试描述**：同时渲染 100 个组件
- **预期结果**：性能正常，不卡顿

## 3 人工测试用例

### 3.1 UI 交互测试

#### 测试点 34：只读态视觉效果

- **测试步骤**：
  1. 设置 mode="read"，value="这是一段测试文本"
  2. 设置 ellipsis=true
  3. 观察文本展示
- **预期结果**：
  - 不显示输入框
  - 文本以纯文本形式展示
  - 超出容器宽度时显示省略号
- **测试状态**：待测试 ⏳

#### 测试点 35：只读态 Tooltip

- **测试步骤**：
  1. 设置 mode="read"，value="很长的文本内容..."
  2. 设置 ellipsis=true，showTooltip=true
  3. 鼠标悬停在文本上
- **预期结果**：
  - 显示完整内容的 Tooltip
- **测试状态**：待测试 ⏳

#### 测试点 36：编辑态输入体验

- **测试步骤**：
  1. 设置 mode="edit"
  2. 在输入框中输入文字
  3. 复制粘贴文字
  4. 使用快捷键（Ctrl+A、Ctrl+C、Ctrl+V）
- **预期结果**：
  - 输入流畅
  - 复制粘贴正常
  - 快捷键正常工作
- **测试状态**：待测试 ⏳

#### 测试点 37：禁用态交互

- **测试步骤**：
  1. 设置 disabled=true
  2. 尝试点击、输入
- **预期结果**：
  - 透明度 40%
  - 无法输入
  - 无法聚焦
  - 鼠标 cursor 显示为 not-allowed
- **测试状态**：待测试 ⏳

### 3.2 校验功能人工测试

#### 测试点 38：必填校验视觉反馈

- **测试步骤**：
  1. 设置 required=true
  2. 输入框输入内容后全部删除
  3. 失焦
- **预期结果**：
  - 输入框边框变红
  - 下方显示 "此字段为必填项"
  - 错误提示有淡入动画
- **测试状态**：待测试 ⏳

#### 测试点 39：实时校验体验

- **测试步骤**：
  1. 设置 validateTrigger="onChange"，minLength=5
  2. 逐字输入 "hello"
- **预期结果**：
  - 输入 1-4 个字符时显示错误
  - 输入第 5 个字符时错误消失
- **测试状态**：待测试 ⏳

#### 测试点 40：失焦校验体验

- **测试步骤**：
  1. 设置 validateTrigger="onBlur"，required=true
  2. 输入框聚焦后不输入
  3. 失焦
- **预期结果**：
  - 输入过程中不显示错误
  - 失焦时才显示错误
- **测试状态**：待测试 ⏳

### 3.3 样式配置测试

#### 测试点 41：自定义字号

- **测试步骤**：
  1. 设置 mode="read"，fontSize="20px"
  2. 观察文本
- **预期结果**：
  - 文字大小为 20px
- **测试状态**：待测试 ⏳

#### 测试点 42：自定义颜色

- **测试步骤**：
  1. 设置 mode="read"，color="#ff0000"
  2. 观察文本
- **预期结果**：
  - 文字颜色为红色
- **测试状态**：待测试 ⏳

#### 测试点 43：对齐方式

- **测试步骤**：
  1. 分别设置 textAlign="left"/"center"/"right"
  2. 观察文本对齐
- **预期结果**：
  - 文本按指定方式对齐
- **测试状态**：待测试 ⏳

### 3.4 编辑配置测试

#### 测试点 44：字数统计显示

- **测试步骤**：
  1. 设置 showCount=true，maxLength=10
  2. 输入文字
- **预期结果**：
  - 显示 "x / 10" 字数统计
  - 实时更新
- **测试状态**：待测试 ⏳

#### 测试点 45：清空按钮

- **测试步骤**：
  1. 设置 allowClear=true
  2. 输入文字后点击清空按钮
- **预期结果**：
  - 输入框右侧显示清空图标
  - 点击后内容被清空
  - 触发 onChange 回调
- **测试状态**：待测试 ⏳

#### 测试点 46：前缀图标

- **测试步骤**：
  1. 设置 prefix={<UserOutlined />}
  2. 观察输入框
- **预期结果**：
  - 输入框左侧显示用户图标
- **测试状态**：待测试 ⏳

#### 测试点 47：后缀文本

- **测试步骤**：
  1. 设置 suffix="元"
  2. 观察输入框
- **预期结果**：
  - 输入框右侧显示 "元"
- **测试状态**：待测试 ⏳

#### 测试点 48：前置标签

- **测试步骤**：
  1. 设置 addonBefore="http://"
  2. 观察输入框
- **预期结果**：
  - 输入框左侧前置 "http://"
- **测试状态**：待测试 ⏳

#### 测试点 49：后置标签

- **测试步骤**：
  1. 设置 addonAfter={<Button>搜索</Button>}
  2. 观察输入框
- **预期结果**：
  - 输入框右侧附加搜索按钮
- **测试状态**：待测试 ⏳

### 3.5 无障碍访问测试

#### 测试点 50：ARIA 标签

- **测试步骤**：
  1. 设置 aria-label="用户名输入框"
  2. 使用屏幕阅读器测试
- **预期结果**：
  - 屏幕阅读器正确读取标签
- **测试状态**：待测试 ⏳

#### 测试点 51：键盘导航

- **测试步骤**：
  1. 使用 Tab 键在多个输入框间切换
  2. 使用方向键移动光标
- **预期结果**：
  - Tab 键正常切换焦点
  - 方向键正常移动光标
- **测试状态**：待测试 ⏳

### 3.6 兼容性测试

#### 测试点 52：浏览器兼容性

- **测试步骤**：
  1. 在 Chrome、Firefox、Safari、Edge 中测试
  2. 测试核心功能
- **预期结果**：
  - 所有浏览器中功能正常
- **测试状态**：待测试 ⏳

#### 测试点 53：响应式表现

- **测试步骤**：
  1. 在不同屏幕尺寸下测试
  2. 移动端、平板、桌面端
- **预期结果**：
  - 各种屏幕尺寸下正常显示
- **测试状态**：待测试 ⏳

### 3.7 组合使用测试

#### 测试点 54：必填 + 最小长度

- **测试步骤**：
  1. 设置 required=true，minLength=3
  2. 测试空值、短值、合法值
- **预期结果**：
  - 空值提示 "此字段为必填项"
  - 短值（1-2字符）提示 "最少需要 3 个字符"
  - 合法值（≥3字符）无错误
- **测试状态**：待测试 ⏳

#### 测试点 55：正则 + 自定义校验

- **测试步骤**：
  1. 设置 pattern + validator 两种校验
  2. 测试只满足 pattern、只满足 validator、都满足、都不满足的情况
- **预期结果**：
  - 两种校验都通过才显示为有效
- **测试状态**：待测试 ⏳

#### 测试点 56：前后缀 + 前后置标签组合

- **测试步骤**：
  1. 同时设置 prefix、suffix、addonBefore、addonAfter
  2. 观察布局
- **预期结果**：
  - 布局正确，不重叠
  - 视觉美观
- **测试状态**：待测试 ⏳

## 4 性能测试

### 4.1 渲染性能

#### 测试点 57：首次渲染时间

- **测试方法**：使用 React Profiler 测量
- **性能指标**：< 16ms
- **测试状态**：待测试 ⏳

#### 测试点 58：重渲染性能

- **测试方法**：props 更新时的重渲染时间
- **性能指标**：< 8ms
- **测试状态**：待测试 ⏳

#### 测试点 59：内存占用

- **测试方法**：渲染 100 个组件，观察内存
- **性能指标**：< 100MB
- **测试状态**：待测试 ⏳

## 5 回归测试

### 5.1 核心功能回归

每次代码修改后，需要回归测试以下核心功能：

- ✅ 三种状态切换正常
- ✅ 受控/非受控模式正常
- ✅ 校验功能正常
- ✅ 事件回调正常
- ✅ 样式配置生效

### 5.2 兼容性回归

- ✅ 主流浏览器兼容
- ✅ 移动端兼容
- ✅ 低代码平台正常使用

## 6 测试覆盖率要求

### 6.1 代码覆盖率

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

### 6.2 功能覆盖率

- **状态模式**：100%（3/3）
- **校验规则**：100%（5/5）
- **事件回调**：100%（5/5）
- **展示配置**：100%（6/6）
- **编辑配置**：100%（8/8）

## 7 测试总结

### 7.1 测试统计

- **总测试用例数**：59 个
- **单元测试**：33 个
- **人工测试**：26 个
- **已完成**：0 个
- **待测试**：59 个
- **通过率**：0%（待测试）

### 7.2 重点测试项

以下为核心功能，必须重点测试：

1. ✅ **状态切换**：只读、编辑、禁用三种状态
2. ✅ **受控模式**：value 和 onChange 配合使用
3. ✅ **必填校验**：最常用的校验场景
4. ✅ **校验时机**：onChange vs onBlur
5. ✅ **清空按钮**：常用交互功能

---

## 8 Bug 汇总模块

此模块用于记录人工测试过程中发现的 Bug，格式如下：

### Bug 格式说明

**Bug ID**: BUG-001  
**发现时间**: 2026-01-24  
**严重程度**: 高/中/低  
**Bug 描述**: 详细描述 Bug 现象  
**复现步骤**:

1. 步骤1
2. 步骤2
3. ...

**预期结果**: 应该如何表现  
**实际结果**: 实际如何表现  
**修复状态**: 待修复 / 修复中 / 已修复  
**修复时间**: -

---

### 已发现的 Bug 列表

> 暂无 Bug

---

### 已修复的 Bug 列表

> 暂无已修复 Bug

---

**说明**：

- 人工测试时发现的 Bug 请按照上述格式记录在此模块
- Bug 修复后请更新状态和修复时间
- 已修复的 Bug 移动到 "已修复的 Bug 列表" 中
