test: 添加全面的测试套件,覆盖所有 Reader 实现

- 测试数量从 83 个增加到 193 个 (+132%)
- 代码覆盖率从 48% 提升到 69% (+44%)
- 为每种文档格式的所有 Reader 实现创建独立测试
- 添加跨 Reader 的一致性验证测试
- 新增 4 个测试规范 (cli-testing, exception-testing, reader-testing, test-fixtures)
- 更新 README 测试统计信息

测试覆盖:
- DOCX: python-docx, markitdown, docling, native-xml, pypandoc, unstructured
- PDF: pypdf, markitdown, docling, docling-ocr, unstructured, unstructured-ocr
- HTML: html2text, markitdown, trafilatura, domscribe
- PPTX: python-pptx, markitdown, docling, native-xml, unstructured
- XLSX: pandas, markitdown, docling, native-xml, unstructured
- CLI: 所有命令行选项和错误处理

所有 193 个测试通过。
This commit is contained in:
2026-03-08 22:20:21 +08:00
parent c35bbc90b5
commit 7eab1dcef1
53 changed files with 3094 additions and 259 deletions

View File

@@ -0,0 +1,119 @@
# 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 等独立文件