Removed an old run configuration, added a new coverage XML report, and updated multiple source files including main.py, middleware, models, routers, services, tests, and utility modules. Also updated pyproject.toml and the lock file. These changes likely include code improvements, test coverage updates, and dependency adjustments.
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 # 本文档
运行测试
安装依赖
# 使用 uv (推荐)
uv sync
# 或使用 pip
pip install -e .
运行所有测试
pytest
运行特定测试文件
# 测试模型层
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
运行特定测试函数
pytest tests/unit/models/test_base.py::test_table_base_add_single
运行带覆盖率的测试
# 生成覆盖率报告
pytest --cov
# 生成 HTML 覆盖率报告
pytest --cov --cov-report=html
# 查看 HTML 报告
# 打开 htmlcov/index.html
并行测试
# 使用所有 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. 导入错误
确保从项目根目录运行测试:
cd c:\Users\Administrator\Documents\Code\Server
pytest
3. 异步测试错误
项目已配置 pytest-asyncio,使用 @pytest.mark.asyncio 装饰器即可。
4. Fixture 依赖错误
检查 conftest.py 中是否定义了所需的 fixture,确保使用正确的参数名。
编写新测试
模板
"""
模块名称的单元测试
"""
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%),确保新代码有足够的测试覆盖。
# 检查覆盖率是否达标
pytest --cov --cov-fail-under=80