Add unit tests for models and services
- Implemented unit tests for Object model including folder and file creation, properties, and path retrieval. - Added unit tests for Setting model covering creation, unique constraints, and type enumeration. - Created unit tests for User model focusing on user creation, uniqueness, and group relationships. - Developed unit tests for Login service to validate login functionality, including 2FA and token generation. - Added utility tests for JWT creation and verification, ensuring token integrity and expiration handling. - Implemented password utility tests for password generation, hashing, and TOTP verification.
This commit is contained in:
246
tests/README.md
Normal file
246
tests/README.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# DiskNext Server 单元测试文档
|
||||
|
||||
## 测试结构
|
||||
|
||||
```
|
||||
tests/
|
||||
├── conftest.py # Pytest 配置和 fixtures
|
||||
├── unit/ # 单元测试
|
||||
│ ├── models/ # 模型层测试
|
||||
│ │ ├── test_base.py # TableBase/UUIDTableBase 测试
|
||||
│ │ ├── test_user.py # User 模型测试
|
||||
│ │ ├── test_group.py # Group/GroupOptions 测试
|
||||
│ │ ├── test_object.py # Object 模型测试
|
||||
│ │ └── test_setting.py # Setting 模型测试
|
||||
│ ├── utils/ # 工具层测试
|
||||
│ │ ├── test_password.py # Password 工具测试
|
||||
│ │ └── test_jwt.py # JWT 工具测试
|
||||
│ └── service/ # 服务层测试
|
||||
│ └── test_login.py # Login 服务测试
|
||||
└── README.md # 本文档
|
||||
|
||||
```
|
||||
|
||||
## 运行测试
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
# 使用 uv (推荐)
|
||||
uv sync
|
||||
|
||||
# 或使用 pip
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
### 运行所有测试
|
||||
|
||||
```bash
|
||||
pytest
|
||||
```
|
||||
|
||||
### 运行特定测试文件
|
||||
|
||||
```bash
|
||||
# 测试模型层
|
||||
pytest tests/unit/models/test_base.py
|
||||
|
||||
# 测试用户模型
|
||||
pytest tests/unit/models/test_user.py
|
||||
|
||||
# 测试工具层
|
||||
pytest tests/unit/utils/test_password.py
|
||||
|
||||
# 测试服务层
|
||||
pytest tests/unit/service/test_login.py
|
||||
```
|
||||
|
||||
### 运行特定测试函数
|
||||
|
||||
```bash
|
||||
pytest tests/unit/models/test_base.py::test_table_base_add_single
|
||||
```
|
||||
|
||||
### 运行带覆盖率的测试
|
||||
|
||||
```bash
|
||||
# 生成覆盖率报告
|
||||
pytest --cov
|
||||
|
||||
# 生成 HTML 覆盖率报告
|
||||
pytest --cov --cov-report=html
|
||||
|
||||
# 查看 HTML 报告
|
||||
# 打开 htmlcov/index.html
|
||||
```
|
||||
|
||||
### 并行测试
|
||||
|
||||
```bash
|
||||
# 使用所有 CPU 核心
|
||||
pytest -n auto
|
||||
|
||||
# 使用指定数量的核心
|
||||
pytest -n 4
|
||||
```
|
||||
|
||||
## Fixtures 说明
|
||||
|
||||
### 数据库相关
|
||||
|
||||
- `test_engine`: 内存 SQLite 数据库引擎
|
||||
- `initialized_db`: 已初始化表结构的数据库
|
||||
- `db_session`: 数据库会话(每个测试函数独立)
|
||||
|
||||
### 用户相关(在 conftest.py 中已提供)
|
||||
|
||||
- `test_user`: 创建测试用户,返回 {id, username, password, token, group_id, policy_id}
|
||||
- `admin_user`: 创建管理员用户
|
||||
- `auth_headers`: 测试用户的认证请求头
|
||||
- `admin_headers`: 管理员的认证请求头
|
||||
|
||||
### 数据相关
|
||||
|
||||
- `test_directory`: 为测试用户创建目录结构
|
||||
|
||||
## 测试覆盖范围
|
||||
|
||||
### 模型层 (tests/unit/models/)
|
||||
|
||||
#### test_base.py - TableBase/UUIDTableBase
|
||||
- ✅ 单条记录创建
|
||||
- ✅ 批量创建
|
||||
- ✅ save() 方法
|
||||
- ✅ update() 方法
|
||||
- ✅ delete() 方法
|
||||
- ✅ get() 三种 fetch_mode
|
||||
- ✅ offset/limit 分页
|
||||
- ✅ get_exist_one() 存在/不存在场景
|
||||
- ✅ UUID 自动生成
|
||||
- ✅ 时间戳自动维护
|
||||
|
||||
#### test_user.py - User 模型
|
||||
- ✅ 创建用户
|
||||
- ✅ 用户名唯一约束
|
||||
- ✅ to_public() DTO 转换
|
||||
- ✅ 用户与用户组关系
|
||||
- ✅ status 默认值
|
||||
- ✅ storage 默认值
|
||||
- ✅ ThemeType 枚举
|
||||
|
||||
#### test_group.py - Group/GroupOptions 模型
|
||||
- ✅ 创建用户组
|
||||
- ✅ 用户组与选项一对一关系
|
||||
- ✅ to_response() DTO 转换
|
||||
- ✅ 多对多关系(policies)
|
||||
|
||||
#### test_object.py - Object 模型
|
||||
- ✅ 创建目录
|
||||
- ✅ 创建文件
|
||||
- ✅ is_file 属性
|
||||
- ✅ is_folder 属性
|
||||
- ✅ get_root() 方法
|
||||
- ✅ get_by_path() 根目录
|
||||
- ✅ get_by_path() 嵌套路径
|
||||
- ✅ get_by_path() 路径不存在
|
||||
- ✅ get_children() 方法
|
||||
- ✅ 父子关系
|
||||
- ✅ 同目录名称唯一约束
|
||||
|
||||
#### test_setting.py - Setting 模型
|
||||
- ✅ 创建设置
|
||||
- ✅ type+name 唯一约束
|
||||
- ✅ SettingsType 枚举
|
||||
- ✅ 更新设置值
|
||||
|
||||
### 工具层 (tests/unit/utils/)
|
||||
|
||||
#### test_password.py - Password 工具
|
||||
- ✅ 默认长度生成密码
|
||||
- ✅ 自定义长度生成密码
|
||||
- ✅ 密码哈希
|
||||
- ✅ 正确密码验证
|
||||
- ✅ 错误密码验证
|
||||
- ✅ TOTP 密钥生成
|
||||
- ✅ TOTP 验证正确
|
||||
- ✅ TOTP 验证错误
|
||||
|
||||
#### test_jwt.py - JWT 工具
|
||||
- ✅ 访问令牌创建
|
||||
- ✅ 自定义过期时间
|
||||
- ✅ 刷新令牌创建
|
||||
- ✅ 令牌解码
|
||||
- ✅ 令牌过期
|
||||
- ✅ 无效签名
|
||||
|
||||
### 服务层 (tests/unit/service/)
|
||||
|
||||
#### test_login.py - Login 服务
|
||||
- ✅ 正常登录
|
||||
- ✅ 用户不存在
|
||||
- ✅ 密码错误
|
||||
- ✅ 用户被封禁
|
||||
- ✅ 需要 2FA
|
||||
- ✅ 2FA 错误
|
||||
- ✅ 2FA 成功
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 数据库连接错误
|
||||
|
||||
所有测试使用内存 SQLite 数据库,不需要外部数据库服务。
|
||||
|
||||
### 2. 导入错误
|
||||
|
||||
确保从项目根目录运行测试:
|
||||
|
||||
```bash
|
||||
cd c:\Users\Administrator\Documents\Code\Server
|
||||
pytest
|
||||
```
|
||||
|
||||
### 3. 异步测试错误
|
||||
|
||||
项目已配置 `pytest-asyncio`,使用 `@pytest.mark.asyncio` 装饰器即可。
|
||||
|
||||
### 4. Fixture 依赖错误
|
||||
|
||||
检查 conftest.py 中是否定义了所需的 fixture,确保使用正确的参数名。
|
||||
|
||||
## 编写新测试
|
||||
|
||||
### 模板
|
||||
|
||||
```python
|
||||
"""
|
||||
模块名称的单元测试
|
||||
"""
|
||||
import pytest
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from models.xxx import YourModel
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_your_feature(db_session: AsyncSession):
|
||||
"""测试功能描述"""
|
||||
# 准备数据
|
||||
instance = YourModel(field="value")
|
||||
instance = await instance.save(db_session)
|
||||
|
||||
# 执行操作
|
||||
result = await YourModel.get(db_session, YourModel.id == instance.id)
|
||||
|
||||
# 断言验证
|
||||
assert result is not None
|
||||
assert result.field == "value"
|
||||
```
|
||||
|
||||
## 持续集成
|
||||
|
||||
项目配置了覆盖率要求(80%),确保新代码有足够的测试覆盖。
|
||||
|
||||
```bash
|
||||
# 检查覆盖率是否达标
|
||||
pytest --cov --cov-fail-under=80
|
||||
```
|
||||
Reference in New Issue
Block a user