feat(zh): add Chinese translations in zh/ directory

Add Chinese (Simplified) translations for all documentation, organized
under a dedicated zh/ directory that mirrors the English folder structure.

Co-authored-by: tanqingkuang <tanqingkuang@users.noreply.github.com>

Translations originally contributed by @tanqingkuang in #45.
Restructured from *-CN.md suffix pattern into zh/ directory to prevent
the EPUB builder (scripts/build_epub.py collect_folder_files) from
picking up Chinese files via glob("*.md") inside module folders.
This commit is contained in:
Luong NGUYEN
2026-04-06 23:08:54 +02:00
committed by GitHub
parent 100c45eef2
commit 89e89d4aa3
100 changed files with 20487 additions and 1 deletions

341
zh/.github/TESTING.md vendored Normal file
View File

@@ -0,0 +1,341 @@
# 测试指南
本文档说明 Claude How To 的测试基础设施。
## 概览
项目使用 GitHub Actions 在每次 push 和 pull request 时自动运行测试。测试覆盖:
- **单元测试**:使用 pytest 的 Python 测试
- **代码质量**:使用 Ruff 做 lint 和格式化
- **安全**:使用 Bandit 做漏洞扫描
- **类型检查**:使用 mypy 做静态类型分析
- **构建验证**EPUB 生成测试
## 在本地运行测试
### 前置条件
```bash
# 安装 uv快速 Python 包管理器)
pip install uv
# 或者在 macOS 上使用 Homebrew
brew install uv
```
### 配置环境
```bash
# 克隆仓库
git clone https://github.com/luongnv89/claude-howto.git
cd claude-howto
# 创建虚拟环境
uv venv
# 激活虚拟环境
source .venv/bin/activate # macOS/Linux
# 或者
.venv\Scripts\activate # Windows
# 安装开发依赖
uv pip install -r requirements-dev.txt
```
### 运行测试
```bash
# 运行所有单元测试
pytest scripts/tests/ -v
# 运行带覆盖率的测试
pytest scripts/tests/ -v --cov=scripts --cov-report=html
# 运行指定测试文件
pytest scripts/tests/test_build_epub.py -v
# 运行指定测试函数
pytest scripts/tests/test_build_epub.py::test_function_name -v
# 以 watch 模式运行测试(需要 pytest-watch
ptw scripts/tests/
```
### 运行 lint
```bash
# 检查代码格式
ruff format --check scripts/
# 自动修复格式问题
ruff format scripts/
# 运行 lint
ruff check scripts/
# 自动修复 lint 问题
ruff check --fix scripts/
```
### 运行安全扫描
```bash
# 运行 Bandit 安全扫描
bandit -c pyproject.toml -r scripts/ --exclude scripts/tests/
# 生成 JSON 报告
bandit -c pyproject.toml -r scripts/ --exclude scripts/tests/ -f json -o bandit-report.json
```
### 运行类型检查
```bash
# 使用 mypy 检查类型
mypy scripts/ --ignore-missing-imports --no-implicit-optional
```
## GitHub Actions 工作流
### 触发条件
- 推送到 `main``develop` 分支(当 `scripts` 有变更时)
-`main` 提交 Pull Request`scripts` 有变更时)
- 手动触发 workflow
### 作业
#### 1. 单元测试pytest
- **运行环境**Ubuntu latest
- **Python 版本**3.10、3.11、3.12
- **执行内容**
-`requirements-dev.txt` 安装依赖
- 运行 pytest 并生成覆盖率报告
- 将覆盖率上传到 Codecov
- 归档测试结果和 HTML 覆盖率报告
**结果**:如果任何测试失败,工作流失败(关键)
#### 2. 代码质量Ruff
- **运行环境**Ubuntu latest
- **Python 版本**3.11
- **执行内容**
- 使用 `ruff format` 检查格式
- 使用 `ruff check` 运行 lint
- 报告问题,但不会让整个工作流失败
**结果**:非阻塞(仅警告)
#### 3. 安全扫描Bandit
- **运行环境**Ubuntu latest
- **Python 版本**3.11
- **执行内容**
- 扫描安全漏洞
- 生成 JSON 报告
- 将报告作为 artifact 上传
**结果**:非阻塞(仅警告)
#### 4. 类型检查mypy
- **运行环境**Ubuntu latest
- **Python 版本**3.11
- **执行内容**
- 执行静态类型分析
- 报告类型不匹配
- 帮助尽早发现 bug
**结果**:非阻塞(仅警告)
#### 5. 构建 EPUB
- **运行环境**Ubuntu latest
- **依赖**pytest、lint、安全扫描都必须通过
- **执行内容**
- 使用 `scripts/build_epub.py` 构建 EPUB
- 验证 EPUB 是否成功生成
- 将 EPUB 作为 artifact 上传
**结果**:如果构建失败,工作流失败(关键)
#### 6. 总结
- **运行环境**Ubuntu latest
- **依赖**:所有其他作业
- **执行内容**
- 生成工作流总结
- 列出所有 artifacts
- 汇总总体状态
## 编写测试
### 测试结构
测试应放在 `scripts/tests/` 中,文件名形如 `test_*.py`
```python
# scripts/tests/test_example.py
import pytest
from scripts.example_module import some_function
def test_basic_functionality():
"""测试 some_function 是否正常工作。"""
result = some_function("input")
assert result == "expected_output"
def test_error_handling():
"""测试 some_function 是否能优雅处理错误。"""
with pytest.raises(ValueError):
some_function("invalid_input")
@pytest.mark.asyncio
async def test_async_function():
"""测试异步函数。"""
result = await async_function()
assert result is not None
```
### 测试最佳实践
- **使用有描述性的名称**:例如 `test_function_returns_correct_value()`
- **尽量每个测试只做一个断言**:更容易排查失败原因
- **使用 fixture** 复用初始化逻辑:见 `scripts/tests/conftest.py`
- **Mock 外部服务**:使用 `unittest.mock``pytest-mock`
- **测试边界情况**空输入、None 值、错误情况
- **保持测试快速**:避免 `sleep()` 和外部 I/O
- **使用 pytest 标记**:例如 `@pytest.mark.slow` 标记慢测试
### Fixtures
常用 fixture 定义在 `scripts/tests/conftest.py`
```python
# 在测试中使用 fixture
def test_something(tmp_path):
"""tmp_path fixture 提供临时目录。"""
test_file = tmp_path / "test.txt"
test_file.write_text("content")
assert test_file.read_text() == "content"
```
## 覆盖率报告
### 本地覆盖率
```bash
# 生成覆盖率报告
pytest scripts/tests/ --cov=scripts --cov-report=html
# 在浏览器中打开覆盖率报告
open htmlcov/index.html
```
### 覆盖率目标
- **最低覆盖率**80%
- **分支覆盖率**:启用
- **重点区域**:核心功能和错误路径
## Pre-commit Hooks
项目使用 pre-commit hooks 在每次提交前自动运行检查:
```bash
# 安装 pre-commit hooks
pre-commit install
# 手动运行 hooks
pre-commit run --all-files
# 跳过某次提交的 hooks不推荐
git commit --no-verify
```
`.pre-commit-config.yaml` 中配置的 hooks
- Ruff formatter
- Ruff linter
- Bandit security scanner
- YAML validation
- 文件大小检查
- 合并冲突检测
## 排障
### 本地测试通过,但 CI 失败
常见原因:
1. **Python 版本差异**CI 使用 3.10、3.11、3.12
2. **依赖缺失**:更新 `requirements-dev.txt`
3. **平台差异**:路径分隔符、环境变量
4. **测试不稳定**:依赖时序或执行顺序的测试
解决方案:
```bash
# 使用相同的 Python 版本测试
uv python install 3.10 3.11 3.12
# 使用干净环境测试
rm -rf .venv
uv venv
uv pip install -r requirements-dev.txt
pytest scripts/tests/
```
### Bandit 报告误报
某些安全警告可能是误报。可在 `pyproject.toml` 中配置:
```toml
[tool.bandit]
exclude_dirs = ["scripts/tests"]
skips = ["B101"] # 跳过 assert_used 警告
```
### 类型检查太严格
对特定文件放宽类型检查:
```python
# 放在文件顶部
# type: ignore
# 或者针对特定行
some_dynamic_code() # type: ignore
```
## 持续集成最佳实践
1. **保持测试快速**:每个测试最好在 1 秒内完成
2. **不要测试外部 API**:用 mock 替代外部服务
3. **测试要隔离**:每个测试都应独立
4. **断言要清晰**:写 `assert x == 5`,不要写 `assert x`
5. **处理异步测试**:使用 `@pytest.mark.asyncio`
6. **生成报告**:覆盖率、安全扫描、类型检查
## 资源
- [pytest Documentation](https://docs.pytest.org/)
- [Ruff Documentation](https://docs.astral.sh/ruff/)
- [Bandit Documentation](https://bandit.readthedocs.io/)
- [mypy Documentation](https://mypy.readthedocs.io/)
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
## 贡献测试
提交 PR 时:
1. **为新功能编写测试**
2. **本地运行测试**`pytest scripts/tests/ -v`
3. **检查覆盖率**`pytest scripts/tests/ --cov=scripts`
4. **运行 lint**`ruff check scripts/`
5. **安全扫描**`bandit -r scripts/ --exclude scripts/tests/`
6. **如果测试变化,更新文档**
所有 PR 都必须包含测试!🧪
---
如果你对测试有问题或疑问,请在 GitHub 上创建 issue 或 discussion。