""" 测试数据生成模块 提供测试过程中需要的各种测试数据生成功能 """ import random import string import uuid import re from datetime import datetime, timedelta from typing import Any, Dict, List, Optional, Tuple, Union from dataclasses import dataclass, field from faker import Faker from config.settings import get_settings class ChineseFaker: """中文测试数据生成器""" def __init__(self, locale: str = "zh_CN"): self.faker_zh = Faker("zh_CN") self.faker_en = Faker("en_US") def name(self) -> str: """生成中文姓名""" return self.faker_zh.name() def first_name(self) -> str: """生成中文名字""" return self.faker_zh.first_name() def last_name(self) -> str: """生成中文姓氏""" return self.faker_zh.last_name() def phone_number(self) -> str: """生成中国手机号""" # 生成以13-19开头的11位手机号 prefix = random.choice(["13", "14", "15", "16", "17", "18", "19"]) suffix = "".join(random.choices(string.digits, k=8)) return prefix + suffix def email(self, domain: Optional[str] = None) -> str: """生成邮箱""" if domain: return self.faker_zh.email(domain=domain) return self.faker_zh.email() def company_name(self) -> str: """生成公司名称""" prefixes = ["四川", "成都", "西部", "西南", "中国", "高新"] suffixes = ["科技", "信息", "网络", "软件", "数据", "智能", "创新", "未来"] name = f"{random.choice(prefixes)}{self.faker_zh.company()}{random.choice(suffixes)}" return name def address(self) -> str: """生成中文地址""" return self.faker_zh.address().replace("\n", "") def city(self) -> str: """生成城市名""" return self.faker_zh.city() def province(self) -> str: """生成省份名""" return self.faker_zh.province() def job_title(self) -> str: """生成职位名称""" titles = [ "软件工程师", "产品经理", "UI设计师", "测试工程师", "项目主管", "技术总监", "架构师", "数据分析师", "运维工程师", "产品运营", "市场经理", "销售代表" ] return random.choice(titles) def username(self) -> str: """生成用户名""" return self.faker_zh.user_name() def password(self, length: int = 12) -> str: """生成密码""" chars = string.ascii_letters + string.digits + "!@#$%^&*" return "".join(random.choices(chars, k=length)) def text(self, max_chars: int = 200) -> str: """生成随机中文文本""" paragraphs = [] for _ in range(random.randint(1, 3)): sentences = [] for _ in range(random.randint(3, 8)): sentence_len = random.randint(10, 30) sentence = self.faker_zh.sentence(nb_words=sentence_len) sentences.append(sentence) paragraphs.append("。".join(sentences) + "。") return "".join(paragraphs)[:max_chars] def sentence(self, nb_words: int = 20) -> str: """生成随机句子""" return self.faker_zh.sentence(nb_words=nb_words) def word(self) -> str: """生成随机词语""" return self.faker_zh.word() def words(self, nb: int = 5) -> List[str]: """生成随机词语列表""" return self.faker_zh.words(nb=nb) def date_of_birth(self, start_year: int = 1960, end_year: int = 2000) -> str: """生成出生日期""" return self.faker_zh.date_of_birth( minimum_age=end_year - datetime.now().year, maximum_age=start_year - datetime.now().year ).strftime("%Y-%m-%d") def credit_card_number(self) -> str: """生成信用卡号(测试用)""" return self.faker_zh.credit_card_number() def credit_card_provider(self) -> str: """生成信用卡提供商""" providers = ["Visa", "MasterCard", "银联", "JCB", "American Express"] return random.choice(providers) def ipv4(self) -> str: """生成IPv4地址""" return self.faker_zh.ipv4() def mac_address(self) -> str: """生成MAC地址""" return self.faker_zh.mac_address() def url(self) -> str: """生成URL""" return self.faker_zh.url() def uri_path(self) -> str: """生成URI路径""" return self.faker_zh.uri_path() def user_agent(self) -> str: """生成User-Agent""" return self.faker_zh.user_agent() def hex_color(self) -> str: """生成十六进制颜色""" return self.faker_zh.hex_color() def rgb_color(self) -> Tuple[int, int, int]: """生成RGB颜色""" return self.faker_zh.rgb_color() class EnglishFaker: """英文测试数据生成器""" def __init__(self): self.faker = Faker("en_US") def name(self) -> str: """生成英文姓名""" return self.faker.name() def first_name(self) -> str: """生成英文名字""" return self.faker.first_name() def last_name(self) -> str: """生成英文姓氏""" return self.faker.last_name() def email(self, domain: Optional[str] = None) -> str: """生成邮箱""" if domain: return self.faker.email(domain=domain) return self.faker.email() def phone_number(self) -> str: """生成美国电话号码""" return self.faker.phone_number() def company(self) -> str: """生成公司名称""" return self.faker.company() def address(self) -> str: """生成地址""" return self.faker.address().replace("\n", ", ") def city(self) -> str: """生成城市名""" return self.faker.city() def state(self) -> str: """生成州/省名""" return self.faker.state() def country(self) -> str: """生成国家名""" return self.faker.country() def zip_code(self) -> str: """生成邮编""" return self.faker.zipcode() def username(self) -> str: """生成用户名""" return self.faker.user_name() def password(self, length: int = 12) -> str: """生成密码""" chars = string.ascii_letters + string.digits + "!@#$%^&*" return "".join(random.choices(chars, k=length)) def text(self, max_chars: int = 200) -> str: """生成随机英文文本""" return self.faker.text(max_nb_chars=max_chars) def sentence(self, nb_words: int = 10) -> str: """生成随机句子""" return self.faker.sentence(nb_words=nb_words) def paragraph(self, nb_sentences: int = 3) -> str: """生成段落""" return self.faker.paragraph(nb_sentences=nb_sentences) def date_of_birth(self, start_year: int = 1960, end_year: int = 2000) -> str: """生成出生日期""" return self.faker.date_of_birth( minimum_age=end_year - datetime.now().year, maximum_age=start_year - datetime.now().year ).strftime("%Y-%m-%d") def date_between(self, start_date: str, end_date: str) -> str: """生成日期范围""" start = datetime.strptime(start_date, "%Y-%m-%d") end = datetime.strptime(end_date, "%Y-%m-%d") return self.faker.date_between(start, end).strftime("%Y-%m-%d") class TestDataGenerator: """测试数据生成器主类""" def __init__(self): self.settings = get_settings() self.zh_faker = ChineseFaker() self.en_faker = EnglishFaker() def generate_contact_form_data( self, use_valid: bool = True, lang: str = "zh" ) -> Dict[str, str]: """生成联系表单数据""" if use_valid: if lang == "zh": return { "name": self.zh_faker.name(), "phone": self.zh_faker.phone_number(), "email": self.zh_faker.email(domain="example.com"), "subject": self.zh_faker.sentence(nb_words=8), "message": self.zh_faker.text(max_chars=300) } else: return { "name": self.en_faker.name(), "phone": self.en_faker.phone_number(), "email": self.en_faker.email(domain="example.com"), "subject": self.en_faker.sentence(nb_words=8), "message": self.en_faker.paragraph(nb_sentences=3) } else: return self.settings.test_form_data.get("invalid", { "email": "invalid-email", "phone": "123" }) def generate_user_profile(self, lang: str = "zh") -> Dict[str, Any]: """生成用户资料数据""" if lang == "zh": return { "name": self.zh_faker.name(), "email": self.zh_faker.email(domain="example.com"), "phone": self.zh_faker.phone_number(), "address": self.zh_faker.address(), "job_title": self.zh_faker.job_title(), "company": self.zh_faker.company_name(), "date_of_birth": self.zh_faker.date_of_birth() } else: return { "name": self.en_faker.name(), "email": self.en_faker.email(domain="example.com"), "phone": self.en_faker.phone_number(), "address": self.en_faker.address(), "job_title": random.choice([ "Software Engineer", "Product Manager", "Designer", "Marketing Manager", "Sales Representative", "Data Analyst" ]), "company": self.en_faker.company(), "date_of_birth": self.en_faker.date_of_birth() } def generate_search_query(self) -> str: """生成搜索查询""" topics = [ "软件开发", "云计算", "人工智能", "数据分析", "数字化转型", "企业服务", "智能制造", "物联网" ] return random.choice(topics) def generate_news_article(self) -> Dict[str, Any]: """生成新闻文章数据""" return { "title": self.zh_faker.sentence(nb_words=12), "summary": self.zh_faker.text(max_chars=200), "content": self.zh_faker.text(max_chars=1000), "author": self.zh_faker.name(), "publish_date": datetime.now().strftime("%Y-%m-%d"), "category": random.choice(["公司新闻", "行业动态", "产品发布", "技术文章"]) } def generate_product_data(self) -> Dict[str, Any]: """生成产品数据""" products = [ {"name": "睿新ERP管理系统", "category": "企业软件"}, {"name": "睿新客户关系管理系统", "category": "企业软件"}, {"name": "睿新协同办公平台", "category": "企业软件"}, {"name": "睿新商业智能平台", "category": "数据产品"}, {"name": "睿新物联网平台", "category": "物联网"}, {"name": "睿新AI智能应用套件", "category": "人工智能"} ] product = random.choice(products) return { "name": product["name"], "category": product["category"], "description": self.zh_faker.text(max_chars=300), "features": random.sample([ "高性能", "高可用", "易扩展", "安全可靠", "智能化", "云原生", "移动优先", "低代码" ], k=4), "price": round(random.uniform(1000, 100000), 2) } def generate_company_info(self) -> Dict[str, str]: """生成公司信息""" return { "name": self.zh_faker.company_name(), "short_name": "".join(self.zh_faker.company_name()[:4]), "slogan": self.zh_faker.sentence(nb_words=6), "description": self.zh_faker.text(max_chars=200), "address": self.zh_faker.address(), "phone": self.zh_faker.phone_number(), "email": self.zh_faker.email(domain="example.com"), "website": self.zh_faker.url() } def generate_dates(self, count: int = 10) -> List[str]: """生成日期列表""" dates = [] base_date = datetime.now() for i in range(count): date = base_date - timedelta(days=random.randint(0, 365)) dates.append(date.strftime("%Y-%m-%d")) return dates def generate_unique_id(self) -> str: """生成唯一ID""" return str(uuid.uuid4()) def generate_order_number(self) -> str: """生成订单号""" prefix = "ORD" timestamp = datetime.now().strftime("%Y%m%d%H%M%S") random_suffix = "".join(random.choices(string.ascii_uppercase + string.digits, k=6)) return f"{prefix}{timestamp}{random_suffix}" def generate_numeric_range( self, min_val: int = 1, max_val: int = 100, decimals: int = 0 ) -> Union[int, float]: """生成数值范围""" value = random.uniform(min_val, max_val) return round(value, decimals) if decimals else int(value) def generate_boolean(self) -> bool: """生成布尔值""" return random.choice([True, False]) def generate_choice(self, options: List[Any]) -> Any: """从列表中随机选择一个""" return random.choice(options) def generate_color(self, format: str = "hex") -> Union[str, Tuple[int, int, int]]: """生成颜色值""" if format == "hex": return self.zh_faker.hex_color() elif format == "rgb": return self.zh_faker.rgb_color() return self.zh_faker.hex_color() # 全局测试数据生成器实例 test_data_generator = TestDataGenerator() def get_test_data_generator() -> TestDataGenerator: """获取测试数据生成器""" return test_data_generator