260 行
9.6 KiB
Python
260 行
9.6 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
站点配图与视觉丰富度自动化测试 (TDD)
|
||
验证:
|
||
1. 所有核心配图资产物理存在、非空且格式正确
|
||
2. PC 首页与移动端首页正确展示服务、产品、案例等丰富配图
|
||
3. 独立服务页、产品页、案例页包含深度高保真系统与业务界面配图
|
||
4. 关于我们页面包含专家团队专业徽标与资质认证图
|
||
5. CSS 针对配图有严格的响应式(max-width: 100%、圆角、细线边框、悬停微光)控制
|
||
6. 无破损路径或 404 资源引用
|
||
"""
|
||
|
||
import os
|
||
import unittest
|
||
|
||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
|
||
|
||
class SiteImagesTest(unittest.TestCase):
|
||
def setUp(self):
|
||
self.img_dir = os.path.join(
|
||
BASE_DIR, "public", "assets", "addons", "official", "images", "showcases"
|
||
)
|
||
self.pc_home_path = os.path.join(
|
||
BASE_DIR, "addons", "official", "view", "web", "official_home", "index.html"
|
||
)
|
||
self.mobile_home_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_home",
|
||
"index_e.html",
|
||
)
|
||
self.service_page_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_product",
|
||
"service_page.html",
|
||
)
|
||
self.product_page_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_product",
|
||
"product_page.html",
|
||
)
|
||
self.case_page_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_case_show",
|
||
"list.html",
|
||
)
|
||
self.case_mobile_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_case_show",
|
||
"list_e.html",
|
||
)
|
||
self.about_page_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_home",
|
||
"single.html",
|
||
)
|
||
self.about_mobile_path = os.path.join(
|
||
BASE_DIR,
|
||
"addons",
|
||
"official",
|
||
"view",
|
||
"web",
|
||
"official_home",
|
||
"single_e.html",
|
||
)
|
||
self.css_path = os.path.join(
|
||
BASE_DIR, "public", "assets", "addons", "official", "css", "modern_nhc.css"
|
||
)
|
||
|
||
def test_01_image_assets_exist_and_non_empty(self):
|
||
"""核心配图资源必须物理存在且内容非空"""
|
||
required_images = [
|
||
# 服务类配图
|
||
"service_middle.svg",
|
||
"service_app.svg",
|
||
"service_agent.svg",
|
||
# 产品类配图
|
||
"product_mall.svg",
|
||
"product_pos.svg",
|
||
"product_erp.svg",
|
||
"product_saas.svg",
|
||
# 案例类配图
|
||
"case_distrib.svg",
|
||
"case_catering.svg",
|
||
"case_gov_agent.svg",
|
||
"case_manufacture.svg",
|
||
# 专家与资质徽标
|
||
"team_architect.svg",
|
||
"team_fullstack.svg",
|
||
"team_ai.svg",
|
||
"team_security.svg",
|
||
"cert_hi_tech.svg",
|
||
"cert_iso9001.svg",
|
||
]
|
||
self.assertTrue(
|
||
os.path.isdir(self.img_dir), f"图片目录 {self.img_dir} 必须存在"
|
||
)
|
||
for img_name in required_images:
|
||
img_path = os.path.join(self.img_dir, img_name)
|
||
self.assertTrue(
|
||
os.path.isfile(img_path),
|
||
f"图片文件 {img_name} 必须存在于 showcases 目录下",
|
||
)
|
||
size = os.path.getsize(img_path)
|
||
self.assertGreater(size, 100, f"图片文件 {img_name} 大小不能过小")
|
||
|
||
def test_02_pc_and_mobile_homepage_service_images(self):
|
||
"""首页服务入口必须包含三个一致的服务视觉卡片"""
|
||
with open(self.pc_home_path, encoding="utf-8") as f:
|
||
pc_content = f.read()
|
||
with open(self.mobile_home_path, encoding="utf-8") as f:
|
||
mobile_content = f.read()
|
||
|
||
for content, page_name in [
|
||
(pc_content, "PC 首页"),
|
||
(mobile_content, "移动端首页"),
|
||
]:
|
||
self.assertEqual(
|
||
content.count("hn-service-top"),
|
||
3,
|
||
f"{page_name} 应包含三个服务视觉卡片",
|
||
)
|
||
for service_name in ["软件开发", "APP与小程序定制", "智能体开发"]:
|
||
self.assertIn(
|
||
service_name, content, f"{page_name} 应包含服务入口:{service_name}"
|
||
)
|
||
|
||
def test_03_pc_and_mobile_homepage_product_images(self):
|
||
"""首页产品区必须包含经营工作台示意与四类产品入口"""
|
||
with open(self.pc_home_path, encoding="utf-8") as f:
|
||
pc_content = f.read()
|
||
with open(self.mobile_home_path, encoding="utf-8") as f:
|
||
mobile_content = f.read()
|
||
|
||
for content, page_name in [
|
||
(pc_content, "PC 首页"),
|
||
(mobile_content, "移动端首页"),
|
||
]:
|
||
self.assertIn(
|
||
"hn-app-window", content, f"{page_name} 应包含经营工作台界面示意"
|
||
)
|
||
self.assertIn("hn-chart", content, f"{page_name} 应包含经营趋势示意")
|
||
for product_name in ["商城", "收银", "进销存", "SaaS版本"]:
|
||
self.assertIn(
|
||
product_name, content, f"{page_name} 应包含产品入口:{product_name}"
|
||
)
|
||
|
||
def test_04_cases_pages_have_preview_images(self):
|
||
"""标杆案例卡片必须配有真实的业务系统视窗图"""
|
||
with open(self.case_page_path, encoding="utf-8") as f:
|
||
case_pc = f.read()
|
||
with open(self.case_mobile_path, encoding="utf-8") as f:
|
||
case_mobile = f.read()
|
||
|
||
for content, page_name in [
|
||
(case_pc, "PC 案例独立页"),
|
||
(case_mobile, "移动端案例独立页"),
|
||
]:
|
||
self.assertIn(
|
||
"case_distrib.svg", content, f"{page_name} 应包含分销订货中台界面图"
|
||
)
|
||
self.assertIn(
|
||
"case_catering.svg", content, f"{page_name} 应包含连锁餐饮收银界面图"
|
||
)
|
||
self.assertIn(
|
||
"case_gov_agent.svg", content, f"{page_name} 应包含政务智能体界面图"
|
||
)
|
||
self.assertIn(
|
||
"case_manufacture.svg",
|
||
content,
|
||
f"{page_name} 应包含工业制造进销存界面图",
|
||
)
|
||
|
||
def test_05_service_and_product_pages_have_showcases(self):
|
||
"""独立服务页与产品页必须嵌入高质量系统拓扑与界面大图"""
|
||
with open(self.service_page_path, encoding="utf-8") as f:
|
||
service_content = f.read()
|
||
with open(self.product_page_path, encoding="utf-8") as f:
|
||
product_content = f.read()
|
||
|
||
self.assertIn("service_middle.svg", service_content)
|
||
self.assertIn("service_app.svg", service_content)
|
||
self.assertIn("service_agent.svg", service_content)
|
||
|
||
self.assertIn("product_mall.svg", product_content)
|
||
self.assertIn("product_pos.svg", product_content)
|
||
self.assertIn("product_erp.svg", product_content)
|
||
self.assertIn("product_saas.svg", product_content)
|
||
|
||
def test_06_about_pages_have_abstract_brand_images(self):
|
||
"""关于我们使用已标注的品牌抽象配图,保留格式回退。"""
|
||
with open(self.about_page_path, encoding="utf-8") as f:
|
||
about_pc = f.read()
|
||
with open(self.about_mobile_path, encoding="utf-8") as f:
|
||
about_mobile = f.read()
|
||
|
||
for content, page_name in [
|
||
(about_pc, "PC 关于我们页"),
|
||
(about_mobile, "移动端关于我们页"),
|
||
]:
|
||
for name in ("landscape", "collaboration"):
|
||
for extension in ("webp", "jpg"):
|
||
relative_path = f"images/about/{name}.{extension}"
|
||
self.assertIn(
|
||
relative_path, content, f"{page_name} 应包含抽象配图及格式回退"
|
||
)
|
||
self.assertTrue(
|
||
os.path.isfile(
|
||
os.path.join(
|
||
BASE_DIR,
|
||
"public",
|
||
"assets",
|
||
"addons",
|
||
"official",
|
||
relative_path,
|
||
)
|
||
)
|
||
)
|
||
self.assertIn("抽象建筑示意", content)
|
||
self.assertNotIn("cert_hi_tech.svg", content)
|
||
self.assertNotIn("cert_iso9001.svg", content)
|
||
|
||
def test_07_responsive_image_styles_in_css(self):
|
||
"""CSS 必须具备严谨的配图自适应与质感样式定义"""
|
||
with open(self.css_path, encoding="utf-8") as f:
|
||
css = f.read()
|
||
|
||
self.assertIn(".nhc-card-thumb", css, "CSS 应定义 .nhc-card-thumb 图片容器类")
|
||
self.assertIn("object-fit", css, "CSS 应规范图片的适应展示模式")
|
||
self.assertIn(".nhc-case-img-wrap", css, "CSS 应定义案例图视窗包装器")
|
||
self.assertIn(".nhc-service-media-box", css, "CSS 应定义服务媒体容器")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|