Files
disknext/tests/IMPLEMENTATION_SUMMARY.md
于小丘 f93cb3eedb 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.
2025-12-19 19:48:05 +08:00

9.3 KiB
Raw Permalink Blame History

DiskNext Server 单元测试实现总结

概述

本次任务完成了 DiskNext Server 项目的单元测试实现,覆盖了模型层、工具层和服务层的核心功能。

实现的测试文件

1. 配置文件

文件: tests/conftest.py

提供了测试所需的所有 fixtures:

  • 数据库相关:

    • test_engine: 内存 SQLite 数据库引擎
    • initialized_db: 已初始化表结构的数据库
    • db_session: 数据库会话(每个测试函数独立)
  • 用户相关:

    • test_user: 创建测试用户
    • admin_user: 创建管理员用户
    • auth_headers: 测试用户的认证请求头
    • admin_headers: 管理员的认证请求头
  • 数据相关:

    • test_directory: 创建测试目录结构

2. 模型层测试 (tests/unit/models/)

test_base.py - TableBase 和 UUIDTableBase 基类测试

测试用例数: 14个

  • test_table_base_add_single - 单条记录创建
  • test_table_base_add_batch - 批量创建
  • test_table_base_save - save() 方法
  • test_table_base_update - update() 方法
  • test_table_base_delete - delete() 方法
  • test_table_base_get_first - get() fetch_mode="first"
  • test_table_base_get_one - get() fetch_mode="one"
  • test_table_base_get_all - get() fetch_mode="all"
  • test_table_base_get_with_pagination - offset/limit 分页
  • test_table_base_get_exist_one_found - 存在时返回
  • test_table_base_get_exist_one_not_found - 不存在时抛出 HTTPException 404
  • test_uuid_table_base_id_generation - UUID 自动生成
  • test_timestamps_auto_update - created_at/updated_at 自动维护

覆盖的核心方法:

  • add() - 单条和批量添加
  • save() - 保存实例
  • update() - 更新实例
  • delete() - 删除实例
  • get() - 查询(三种模式)
  • get_exist_one() - 查询存在或抛出异常

test_user.py - User 模型测试

测试用例数: 7个

  • test_user_create - 创建用户
  • test_user_unique_username - 用户名唯一约束
  • test_user_to_public - to_public() DTO 转换
  • test_user_group_relationship - 用户与用户组关系
  • test_user_status_default - status 默认值
  • test_user_storage_default - storage 默认值
  • test_user_theme_enum - ThemeType 枚举

覆盖的特性:

  • 用户创建和字段验证
  • 唯一约束检查
  • DTO 转换(排除敏感字段)
  • 关系加载(用户组)
  • 默认值验证
  • 枚举类型使用

test_group.py - Group 和 GroupOptions 模型测试

测试用例数: 4个

  • test_group_create - 创建用户组
  • test_group_options_relationship - 用户组与选项一对一关系
  • test_group_to_response - to_response() DTO 转换
  • test_group_policies_relationship - 多对多关系

覆盖的特性:

  • 用户组创建
  • 一对一关系GroupOptions
  • DTO 转换逻辑
  • 多对多关系policies

test_object.py - Object 模型测试

测试用例数: 12个

  • test_object_create_folder - 创建目录
  • test_object_create_file - 创建文件
  • test_object_is_file_property - is_file 属性
  • test_object_is_folder_property - is_folder 属性
  • test_object_get_root - get_root() 方法
  • test_object_get_by_path_root - 获取根目录
  • test_object_get_by_path_nested - 获取嵌套路径
  • test_object_get_by_path_not_found - 路径不存在
  • test_object_get_children - get_children() 方法
  • test_object_parent_child_relationship - 父子关系
  • test_object_unique_constraint - 同目录名称唯一

覆盖的特性:

  • 文件和目录创建
  • 属性判断is_file, is_folder
  • 根目录获取
  • 路径解析(支持嵌套)
  • 子对象获取
  • 父子关系
  • 唯一性约束

test_setting.py - Setting 模型测试

测试用例数: 7个

  • test_setting_create - 创建设置
  • test_setting_unique_type_name - type+name 唯一约束
  • test_settings_type_enum - SettingsType 枚举
  • test_setting_update_value - 更新设置值
  • test_setting_nullable_value - value 可为空
  • test_setting_get_by_type_and_name - 通过 type 和 name 查询
  • test_setting_get_all_by_type - 获取某类型的所有设置

覆盖的特性:

  • 设置项创建
  • 复合唯一约束
  • 枚举类型
  • 更新操作
  • 空值处理
  • 复合查询

3. 工具层测试 (tests/unit/utils/)

test_password.py - Password 工具类测试

测试用例数: 10个

  • test_password_generate_default_length - 默认长度生成
  • test_password_generate_custom_length - 自定义长度
  • test_password_hash - 密码哈希
  • test_password_verify_valid - 正确密码验证
  • test_password_verify_invalid - 错误密码验证
  • test_totp_generate - TOTP 密钥生成
  • test_totp_verify_valid - TOTP 验证正确
  • test_totp_verify_invalid - TOTP 验证错误
  • test_password_hash_consistency - 哈希一致性(盐随机)
  • test_password_generate_uniqueness - 密码唯一性

覆盖的方法:

  • Password.generate() - 密码生成
  • Password.hash() - 密码哈希
  • Password.verify() - 密码验证
  • Password.generate_totp() - TOTP 生成
  • Password.verify_totp() - TOTP 验证

test_jwt.py - JWT 工具测试

测试用例数: 10个

  • test_create_access_token - 访问令牌创建
  • test_create_access_token_custom_expiry - 自定义过期时间
  • test_create_refresh_token - 刷新令牌创建
  • test_token_decode - 令牌解码
  • test_token_expired - 令牌过期
  • test_token_invalid_signature - 无效签名
  • test_access_token_does_not_have_token_type - 访问令牌无 token_type
  • test_refresh_token_has_token_type - 刷新令牌有 token_type
  • test_token_payload_preserved - 自定义负载保留
  • test_create_refresh_token_default_expiry - 默认30天过期

覆盖的方法:

  • create_access_token() - 访问令牌
  • create_refresh_token() - 刷新令牌
  • JWT 解码和验证

4. 服务层测试 (tests/unit/service/)

test_login.py - Login 服务测试

测试用例数: 8个

  • test_login_success - 正常登录
  • test_login_user_not_found - 用户不存在
  • test_login_wrong_password - 密码错误
  • test_login_user_banned - 用户被封禁
  • test_login_2fa_required - 需要 2FA
  • test_login_2fa_invalid - 2FA 错误
  • test_login_2fa_success - 2FA 成功
  • test_login_case_sensitive_username - 用户名大小写敏感

覆盖的场景:

  • 正常登录流程
  • 用户不存在
  • 密码错误
  • 用户状态检查
  • 两步验证流程
  • 边界情况

测试统计

测试模块 文件数 测试用例数
模型层 4 44
工具层 2 20
服务层 1 8
总计 7 72

技术栈

  • 测试框架: pytest
  • 异步支持: pytest-asyncio
  • 数据库: SQLite (内存)
  • ORM: SQLModel
  • 覆盖率: pytest-cov

运行测试

快速开始

# 安装依赖
uv sync

# 运行所有测试
pytest

# 运行特定模块
python run_tests.py models
python run_tests.py utils
python run_tests.py service

# 带覆盖率运行
pytest --cov

详细文档

参见 tests/README.md 获取详细的测试文档和使用指南。

测试设计原则

  1. 隔离性: 每个测试函数使用独立的数据库会话,测试之间互不影响
  2. 可读性: 使用简体中文 docstring,清晰描述测试目的
  3. 完整性: 覆盖正常流程、异常流程和边界情况
  4. 真实性: 使用真实的数据库操作,而非 Mock
  5. 可维护性: 使用 fixtures 复用测试数据和配置

符合项目规范

  • 使用 Python 3.10+ 类型注解
  • 所有异步测试使用 @pytest.mark.asyncio
  • 使用简体中文 docstring
  • 遵循 test_功能_场景 命名规范
  • 使用 conftest.py 管理 fixtures
  • 禁止使用 Mock除非必要

未来工作

可扩展的测试点

  1. 集成测试: 测试 API 端点的完整流程
  2. 性能测试: 使用 pytest-benchmark 测试性能
  3. 并发测试: 测试并发场景下的数据一致性
  4. Edge Cases: 更多边界情况和异常场景

建议添加的测试

  1. Policy 模型的完整测试
  2. GroupPolicyLink 多对多关系测试
  3. Object 的文件上传/下载测试
  4. 更多服务层的业务逻辑测试

注意事项

  1. SQLite 限制: 内存数据库不支持某些特性(如 onupdate),部分测试可能需要根据实际数据库调整
  2. Secret Key: JWT 测试使用测试专用密钥,与生产环境隔离
  3. TOTP 时间敏感: TOTP 测试依赖系统时间,确保系统时钟准确

贡献者指南

编写新测试时:

  1. 在对应的目录下创建 test_<module>.py 文件
  2. 使用 conftest.py 中的 fixtures
  3. 遵循现有的命名和结构规范
  4. 确保测试独立且可重复运行
  5. 添加清晰的 docstring

总结

本次实现完成了 DiskNext Server 项目的单元测试基础设施,包括:

  • 完整的 pytest 配置
  • 72 个测试用例覆盖核心功能
  • 灵活的 fixtures 系统
  • 详细的测试文档
  • 便捷的测试运行脚本

所有测试均遵循项目规范,使用异步数据库操作,确保测试的真实性和可靠性。