""" 测试数据生成器模块 """ import random import string from datetime import datetime, timedelta from typing import Dict, Any, List import hashlib class TestDataGenerator: """测试数据生成器""" @staticmethod def random_string(length: int = 10) -> str: """ 生成随机字符串 Args: length: 字符串长度 Returns: 随机字符串 """ return ''.join(random.choices(string.ascii_letters + string.digits, k=length)) @staticmethod def random_email() -> str: """ 生成随机邮箱 Returns: 随机邮箱 """ username = TestDataGenerator.random_string(8) domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'example.com'] domain = random.choice(domains) return f"{username}@{domain}" @staticmethod def random_phone() -> str: """ 生成随机手机号 Returns: 随机手机号 """ return f"1{random.choice([3, 5, 7, 8, 9])}{random.randint(100000000, 999999999)}" @staticmethod def random_password(length: int = 12) -> str: """ 生成随机密码 Args: length: 密码长度 Returns: 随机密码 """ chars = string.ascii_letters + string.digits + "!@#$%^&*" return ''.join(random.choices(chars, k=length)) @staticmethod def random_int(min_val: int = 0, max_val: int = 100) -> int: """ 生成随机整数 Args: min_val: 最小值 max_val: 最大值 Returns: 随机整数 """ return random.randint(min_val, max_val) @staticmethod def random_float(min_val: float = 0.0, max_val: float = 100.0, decimals: int = 2) -> float: """ 生成随机浮点数 Args: min_val: 最小值 max_val: 最大值 decimals: 小数位数 Returns: 随机浮点数 """ return round(random.uniform(min_val, max_val), decimals) @staticmethod def random_date(start_year: int = 2020, end_year: int = 2025) -> datetime: """ 生成随机日期 Args: start_year: 起始年份 end_year: 结束年份 Returns: 随机日期 """ start_date = datetime(start_year, 1, 1) end_date = datetime(end_year, 12, 31) delta = end_date - start_date random_days = random.randint(0, delta.days) return start_date + timedelta(days=random_days) @staticmethod def random_boolean() -> bool: """ 生成随机布尔值 Returns: 随机布尔值 """ return random.choice([True, False]) @staticmethod def random_choice(choices: List[Any]) -> Any: """ 从列表中随机选择一个值 Args: choices: 选项列表 Returns: 随机选择的值 """ return random.choice(choices) @staticmethod def generate_user_data(overrides: Dict[str, Any] = None) -> Dict[str, Any]: """ 生成用户数据 Args: overrides: 覆盖的默认值 Returns: 用户数据 """ username = TestDataGenerator.random_string(8) data = { "username": username, "password": "Test@123", "email": f"{username}@example.com", "phone": TestDataGenerator.random_phone(), "nickname": f"用户{username}", "status": 1, "roleIds": [] } if overrides: data.update(overrides) return data @staticmethod def generate_admin_data(overrides: Dict[str, Any] = None) -> Dict[str, Any]: """ 生成管理员数据 Args: overrides: 覆盖的默认值 Returns: 管理员数据 """ data = TestDataGenerator.generate_user_data({ "username": "admin", "password": "admin123", "email": "admin@example.com", "nickname": "管理员", "roleIds": [1] }) if overrides: data.update(overrides) return data @staticmethod def generate_role_data(overrides: Dict[str, Any] = None) -> Dict[str, Any]: """ 生成角色数据 Args: overrides: 覆盖的默认值 Returns: 角色数据 """ role_code = f"role_{TestDataGenerator.random_string(6).lower()}" data = { "roleName": f"测试角色{role_code}", "roleCode": role_code, "description": f"这是一个测试角色{role_code}", "status": 1, "sort": TestDataGenerator.random_int(1, 100) } if overrides: data.update(overrides) return data @staticmethod def generate_menu_data(overrides: Dict[str, Any] = None) -> Dict[str, Any]: """ 生成菜单数据 Args: overrides: 覆盖的默认值 Returns: 菜单数据 """ menu_code = f"menu_{TestDataGenerator.random_string(6).lower()}" data = { "menuName": f"测试菜单{menu_code}", "menuCode": menu_code, "menuType": 1, "path": f"/{menu_code}", "component": f"{menu_code}/index", "icon": "SettingOutlined", "parentId": 0, "sort": TestDataGenerator.random_int(1, 100), "status": 0, "visible": 1 } if overrides: data.update(overrides) return data @staticmethod def generate_permission_data(overrides: Dict[str, Any] = None) -> Dict[str, Any]: """ 生成权限数据 Args: overrides: 覆盖的默认值 Returns: 权限数据 """ permission_code = f"perm:{TestDataGenerator.random_string(6).lower()}" data = { "permissionName": f"测试权限{permission_code}", "permissionCode": permission_code, "permissionType": "button", "description": f"这是一个测试权限{permission_code}", "status": 1 } if overrides: data.update(overrides) return data @staticmethod def generate_user_list(count: int, overrides: Dict[str, Any] = None) -> List[Dict[str, Any]]: """ 批量生成用户数据 Args: count: 生成数量 overrides: 覆盖的默认值 Returns: 用户数据列表 """ return [TestDataGenerator.generate_user_data(overrides) for _ in range(count)] @staticmethod def generate_role_list(count: int, overrides: Dict[str, Any] = None) -> List[Dict[str, Any]]: """ 批量生成角色数据 Args: count: 生成数量 overrides: 覆盖的默认值 Returns: 角色数据列表 """ return [TestDataGenerator.generate_role_data(overrides) for _ in range(count)] @staticmethod def generate_menu_list(count: int, overrides: Dict[str, Any] = None) -> List[Dict[str, Any]]: """ 批量生成菜单数据 Args: count: 生成数量 overrides: 覆盖的默认值 Returns: 菜单数据列表 """ return [TestDataGenerator.generate_menu_data(overrides) for _ in range(count)] @staticmethod def generate_pagination_data(data: List[Any], page: int = 1, page_size: int = 10) -> Dict[str, Any]: """ 生成分页数据 Args: data: 原始数据列表 page: 当前页码 page_size: 每页数量 Returns: 分页数据 """ total = len(data) total_pages = (total + page_size - 1) // page_size start_index = (page - 1) * page_size end_index = start_index + page_size page_data = data[start_index:end_index] return { "records": page_data, "total": total, "page": page, "pageSize": page_size, "totalPages": total_pages } @staticmethod def generate_search_query(keyword: str = None) -> Dict[str, Any]: """ 生成搜索查询 Args: keyword: 搜索关键词 Returns: 搜索查询参数 """ query = { "keyword": keyword or TestDataGenerator.random_string(5), "page": TestDataGenerator.random_int(1, 10), "pageSize": random.choice([10, 20, 50, 100]), "sortField": "createTime", "sortOrder": random.choice(["asc", "desc"]) } return query @staticmethod def generate_test_credentials() -> Dict[str, Dict[str, str]]: """ 生成测试凭据 Returns: 测试凭据字典 """ return { "admin": { "username": "admin", "password": "admin123" }, "user": { "username": "testuser", "password": "test123" } } @staticmethod def generate_hash(data: str) -> str: """ 生成数据的哈希值 Args: data: 原始数据 Returns: 哈希值 """ return hashlib.md5(data.encode()).hexdigest()