Files
lanyuanxiaoyao fad0edc46a feat: 添加 doc/xls/ppt 旧格式文档静态测试文件支持
- 更新 .gitattributes,将 fixtures 目录所有文件纳入 Git LFS
- 在 tests/test_readers/conftest.py 中添加静态文件 fixtures
- 添加 doc/xls/ppt 静态测试文件(9个文件)
- 更新各旧格式解析器测试用例使用静态文件
- 更新一致性测试使用静态文件
- 在 README.md 中添加 fixtures 使用规范
- 同步 delta specs 到主 specs(doc-reader/xls-reader/ppt-reader/reader-testing/test-fixtures)
- 归档 add-static-test-fixtures 变更
2026-03-11 00:30:47 +08:00

177 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Reader Testing Specification
## Purpose
定义 Reader 实现的测试规范,包括 supports 方法验证、parse 方法测试、特殊字符处理、多 Reader 一致性等。
## Requirements
### Requirement: Reader supports 方法验证
每个 Reader MUST 实现 `supports(file_path: str) -> bool` 方法,正确判断是否支持给定输入。
#### Scenario: DOCX Reader 识别标准扩展名
- **WHEN** 调用 DOCX Reader 的 `supports("file.docx")`
- **THEN** 返回 True
#### Scenario: DOCX Reader 识别大写扩展名
- **WHEN** 调用 DOCX Reader 的 `supports("FILE.DOCX")`
- **THEN** 返回 True
#### Scenario: DOCX Reader 识别 .doc 扩展名
- **WHEN** 调用 DOCX Reader 的 `supports("file.doc")`
- **THEN** 返回 True
#### Scenario: DOCX Reader 拒绝不支持格式
- **WHEN** 调用 DOCX Reader 的 `supports("file.pdf")`
- **THEN** 返回 False
#### Scenario: DOCX Reader 支持 URL
- **WHEN** 调用 DOCX Reader 的 `supports("http://example.com/file.docx")`
- **THEN** 返回 True
#### Scenario: PDF Reader 识别 PDF 文件
- **WHEN** 调用 PDF Reader 的 `supports("file.pdf")`
- **THEN** 返回 True
#### Scenario: HTML Reader 识别 HTML 文件
- **WHEN** 调用 HTML Reader 的 `supports("file.html")`
- **THEN** 返回 True
### Requirement: Reader parse 方法正常解析
每个 Reader MUST 实现 `parse(file_path: str) -> Tuple[Optional[str], List[str]]` 方法,成功解析时返回 Markdown 内容和空失败列表。
#### Scenario: DOCX Reader 解析包含段落
- **WHEN** DOCX Reader 解析包含段落的文件
- **THEN** 返回的 Markdown 内容包含段落文字
- **AND** 失败列表为空
#### Scenario: DOCX Reader 解析包含标题
- **WHEN** DOCX Reader 解析包含标题的文件
- **THEN** 返回的 Markdown 内容包含 `# ` 标记的标题
#### Scenario: DOCX Reader 解析包含表格
- **WHEN** DOCX Reader 解析包含表格的文件
- **THEN** 返回的 Markdown 内容包含表格中的关键文字
#### Scenario: DOCX Reader 解析包含列表
- **WHEN** DOCX Reader 解析包含列表的文件
- **THEN** 返回的 Markdown 内容包含列表项文字
#### Scenario: PDF Reader 解析基本内容
- **WHEN** PDF Reader 解析包含文字的 PDF
- **THEN** 返回的 Markdown 内容包含关键文字
#### Scenario: HTML Reader 解析网页内容
- **WHEN** HTML Reader 解析包含内容的 HTML 文件
- **THEN** 返回的 Markdown 内容包含网页关键文字
### Requirement: Reader 解析结果核心文字一致性
同一文件使用不同 Reader 解析时MUST 保持核心文字内容一致(样式和格式可以不同)。
#### Scenario: DOCX 多 Reader 一致性
- **WHEN** 同一 DOCX 文件被 python-docx、markitdown、docling 等 Reader 解析
- **THEN** 所有输出的 Markdown 都包含相同的核心文字内容
#### Scenario: PDF 多 Reader 一致性
- **WHEN** 同一 PDF 文件被 pypdf、markitdown、docling 等 Reader 解析
- **THEN** 所有输出的 Markdown 都包含相同的核心文字内容
### Requirement: Reader 处理特殊字符
Reader MUST 正确处理包含特殊字符的内容。
#### Scenario: 处理中文字符
- **WHEN** 文件包含中文内容
- **THEN** 解析后的 Markdown 正确包含中文
#### Scenario: 处理 Emoji 表情
- **WHEN** 文件包含 Emoji如 😀🎉)
- **THEN** 解析后的 Markdown 正确包含 Emoji
#### Scenario: 处理特殊符号
- **WHEN** 文件包含特殊符号(©®™°±)
- **THEN** 解析后的 Markdown 正确包含这些符号
#### Scenario: 处理 RTL 文本
- **WHEN** 文件包含阿拉伯文等 RTL 文本
- **THEN** 解析后的 Markdown 正确包含 RTL 文本
#### Scenario: 处理混合文本
- **WHEN** 文件包含混合内容(如 "Hello你好🎉"
- **THEN** 解析后的 Markdown 正确包含混合内容
#### Scenario: 处理零宽字符
- **WHEN** 文件包含零宽字符(\u200b\u200c\u200d
- **THEN** 解析后的 Markdown 正确处理这些字符
#### Scenario: 处理超长文本
- **WHEN** 文件包含超长文本(如 100000 个字符)
- **THEN** Reader 能够成功解析
### Requirement: Reader 独立测试
每个 Reader 实现 MUST 有独立的测试文件,不使用参数化测试。
#### Scenario: 每个 DOCX Reader 有独立测试
- **WHEN** 查看 test_readers/test_docx/ 目录
- **THEN** 存在 test_python_docx.py、test_markitdown.py、test_docling.py 等独立文件
#### Scenario: 每个 PDF Reader 有独立测试
- **WHEN** 查看 test_readers/test_pdf/ 目录
- **THEN** 存在 test_pypdf.py、test_markitdown.py、test_docling.py 等独立文件
### Requirement: 旧格式文档测试覆盖
doc/xls/ppt 旧格式文档 MUST 有与新格式docx/xlsx/pptx一致的测试覆盖。
#### Scenario: doc 有一致性测试
- **WHEN** 查看 `tests/test_readers/test_doc/`
- **THEN** 存在 `test_consistency.py` 测试所有 DOC Readers 解析结果一致性
#### Scenario: xls 有一致性测试
- **WHEN** 查看 `tests/test_readers/test_xls/`
- **THEN** 存在 `test_consistency.py` 测试所有 XLS Readers 解析结果一致性
#### Scenario: ppt 有一致性测试
- **WHEN** 查看 `tests/test_readers/test_ppt/`
- **THEN** 存在 `test_consistency.py` 测试所有 PPT Readers 解析结果一致性
#### Scenario: doc 各解析器独立测试
- **WHEN** 查看 `tests/test_readers/test_doc/`
- **THEN** 每个解析器有独立测试文件(如 `test_markitdown_doc.py``test_pypandoc_doc.py`
#### Scenario: xls 各解析器独立测试
- **WHEN** 查看 `tests/test_readers/test_xls/`
- **THEN** 每个解析器有独立测试文件(如 `test_markitdown_xls.py``test_unstructured_xls.py``test_pandas_xls.py`
#### Scenario: ppt 各解析器独立测试
- **WHEN** 查看 `tests/test_readers/test_ppt/`
- **THEN** 每个解析器有独立测试文件(如 `test_markitdown_ppt.py`
### Requirement: 旧格式测试使用静态文件
旧格式文档测试 MUST 使用静态测试文件,而非尝试自动化创建。
#### Scenario: doc 测试使用静态文件
- **WHEN** 运行 doc 相关测试
- **THEN** 测试从 `tests/test_readers/fixtures/doc/` 读取静态文件
#### Scenario: xls 测试使用静态文件
- **WHEN** 运行 xls 相关测试
- **THEN** 测试从 `tests/test_readers/fixtures/xls/` 读取静态文件
#### Scenario: ppt 测试使用静态文件
- **WHEN** 运行 ppt 相关测试
- **THEN** 测试从 `tests/test_readers/fixtures/ppt/` 读取静态文件
### Requirement: 静态文件缺失时优雅跳过
当静态测试文件不存在时,测试 MUST 优雅跳过,而非失败。
#### Scenario: doc 静态文件不存在时跳过
- **WHEN** `simple.doc` 不存在
- **THEN** 相关测试使用 `pytest.skip()` 跳过
#### Scenario: xls 静态文件不存在时跳过
- **WHEN** `simple.xls` 不存在
- **THEN** 相关测试使用 `pytest.skip()` 跳过
#### Scenario: ppt 静态文件不存在时跳过
- **WHEN** `simple.ppt` 不存在
- **THEN** 相关测试使用 `pytest.skip()` 跳过