文件
nahaichuan/tests/test_advanced_abstract_visuals.py

136 行
6.9 KiB
Python

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

#!/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('<svg'), f"{fname} 必须为合法的 <svg 起始")
self.assertTrue(content.endswith('</svg>'), f"{fname} 必须以 </svg> 闭合")
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'<text[^>]*>(.*?)</text>', 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('<svg') and content.endswith('</svg>'), 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('纳海川技术洞察</div>', content, "首页模板不应直接显示带有灰色背景的纯文字方块,应替换为优雅抽象封面")
if __name__ == '__main__':
unittest.main()