#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 现代中式科技高级抽象配图自动化测试 (TDD - Test-Driven Development) 测试验证重点: 1. 纯粹高级抽象设计:杜绝伪造的假界面截图,杜绝纯文字介绍类图片,必须为严谨抽象的工程美学图形。 2. 艺术质感与层次:具备空间结构(渐变、阴影、微透视、细线窗棂纹理等),杜绝单薄空洞的简陋圆圈。 3. 现代中式浅色规范:背景为 #FFFFFF / #F8FAFC / #EFF6FF 浅色基调,主色 #2563EB 科技蓝,辅以 #06B6D4 青、#7C3AED 紫,克制朱砂印章。 4. 全站展示图集与技术文章封面完整性与 SVG 语法闭合。 5. 首页模板技术文章包含抽象封面的优雅 Fallback 机制。 """ import os import re import unittest BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) class AdvancedAbstractVisualsTest(unittest.TestCase): def setUp(self): self.showcases_dir = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'images', 'showcases') self.articles_dir = os.path.join(BASE_DIR, 'public', 'assets', 'addons', 'official', 'images', 'articles') self.home_tpl_path = os.path.join(BASE_DIR, 'addons', 'official', 'view', 'web', 'official_home', 'index.html') # 4大产品抽象图 self.product_files = [ 'product_mall.svg', 'product_pos.svg', 'product_erp.svg', 'product_saas.svg' ] # 4大标杆案例抽象图 self.case_files = [ 'case_distrib.svg', 'case_catering.svg', 'case_manufacture.svg', 'case_gov_agent.svg' ] # 3大核心服务抽象图 self.service_files = [ 'service_middle.svg', 'service_app.svg', 'service_agent.svg' ] # 4篇核心技术文章抽象封面 self.article_files = [ 'article_microservice.svg', 'article_tdd_standards.svg', 'article_cross_app.svg', 'article_security_whitepaper.svg' ] def test_01_all_files_exist_and_valid_svg(self): """所有抽象视觉文件必须完整存在且具备合法的 SVG 闭合标签与 viewBox""" all_files = self.product_files + self.case_files + self.service_files for fname in all_files: fpath = os.path.join(self.showcases_dir, fname) self.assertTrue(os.path.isfile(fpath), f"抽象视觉图必须存在: {fname}") with open(fpath, 'r', encoding='utf-8') as f: content = f.read().strip() self.assertTrue(content.startswith(''), f"{fname} 必须以 闭合") self.assertIn('viewBox', content, f"{fname} 必须指定 viewBox 属性") def test_02_abstract_visual_richness_and_depth(self): """抽象图必须具有空间深度与现代科技美感,不应是单薄粗糙的几个圆圈""" all_files = self.product_files + self.case_files + self.service_files for fname in all_files: fpath = os.path.join(self.showcases_dir, fname) with open(fpath, 'r', encoding='utf-8') as f: content = f.read() # 必须具有渐变或滤镜定义以实现高质感光影与空间层次 has_depth = ('linearGradient' in content or 'radialGradient' in content) and \ ('feDropShadow' in content or 'feGaussianBlur' in content or 'filter' in content) self.assertTrue(has_depth, f"{fname} 必须具备光影渐变或阴影滤镜,体现空间深度与高级感") # 必须具有现代中式窗棂细线背景图案 self.assertIn('lattice', content, f"{fname} 必须融入现代中式窗棂几何微网格底纹") # 代码大小合理(高质量矢量图通常在 3KB ~ 15KB,兼顾精细度与加载性能) size_kb = len(content) / 1024 self.assertTrue(2.0 <= size_kb <= 25.0, f"{fname} 大小需适中 ({size_kb:.2f}KB),兼顾丰富度与性能") def test_03_color_and_seal_constraints(self): """抽象图形必须遵循配色规范(科技蓝主色,浅色底,克制印章)""" all_files = self.product_files + self.case_files + self.service_files text_regex = re.compile(r']*>(.*?)', re.DOTALL | re.IGNORECASE) for fname in all_files: fpath = os.path.join(self.showcases_dir, fname) with open(fpath, 'r', encoding='utf-8') as f: content = f.read() # 主色必须包含品牌科技蓝 #2563EB / #1D4ED8 self.assertTrue( '#2563EB' in content or '#1D4ED8' in content, f"{fname} 必须包含科技蓝规范主色" ) # 浅色底基 self.assertTrue( '#FFFFFF' in content or '#F8FAFC' in content or '#EFF6FF' in content, f"{fname} 必须使用浅色专业风底基" ) # 文字数量约束:≤ 1 个字符(仅允许一个单字印章或完全无字纯抽象图形) matches = text_regex.findall(content) clean_texts = [re.sub(r'<[^>]+>', '', m).strip() for m in matches if m.strip()] self.assertLessEqual(len(clean_texts), 1, f"{fname} 文字不可超过1个字符(杜绝伪造假界面,保持纯粹抽象): {clean_texts}") def test_04_articles_abstract_covers_exist(self): """核心技术文章必须具备专属抽象科技线稿封面""" self.assertTrue(os.path.isdir(self.articles_dir), "articles 目录必须存在") for fname in self.article_files: fpath = os.path.join(self.articles_dir, fname) self.assertTrue(os.path.isfile(fpath), f"文章封面抽象图必须存在: {fname}") with open(fpath, 'r', encoding='utf-8') as f: content = f.read().strip() self.assertTrue(content.startswith(''), f"{fname} 必须为合法的 SVG") def test_05_home_template_has_intelligent_article_fallback(self): """首页模板在文章图片为空时,必须使用对应的高级抽象技术封面 fallback,消除纯灰空白占位""" self.assertTrue(os.path.isfile(self.home_tpl_path), "首页模板文件必须存在") with open(self.home_tpl_path, 'r', encoding='utf-8') as f: content = f.read() # 检查是否包含 fallback 到 articles 目录下的 SVG 封面 self.assertIn('assets/addons/official/images/articles/', content, "首页模板必须包含针对技术文章抽象封面的智能备用逻辑") self.assertNotIn('纳海川技术洞察', content, "首页模板不应直接显示带有灰色背景的纯文字方块,应替换为优雅抽象封面") if __name__ == '__main__': unittest.main()