6.4 KiB
6.4 KiB
Normalizer Tests
每个 normalizer 模块都有完整的测试覆盖。
测试结构
tests/normalize/normalizers/
├── __init__.py
├── test_invoice_number_normalizer.py # InvoiceNumberNormalizer 测试 (12 个测试)
├── test_ocr_normalizer.py # OCRNormalizer 测试 (9 个测试)
├── test_bankgiro_normalizer.py # BankgiroNormalizer 测试 (11 个测试)
├── test_plusgiro_normalizer.py # PlusgiroNormalizer 测试 (10 个测试)
├── test_amount_normalizer.py # AmountNormalizer 测试 (15 个测试)
├── test_date_normalizer.py # DateNormalizer 测试 (19 个测试)
├── test_organisation_number_normalizer.py # OrganisationNumberNormalizer 测试 (11 个测试)
├── test_supplier_accounts_normalizer.py # SupplierAccountsNormalizer 测试 (13 个测试)
├── test_customer_number_normalizer.py # CustomerNumberNormalizer 测试 (12 个测试)
└── README.md # 本文件
运行测试
运行所有 normalizer 测试
# 在 WSL 环境中
conda activate invoice-py311
pytest tests/normalize/normalizers/ -v
运行单个 normalizer 的测试
# 测试 InvoiceNumberNormalizer
pytest tests/normalize/normalizers/test_invoice_number_normalizer.py -v
# 测试 AmountNormalizer
pytest tests/normalize/normalizers/test_amount_normalizer.py -v
# 测试 DateNormalizer
pytest tests/normalize/normalizers/test_date_normalizer.py -v
查看测试覆盖率
pytest tests/normalize/normalizers/ --cov=src/normalize/normalizers --cov-report=html
测试统计
总计: 112 个测试用例 状态: ✅ 全部通过 执行时间: ~5.6 秒
各 Normalizer 测试数量
| Normalizer | 测试数量 | 覆盖率 |
|---|---|---|
| InvoiceNumberNormalizer | 12 | 100% |
| OCRNormalizer | 9 | 100% |
| BankgiroNormalizer | 11 | 100% |
| PlusgiroNormalizer | 10 | 100% |
| AmountNormalizer | 15 | 100% |
| DateNormalizer | 19 | 93% |
| OrganisationNumberNormalizer | 11 | 100% |
| SupplierAccountsNormalizer | 13 | 100% |
| CustomerNumberNormalizer | 12 | 100% |
测试覆盖的场景
通用测试 (所有 normalizer)
- ✅ 空字符串处理
- ✅ None 值处理
- ✅ Callable 接口 (
__call__) - ✅ 基本功能验证
InvoiceNumberNormalizer
- ✅ 纯数字发票号
- ✅ 带前缀的发票号 (INV-, etc.)
- ✅ 字母数字混合
- ✅ 特殊字符处理
- ✅ Unicode 字符清理
- ✅ 多个分隔符
- ✅ 无数字内容
- ✅ 重复变体去除
OCRNormalizer
- ✅ 纯数字 OCR
- ✅ 带前缀 (OCR:)
- ✅ 空格分隔
- ✅ 连字符分隔
- ✅ 混合分隔符
- ✅ 超长 OCR 号码
BankgiroNormalizer
- ✅ 8 位数字 (带/不带连字符)
- ✅ 7 位数字格式
- ✅ 特殊连字符类型 (en-dash, etc.)
- ✅ 空格处理
- ✅ 前缀处理 (BG:)
- ✅ OCR 错误变体生成
PlusgiroNormalizer
- ✅ 8 位数字 (带/不带连字符)
- ✅ 7 位数字
- ✅ 9 位数字
- ✅ 空格处理
- ✅ 前缀处理 (PG:)
- ✅ OCR 错误变体生成
AmountNormalizer
- ✅ 整数金额
- ✅ 逗号小数分隔符
- ✅ 点小数分隔符
- ✅ 空格千位分隔符
- ✅ 空格作为小数分隔符 (瑞典格式)
- ✅ 美国格式 (1,390.00)
- ✅ 欧洲格式 (1.390,00)
- ✅ 货币符号移除 (kr, SEK)
- ✅ 大金额处理
- ✅ 冒号破折号后缀 (1234:-)
DateNormalizer
- ✅ ISO 格式 (2025-12-13)
- ✅ 欧洲斜杠格式 (13/12/2025)
- ✅ 欧洲点格式 (13.12.2025)
- ✅ 紧凑格式 YYYYMMDD
- ✅ 紧凑格式 YYMMDD
- ✅ 短年份格式 (DD.MM.YY)
- ✅ 瑞典月份名称 (december, dec)
- ✅ 瑞典月份缩写
- ✅ 带时间的 ISO 格式
- ✅ 歧义日期双重解析
- ✅ 中点分隔符
- ✅ 空格格式
- ✅ 无效日期处理
- ✅ 2 位年份世纪判断
OrganisationNumberNormalizer
- ✅ 带/不带连字符
- ✅ VAT 号码提取
- ✅ VAT 号码生成
- ✅ 12 位带世纪组织号
- ✅ VAT 带空格
- ✅ 大小写混合 VAT 前缀
- ✅ OCR 错误变体生成
SupplierAccountsNormalizer
- ✅ 单个 Plusgiro
- ✅ 单个 Bankgiro
- ✅ 多账号 (| 分隔)
- ✅ 前缀标准化
- ✅ 前缀带空格
- ✅ 空账号忽略
- ✅ 无前缀账号
- ✅ 7 位账号
- ✅ 10 位账号
- ✅ 混合格式账号
CustomerNumberNormalizer
- ✅ 字母数字+空格+连字符
- ✅ 字母数字+空格
- ✅ 大小写变体
- ✅ 纯数字
- ✅ 仅连字符
- ✅ 仅空格
- ✅ 大写重复去除
- ✅ 复杂客户编号
- ✅ 瑞典客户编号格式 (UMJ 436-R)
最佳实践
1. 使用 pytest fixtures
每个测试类都使用 @pytest.fixture 创建 normalizer 实例:
@pytest.fixture
def normalizer(self):
"""Create normalizer instance for testing"""
return InvoiceNumberNormalizer()
def test_something(self, normalizer):
result = normalizer.normalize('test')
assert 'expected' in result
2. 清晰的测试命名
测试方法名清楚描述测试场景:
def test_with_dash_8_digits(self, normalizer):
"""8-digit Bankgiro with dash should generate variants"""
...
3. 断言具体行为
明确测试期望的行为:
result = normalizer.normalize('5393-9484')
assert '5393-9484' in result # 保留原始格式
assert '53939484' in result # 生成无连字符格式
4. 边界条件测试
每个 normalizer 都测试:
- 空字符串
- None 值
- 特殊字符
- 极端值
5. 接口一致性测试
验证 callable 接口:
def test_callable_interface(self, normalizer):
"""Normalizer should be callable via __call__"""
result = normalizer('test-value')
assert result is not None
添加新测试
为新功能添加测试:
def test_new_feature(self, normalizer):
"""Description of what this tests"""
# Arrange
input_value = 'test-input'
# Act
result = normalizer.normalize(input_value)
# Assert
assert 'expected-output' in result
assert len(result) > 0
CI/CD 集成
这些测试可以轻松集成到 CI/CD 流程:
# .github/workflows/test.yml
- name: Run Normalizer Tests
run: pytest tests/normalize/normalizers/ -v --cov
总结
✅ 112 个测试全部通过 ✅ 高覆盖率: 大部分 normalizer 达到 100% ✅ 快速执行: 5.6 秒完成所有测试 ✅ 清晰结构: 每个 normalizer 独立测试文件 ✅ 易维护: 遵循 pytest 最佳实践