#!/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()