Files
cultivation-world-simulator/tests/README_i18n_tests.md
4thfever e1091fdf5a Feat/i18n (#92)
* feat: add vue-i18n

* feat: add vue-i18n

* feat: add vue-i18n

* feat: add language class

* add: en templates and configs

* add: en names

* refactor: name gender id and sect id

* feat(i18n): add gettext infrastructure for dynamic text translation (#81)

* feat(i18n): add gettext infrastructure for dynamic text translation

- Add src/i18n/ module with t() translation function
- Add .po/.mo files for zh_CN and en_US locales
- Update LanguageManager to reload translations on language change
- Add comprehensive tests (14 tests, all passing)
- Add implementation spec at docs/specs/i18n-dynamic-text.md

Phase 1 of i18n dynamic text implementation.

* feat(i18n): expand .po files with comprehensive translation entries

Add translation messages for:
- Battle result messages (fatal/non-fatal outcomes)
- Fortune event messages (item discovery, cultivation gains)
- Misfortune event messages (losses, damage, regression)
- Death reason messages
- Item exchange messages (equip, sell, discard)
- Single choice context and option labels
- Common labels (weapon, auxiliary, technique, elixir)

Both zh_CN and en_US locales updated with matching entries.

* test: add .po file integrity tests

* feat: i18n for actions

* feat: i18n for effects

* feat: i18n for gathering

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* update csv

* update world info

* update prompt

* update prompt

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* update

* update

* update

* update

* update

* update

* update

---------

Co-authored-by: Zihao Xu <xzhseh@gmail.com>
2026-01-24 13:47:23 +08:00

468 lines
12 KiB
Markdown
Raw 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.
# i18n 国际化测试套件
## 概述
本测试套件用于确保项目的国际化(i18n)工作质量,包括翻译完整性、代码规范和翻译文件的一致性。
## 测试文件
### 1. `test_i18n_duplicates.py` - PO 文件重复项检查
**独立测试**,不依赖 conftest.py可直接运行。
#### 测试内容
- ✅ 检查中文 PO 文件没有重复的 msgid
- ✅ 检查英文 PO 文件没有重复的 msgid
- ✅ 检查中英文 msgid 数量一致
- ✅ 检查中英文 msgid 键完全匹配
#### 运行方式
```bash
python tests/test_i18n_duplicates.py
```
#### 输出示例
```
============================================================
i18n PO 文件重复项检查
============================================================
检查中文 po 文件没有重复...
[PASS] 中文 po 文件没有重复的 msgid (共 519 个)
检查英文 po 文件没有重复...
[PASS] 英文 po 文件没有重复的 msgid (共 519 个)
检查中英文 msgid 数量一致...
[PASS] 中英文 po 文件的 msgid 数量一致: 519 个
检查中英文 msgid 键完全匹配...
[PASS] 中英文 po 文件的 msgid 键完全匹配
============================================================
[OK] 所有测试通过 (4/4)
```
---
### 2. `test_i18n_po_quality.py` - PO 文件质量和代码检查
**独立测试**,专注于静态分析,不依赖项目导入。
#### 测试内容
- 🔍 检查源代码中是否有硬编码的中文字符串(应使用 `t()` 函数)
- 🔍 检查代码中使用的所有翻译键是否都在 PO 文件中定义
- 🔍 检查格式化参数在 msgid 和 msgstr 中的一致性
#### 运行方式
```bash
python tests/test_i18n_po_quality.py
```
#### 检查项目详情
##### 1. 硬编码中文字符串检查
扫描 `src/` 目录下的所有 Python 文件,查找可能硬编码的中文字符串。
**规则:**
- 跳过注释和文档字符串
- 跳过测试文件
- 检测字符串字面量中的中文字符
- 如果不在 `t()` 调用中,可能需要修复
**常见误报:**
- 枚举值的注释(如 `RIGHTEOUS = "righteous" # 正`
- 测试数据
- 配置键名
##### 2. 翻译键定义检查
使用 AST 解析器提取代码中所有 `t()` 函数调用,并与 PO 文件中定义的 msgid 对比。
**检查逻辑:**
```python
# 代码中使用
result = t("{name} obtained {amount} spirit stones", name="张三", amount=100)
# 必须在 messages.po 中有定义
msgid "{name} obtained {amount} spirit stones"
msgstr "{name} 获得灵石 {amount}"
```
**如果发现缺失:**
需要在两个 PO 文件中都添加这个翻译键。
##### 3. 格式化参数一致性检查
确保翻译文本中的占位符参数与原始 msgid 一致。
**示例:**
```
✅ 正确:
msgid "{name} lost {amount} spirit stones"
msgstr "{name} 损失灵石 {amount} 枚" (参数: name, amount)
❌ 错误:
msgid "{name} lost {amount} spirit stones"
msgstr "{user} 损失灵石 {count} 枚" (参数: user, count) - 不匹配!
```
#### 输出示例
```
============================================================
PO 文件质量和翻译键使用检查
============================================================
============================================================
测试: 检查硬编码中文字符串
============================================================
警告:发现可能的硬编码中文字符串(应使用 t() 函数):
============================================================
classes\appearance.py:35
(1, "俊朗", "你长得很成熟,举止协调,给人从容踏实感。", ...)
... 还有 448 个
注意:这可能包括误报,请手动检查
============================================================
测试: 检查翻译键定义
============================================================
PO 文件中定义了 519 个 msgid
代码中使用了 239 个唯一的 msgid
✓ 所有使用的 msgid 都已在 PO 文件中定义
============================================================
测试: 检查格式化参数一致性
============================================================
检查 519 个翻译条目的格式化参数一致性...
✓ 所有翻译的格式化参数都一致
============================================================
测试完成
============================================================
```
---
### 3. `test_i18n_classes_coverage.py` - Classes 模块国际化覆盖率
**需要完整项目环境**,用于深度测试 classes 模块的国际化集成。
#### 测试内容
- 🧪 测试各种枚举类型的翻译(境界、性别、阵营等)
- 🧪 测试动作名称的翻译
- 🧪 测试效果名称的翻译
- 🧪 测试带参数的翻译
- 🧪 测试中英文切换
#### 运行方式
```bash
python -m pytest tests/test_i18n_classes_coverage.py -v
```
**注意:** 此测试依赖项目完整环境,如果有导入错误请先修复项目依赖。
---
### 4. `test_i18n_dynamic.py` - 动态文本翻译测试
**标准 pytest 测试**,测试 i18n 模块的基本功能。
#### 测试内容
- ✅ PO 文件语法和完整性
- ✅ 中英文基本翻译功能
- ✅ 战斗消息翻译
- ✅ 奇遇消息翻译
- ✅ 死亡原因翻译
- ✅ 语言切换功能
#### 运行方式
```bash
python -m pytest tests/test_i18n_dynamic.py -v
```
---
## 快速检查清单
### 添加新功能时
1. **编写代码时:**
- ✅ 所有用户可见的文本都使用 `t()` 函数
- ✅ 不要硬编码中文或英文字符串
- ✅ 使用有意义的 msgid通常是英文描述
2. **添加翻译:**
```python
# 代码中
message = t("{name} obtained {amount} spirit stones", name=avatar.name, amount=100)
```
```po
# messages.po 中(两个语言文件都要加)
msgid "{name} obtained {amount} spirit stones"
msgstr "{name} 获得灵石 {amount} 枚" # zh_CN
msgstr "{name} obtained {amount} spirit stones" # en_US
```
3. **运行测试:**
```bash
# 快速检查
python tests/test_i18n_duplicates.py
python tests/test_i18n_po_quality.py
# 完整测试
python -m pytest tests/test_i18n_*.py -v
```
### 修复常见问题
#### 问题 1: 发现重复的 msgid
```bash
# 运行重复检查
python tests/test_i18n_duplicates.py
# 输出会显示重复的行号
[FAIL] 中文 po 文件中发现 2 个重复的 msgid:
- 'Encountered fortune ({theme}), {result}' 出现了 2 次
```
**解决方法:** 手动编辑 PO 文件,删除重复的条目
#### 问题 2: 代码中使用但未定义的 msgid
```bash
python tests/test_i18n_po_quality.py
# 输出
错误:发现 9 个未在 PO 文件中定义的 msgid:
- 'Unsupported item type: {item_type}'
- '{avatar} gained cultivation experience +{exp} points'
```
**解决方法:** 在两个 PO 文件中添加这些 msgid 及其翻译
#### 问题 3: 格式化参数不一致
```bash
# 输出
警告:发现 3 个格式化参数不一致的条目:
msgid: {name} lost {amount} spirit stones
原始参数: {'name', 'amount'}
中文参数: {'user', 'count'} # 错误!
英文参数: {'name', 'amount'}
```
**解决方法:** 修改中文翻译,使用相同的参数名
---
## CI/CD 集成
### GitHub Actions 示例
```yaml
name: i18n Tests
on: [push, pull_request]
jobs:
i18n-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11'
- name: Check PO duplicates
run: python tests/test_i18n_duplicates.py
- name: Check PO quality
run: python tests/test_i18n_po_quality.py
- name: Run i18n tests
run: |
pip install pytest
pytest tests/test_i18n_*.py -v
```
---
## 相关工具
### `tools/i18n/check_po_duplicates.py`
独立的检查工具,提供更详细的输出。
```bash
python tools/i18n/check_po_duplicates.py
```
**功能:**
- 检查重复 msgid
- 检查数量一致性
- 检查键匹配
- 返回适合 CI 的退出码
---
## 最佳实践
### DO ✅
1. **使用 t() 函数包裹所有用户可见文本**
```python
# 好
message = t("{name} obtained {amount} spirit stones", name=name, amount=100)
# 不好
message = f"{name} 获得灵石 {amount} 枚"
```
2. **使用描述性的 msgid**
```python
# 好 - 清晰描述
t("cultivate_action_name")
t("{name} cultivation increased by {exp} points", ...)
# 不好 - 含义不明
t("msg1")
t("text_001")
```
3. **保持参数名一致**
```python
# 好 - 统一使用 name
t("{name} defeated {loser}", name=winner, loser=loser)
# 不好 - 混用
t("{name} defeated {loser}", user=winner, target=loser)
```
### DON'T ❌
1. **不要硬编码文本**
```python
# 错误
return "修炼"
# 正确
return t("cultivate_action_name")
```
2. **不要在 PO 文件中使用不同的参数名**
```po
# 错误
msgid "{name} lost {amount} spirit stones"
msgstr "{user} 损失灵石 {count} 枚"
# 正确
msgid "{name} lost {amount} spirit stones"
msgstr "{name} 损失灵石 {amount} 枚"
```
3. **不要忘记更新两个语言文件**
- 添加 msgid 时zh_CN 和 en_US 都要更新
- 保持两个文件的 msgid 完全一致
---
## 维护指南
### 定期检查
建议每次提交前运行:
```bash
# 快速检查(< 10秒
python tests/test_i18n_duplicates.py
python tests/test_i18n_po_quality.py
# 如果有变更,运行完整测试
python -m pytest tests/test_i18n_*.py -v
```
### 修复工作流
1. 发现问题 → 运行测试获取详细信息
2. 根据测试输出定位问题
3. 修复代码或 PO 文件
4. 重新运行测试确认
5. 提交更改
---
## 技术细节
### 工具和技术栈
- **PO 文件解析**: 正则表达式 `msgid\s+"([^"]*)"`
- **代码分析**: Python AST (抽象语法树)
- **中文检测**: Unicode 范围 `\u4e00-\u9fff`
- **翻译系统**: Python gettext
### 文件结构
```
src/
├── i18n/
│ ├── __init__.py # t() 函数定义
│ └── locales/
│ ├── zh_CN/LC_MESSAGES/
│ │ ├── messages.po # 中文翻译
│ │ └── messages.mo # 编译后的翻译
│ └── en_US/LC_MESSAGES/
│ ├── messages.po # 英文翻译
│ └── messages.mo # 编译后的翻译
tests/
├── test_i18n_duplicates.py # 重复项检查
├── test_i18n_po_quality.py # 质量检查
├── test_i18n_classes_coverage.py # 覆盖率测试
└── test_i18n_dynamic.py # 功能测试
tools/
└── i18n/
└── check_po_duplicates.py # 独立检查工具
```
---
## 常见问题
### Q: 测试报告硬编码中文,但那是注释怎么办?
A: 注释中的中文是允许的,测试会跳过。如果误报,可以忽略。
### Q: 如何批量添加缺失的翻译?
A:
1. 运行 `python tests/test_i18n_po_quality.py` 获取缺失列表
2. 在两个 PO 文件末尾添加
3. 重新运行测试确认
### Q: PO 文件太大,如何组织?
A: 考虑按模块添加注释分隔:
```po
# ============================================================================
# Avatar System
# ============================================================================
msgid "Name"
msgstr "名字"
```
### Q: 如何在代码中动态生成 msgid
A: 不推荐。msgid 应该是静态的字符串字面量,便于提取和管理。
---
## 更多资源
- [Python gettext 文档](https://docs.python.org/3/library/gettext.html)
- [GNU gettext 手册](https://www.gnu.org/software/gettext/manual/)
- [项目 i18n 使用指南](../docs/i18n-action-usage.md)