353 lines
12 KiB
Python
353 lines
12 KiB
Python
"""母题库模块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"
|