""" 单元测试套件 - 工具类测试 测试范围: 1. 日期时间工具类 2. 字符串处理工具类 3. 数据验证工具类 4. 加密工具类 作者: 张翔 日期: 2026-04-01 """ import pytest from datetime import datetime from utils.date_helper import DateHelper from utils.string_helper import StringHelper from utils.validator import Validator @pytest.mark.unit class TestDateHelper: """日期时间工具类测试""" def test_format_datetime(self): """ UNIT-DATE-01: 日期时间格式化测试 验证点: 1. 正确格式化日期时间 2. 支持多种格式 3. 处理空值 """ test_datetime = datetime(2026, 4, 1, 12, 30, 45) formatted = DateHelper.format_datetime(test_datetime) assert formatted is not None assert isinstance(formatted, str) assert len(formatted) > 0 def test_parse_datetime(self): """ UNIT-DATE-02: 日期时间解析测试 验证点: 1. 正确解析字符串为日期时间 2. 处理无效格式 """ date_string = "2026-04-01 12:30:45" parsed = DateHelper.parse_datetime(date_string) assert parsed is not None assert isinstance(parsed, datetime) def test_date_range_calculation(self): """ UNIT-DATE-03: 日期范围计算测试 验证点: 1. 正确计算日期范围 2. 处理边界情况 """ start_date = datetime(2026, 4, 1) end_date = datetime(2026, 4, 10) days = DateHelper.days_between(start_date, end_date) assert days == 9 def test_timezone_conversion(self): """ UNIT-DATE-04: 时区转换测试 验证点: 1. 正确转换时区 2. 处理不同时区 """ utc_time = datetime(2026, 4, 1, 12, 0, 0) local_time = DateHelper.utc_to_local(utc_time) assert local_time is not None @pytest.mark.unit class TestStringHelper: """字符串处理工具类测试""" def test_truncate_string(self): """ UNIT-STR-01: 字符串截断测试 验证点: 1. 正确截断字符串 2. 添加省略号 3. 处理短字符串 """ long_string = "这是一个非常长的字符串,需要被截断处理" truncated = StringHelper.truncate(long_string, max_length=10) assert len(truncated) <= 13 assert "..." in truncated or len(truncated) <= 10 def test_mask_sensitive_data(self): """ UNIT-STR-02: 敏感数据脱敏测试 验证点: 1. 正确脱敏手机号 2. 正确脱敏邮箱 3. 正确脱敏身份证号 """ phone = "13800138000" email = "test@example.com" id_card = "110101199001011234" masked_phone = StringHelper.mask_phone(phone) masked_email = StringHelper.mask_email(email) masked_id = StringHelper.mask_id_card(id_card) assert "*" in masked_phone assert "@" in masked_email assert "*" in masked_id def test_generate_random_string(self): """ UNIT-STR-03: 随机字符串生成测试 验证点: 1. 生成指定长度字符串 2. 字符串唯一性 3. 包含指定字符集 """ length = 16 random_str1 = StringHelper.random_string(length) random_str2 = StringHelper.random_string(length) assert len(random_str1) == length assert len(random_str2) == length assert random_str1 != random_str2 def test_camel_to_snake_case(self): """ UNIT-STR-04: 命名风格转换测试 验证点: 1. 驼峰转下划线 2. 下划线转驼峰 """ camel_case = "userName" snake_case = "user_name" result = StringHelper.camel_to_snake(camel_case) assert result == snake_case @pytest.mark.unit class TestValidator: """数据验证工具类测试""" def test_validate_email(self): """ UNIT-VAL-01: 邮箱验证测试 验证点: 1. 正确验证邮箱格式 2. 拒绝无效邮箱 """ valid_emails = [ "test@example.com", "user.name@example.co.uk", "user+tag@example.com" ] invalid_emails = [ "invalid-email", "@example.com", "user@", "user @example.com" ] for email in valid_emails: assert Validator.is_valid_email(email), \ f"应接受有效邮箱: {email}" for email in invalid_emails: assert not Validator.is_valid_email(email), \ f"应拒绝无效邮箱: {email}" def test_validate_phone(self): """ UNIT-VAL-02: 手机号验证测试 验证点: 1. 正确验证手机号格式 2. 拒绝无效手机号 """ valid_phones = [ "13800138000", "15912345678", "18600001111" ] invalid_phones = [ "12345678901", "1380013800", "138001380001", "abcdefghijk" ] for phone in valid_phones: assert Validator.is_valid_phone(phone), \ f"应接受有效手机号: {phone}" for phone in invalid_phones: assert not Validator.is_valid_phone(phone), \ f"应拒绝无效手机号: {phone}" def test_validate_username(self): """ UNIT-VAL-03: 用户名验证测试 验证点: 1. 正确验证用户名格式 2. 长度限制 3. 字符限制 """ valid_usernames = [ "admin", "user123", "test_user", "user-name" ] invalid_usernames = [ "ab", "a" * 51, "user@name", "user name" ] for username in valid_usernames: assert Validator.is_valid_username(username), \ f"应接受有效用户名: {username}" for username in invalid_usernames: assert not Validator.is_valid_username(username), \ f"应拒绝无效用户名: {username}" def test_validate_password_strength(self): """ UNIT-VAL-04: 密码强度验证测试 验证点: 1. 长度要求 2. 复杂度要求 3. 常见密码拒绝 """ strong_passwords = [ "Test123!@#", "StrongP@ssw0rd", "C0mpl3x!Pass" ] weak_passwords = [ "123456", "password", "abc123", "Test123" ] for password in strong_passwords: assert Validator.is_strong_password(password), \ f"应接受强密码: {password}" for password in weak_passwords: assert not Validator.is_strong_password(password), \ f"应拒绝弱密码: {password}" def test_validate_id_card(self): """ UNIT-VAL-05: 身份证号验证测试 验证点: 1. 18位身份证验证 2. 校验码验证 """ valid_id_cards = [ "110101199003077654", "440524198001010012", "11010119900307765X" ] invalid_id_cards = [ "123456789012345678", "abcdefghij", "11010119900307765" ] for id_card in valid_id_cards: result = Validator.is_valid_id_card(id_card) for id_card in invalid_id_cards: assert not Validator.is_valid_id_card(id_card), \ f"应拒绝无效身份证: {id_card}" def test_sanitize_input(self): """ UNIT-VAL-06: 输入清洗测试 验证点: 1. 移除危险字符 2. 转义特殊字符 3. 保留安全内容 """ dangerous_inputs = [ "", "'; DROP TABLE users; --", "../../../etc/passwd" ] for dangerous_input in dangerous_inputs: sanitized = Validator.sanitize(dangerous_input) assert "