"""母题库模块TDD测试 测试策略: - 测试母题模板数据结构 - 测试Prompt渲染逻辑 - 不使用Mock进行业务逻辑测试 """ import pytest from app.services.content.topic_templates import ( TopicTemplate, TOPIC_TEMPLATES, get_topic_template, list_topic_templates, render_topic_prompt, ) # ============================================================================ # 母题模板测试 # ============================================================================ class TestTopicTemplate: """母题模板数据结构测试""" def test_topic_template_attributes(self): """测试母题模板属性""" template = TOPIC_TEMPLATES["product_comparison"] assert template.id == "product_comparison" assert template.name == "产品对比" assert template.icon == "⚖️" assert len(template.prompt_template) > 0 assert len(template.seo_tips) > 0 assert len(template.recommended_platforms) > 0 assert template.word_count_range[0] < template.word_count_range[1] def test_topic_template_required_params(self): """测试母题必填参数""" template = TOPIC_TEMPLATES["product_comparison"] assert "brand_name" in template.required_params assert "competitor_name" in template.required_params assert "comparison_dimensions" in template.required_params assert "keywords" in template.required_params def test_topic_template_optional_params(self): """测试母题可选参数""" template = TOPIC_TEMPLATES["product_comparison"] assert "content_style" in template.optional_params assert "word_count" in template.optional_params class TestAllTopicTemplates: """所有母题模板测试""" def test_all_templates_have_valid_structure(self): """测试所有模板具有有效结构""" for topic_id, template in TOPIC_TEMPLATES.items(): assert template.id == topic_id assert template.name assert template.description assert template.icon assert template.prompt_template assert len(template.seo_tips) > 0 assert len(template.recommended_platforms) > 0 assert template.word_count_range[0] > 0 assert template.word_count_range[1] > template.word_count_range[0] assert len(template.required_params) > 0 def test_all_templates_have_prompt_placeholders(self): """测试所有模板包含Prompt占位符""" for topic_id, template in TOPIC_TEMPLATES.items(): prompt = template.prompt_template for param in template.required_params: assert f"{{{param}}}" in prompt, f"Template {topic_id} missing placeholder {{{param}}}" def test_all_templates_referenced_in_prompt(self): """测试所有参数都在Prompt中使用""" for topic_id, template in TOPIC_TEMPLATES.items(): prompt = template.prompt_template all_params = template.required_params + template.optional_params for param in all_params: if "{" + param + "}" in prompt: # 如果占位符存在,它应该被正确使用 pass # ============================================================================ # 母题模板列表测试 # ============================================================================ class TestTopicTemplateFunctions: """母题模板函数测试""" def test_get_existing_template(self): """测试获取已存在的模板""" template = get_topic_template("product_comparison") assert template is not None assert template.id == "product_comparison" def test_get_nonexistent_template(self): """测试获取不存在的模板""" template = get_topic_template("nonexistent") assert template is None def test_list_topic_templates(self): """测试列出所有模板""" templates = list_topic_templates() assert len(templates) == 8 assert all(isinstance(t, TopicTemplate) for t in templates) def test_list_templates_contains_all_ids(self): """测试列出所有模板ID""" templates = list_topic_templates() template_ids = [t.id for t in templates] for topic_id in TOPIC_TEMPLATES.keys(): assert topic_id in template_ids # ============================================================================ # Prompt渲染测试 # ============================================================================ class TestRenderTopicPrompt: """Prompt渲染测试""" def test_render_product_comparison_prompt(self): """测试渲染产品对比Prompt""" params = { "brand_name": "华为", "competitor_name": "小米", "comparison_dimensions": "性能、价格、外观", "keywords": "手机,5G,性价比", "content_style": "专业", "word_count": 2000, } prompt = render_topic_prompt("product_comparison", params) assert "华为" in prompt assert "小米" in prompt assert "性能、价格、外观" in prompt assert "手机,5G,性价比" in prompt assert "2000" in prompt def test_render_how_to_guide_prompt(self): """测试渲染使用指南Prompt""" params = { "product_name": "iPhone 15", "core_features": "拍照、续航、系统", "target_audience": "普通用户", "keywords": "iPhone,苹果,手机", } prompt = render_topic_prompt("how_to_guide", params) assert "iPhone 15" in prompt assert "拍照、续航、系统" in prompt def test_render_industry_trends_prompt(self): """测试渲染行业趋势Prompt""" params = { "industry_name": "新能源汽车", "brand_perspective": "技术创新", "analysis_dimensions": "技术、市场、政策", "keywords": "电动车,电池,自动驾驶", } prompt = render_topic_prompt("industry_trends", params) assert "新能源汽车" in prompt assert "技术创新" in prompt def test_render_with_default_params(self): """测试使用默认参数渲染""" params = { "brand_name": "测试品牌", "competitor_name": "竞品", "comparison_dimensions": "功能", "keywords": "关键词", } prompt = render_topic_prompt("product_comparison", params) # content_style和word_count应有默认值 assert "content_style" not in params or "专业" in prompt or "专业" in params.get("content_style", "") def test_render_nonexistent_template_raises_error(self): """测试渲染不存在的模板抛出错误""" with pytest.raises(ValueError, match="Unknown topic"): render_topic_prompt("nonexistent_topic", {}) # ============================================================================ # 各母题模板内容测试 # ============================================================================ class TestProductComparison: """产品对比母题测试""" def test_template_has_comparison_structure(self): """测试模板包含对比结构""" template = TOPIC_TEMPLATES["product_comparison"] prompt = template.prompt_template # 验证包含对比维度 assert "对比" in prompt # 验证包含SEO提示 assert any("对比" in tip for tip in template.seo_tips) class TestHowToGuide: """使用指南母题测试""" def test_template_has_step_structure(self): """测试模板包含步骤结构""" template = TOPIC_TEMPLATES["how_to_guide"] prompt = template.prompt_template # 验证包含步骤相关关键词 assert "步骤" in prompt or "教程" in prompt or "使用" in prompt class TestIndustryTrends: """行业趋势母题测试""" def test_template_has_trend_analysis(self): """测试模板包含趋势分析""" template = TOPIC_TEMPLATES["industry_trends"] prompt = template.prompt_template # 验证包含趋势相关关键词 assert "趋势" in prompt or "分析" in prompt or "预测" in prompt class TestExpertOpinion: """专家观点母题测试""" def test_template_has_expert_identity(self): """测试模板包含专家身份""" template = TOPIC_TEMPLATES["expert_opinion"] assert "expert_identity" in template.required_params assert "core_opinion" in template.required_params class TestCaseStudy: """案例研究母题测试""" def test_template_has_case_structure(self): """测试模板包含案例结构""" template = TOPIC_TEMPLATES["case_study"] prompt = template.prompt_template assert "case_name" in template.required_params assert "company_background" in template.required_params class TestDataReport: """数据报告母题测试""" def test_template_has_data_structure(self): """测试模板包含数据报告结构""" template = TOPIC_TEMPLATES["data_report"] assert "report_topic" in template.required_params assert "data_scope" in template.required_params assert "core_findings" in template.required_params # 数据报告字数范围应较大 assert template.word_count_range[0] >= 2000 class TestFAQ: """问题解答母题测试""" def test_template_has_faq_structure(self): """测试模板包含FAQ结构""" template = TOPIC_TEMPLATES["faq"] prompt = template.prompt_template assert "questions" in template.required_params # FAQ字数范围应较小 assert template.word_count_range[1] <= 2500 class TestReview: """评测报告母题测试""" def test_template_has_review_structure(self): """测试模板包含评测结构""" template = TOPIC_TEMPLATES["review"] prompt = template.prompt_template assert "product_name" in template.required_params assert "review_dimensions" in template.required_params # 评测应包含优缺点 assert "优" in prompt or "缺" in prompt or "评测" in prompt # ============================================================================ # SEO提示测试 # ============================================================================ class TestSEOTips: """SEO提示测试""" def test_all_templates_have_seo_tips(self): """测试所有模板都有SEO提示""" for topic_id, template in TOPIC_TEMPLATES.items(): assert len(template.seo_tips) > 0, f"Template {topic_id} missing SEO tips" def test_seo_tips_are_descriptive(self): """测试SEO提示具有描述性""" for topic_id, template in TOPIC_TEMPLATES.items(): for tip in template.seo_tips: assert len(tip) > 5, f"Template {topic_id} has too short SEO tip" # ============================================================================ # 推荐平台测试 # ============================================================================ class TestRecommendedPlatforms: """推荐平台测试""" def test_all_templates_have_recommended_platforms(self): """测试所有模板都有推荐平台""" for topic_id, template in TOPIC_TEMPLATES.items(): assert len(template.recommended_platforms) > 0, f"Template {topic_id} missing platforms" def test_platforms_are_valid(self): """测试平台名称有效""" common_platforms = {"知乎", "百家号", "公众号", "小红书", "简书", "微博"} for topic_id, template in TOPIC_TEMPLATES.items(): for platform in template.recommended_platforms: # 平台应该在常见平台列表中或是有效的 assert platform, f"Template {topic_id} has empty platform name"