feat: 建立完整的测试数据管理体系
- 创建测试数据文件test-data.ts,包含所有测试场景数据 - 增强TestDataGenerator,添加边界、安全、性能等测试数据生成方法 - 支持XSS、SQL注入、路径遍历等安全测试 - 支持WCAG可访问性测试数据 - 支持Core Web Vitals性能测试数据 - 支持响应式断点测试数据
This commit is contained in:
@@ -251,4 +251,210 @@ export class TestDataGenerator {
|
||||
## Message
|
||||
${this.generateMessage()}`;
|
||||
}
|
||||
|
||||
static generateBoundaryTestData(): {
|
||||
name: { minLength: string; maxLength: string; empty: string; whitespace: string };
|
||||
phone: { minLength: string; maxLength: string; validFormat: string };
|
||||
email: { minLength: string; maxLength: string };
|
||||
} {
|
||||
return {
|
||||
name: {
|
||||
minLength: '张',
|
||||
maxLength: '张三李四王五赵六钱七孙八周九吴十',
|
||||
empty: '',
|
||||
whitespace: ' ',
|
||||
},
|
||||
phone: {
|
||||
minLength: '1380013800',
|
||||
maxLength: '138001380001',
|
||||
validFormat: '13800138000',
|
||||
},
|
||||
email: {
|
||||
minLength: 'a@b.c',
|
||||
maxLength: `${'a'.repeat(64)}@${'b'.repeat(63)}.com`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static generateSecurityTestData(): {
|
||||
xssPayloads: string[];
|
||||
sqlInjectionPayloads: string[];
|
||||
pathTraversalPayloads: string[];
|
||||
} {
|
||||
return {
|
||||
xssPayloads: [
|
||||
'<script>alert("XSS")</script>',
|
||||
'<img src=x onerror=alert("XSS")>',
|
||||
'<svg onload=alert("XSS")>',
|
||||
'javascript:alert("XSS")',
|
||||
'<body onload=alert("XSS")>',
|
||||
],
|
||||
sqlInjectionPayloads: [
|
||||
"'; DROP TABLE users; --",
|
||||
"' OR '1'='1",
|
||||
"' UNION SELECT * FROM users --",
|
||||
"1; INSERT INTO users VALUES ('hacker')",
|
||||
],
|
||||
pathTraversalPayloads: [
|
||||
'../../../etc/passwd',
|
||||
'..\\..\\..\\windows\\system32\\config\\sam',
|
||||
'....//....//....//etc/passwd',
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
static generateAccessibilityTestData(): {
|
||||
colorContrastRatios: { normalText: number; largeText: number; uiComponents: number };
|
||||
touchTargetSize: number;
|
||||
focusIndicatorVisible: boolean;
|
||||
keyboardNavigationRequired: boolean;
|
||||
} {
|
||||
return {
|
||||
colorContrastRatios: {
|
||||
normalText: 4.5,
|
||||
largeText: 3.0,
|
||||
uiComponents: 3.0,
|
||||
},
|
||||
touchTargetSize: 44,
|
||||
focusIndicatorVisible: true,
|
||||
keyboardNavigationRequired: true,
|
||||
};
|
||||
}
|
||||
|
||||
static generatePerformanceTestData(): {
|
||||
thresholds: {
|
||||
loadTime: number;
|
||||
firstContentfulPaint: number;
|
||||
largestContentfulPaint: number;
|
||||
timeToInteractive: number;
|
||||
cumulativeLayoutShift: number;
|
||||
firstInputDelay: number;
|
||||
};
|
||||
budgets: {
|
||||
totalPageSize: number;
|
||||
imageSize: number;
|
||||
scriptSize: number;
|
||||
stylesheetSize: number;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
thresholds: {
|
||||
loadTime: 5000,
|
||||
firstContentfulPaint: 1800,
|
||||
largestContentfulPaint: 2500,
|
||||
timeToInteractive: 3800,
|
||||
cumulativeLayoutShift: 0.1,
|
||||
firstInputDelay: 100,
|
||||
},
|
||||
budgets: {
|
||||
totalPageSize: 1600000,
|
||||
imageSize: 500000,
|
||||
scriptSize: 300000,
|
||||
stylesheetSize: 100000,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static generateResponsiveTestData(): Array<{
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
}> {
|
||||
return [
|
||||
{ name: 'mobile-small', width: 320, height: 568 },
|
||||
{ name: 'mobile-medium', width: 375, height: 667 },
|
||||
{ name: 'mobile-large', width: 414, height: 896 },
|
||||
{ name: 'tablet-small', width: 768, height: 1024 },
|
||||
{ name: 'tablet-large', width: 1024, height: 768 },
|
||||
{ name: 'desktop-small', width: 1280, height: 720 },
|
||||
{ name: 'desktop-medium', width: 1366, height: 768 },
|
||||
{ name: 'desktop-large', width: 1920, height: 1080 },
|
||||
];
|
||||
}
|
||||
|
||||
static generateNavigationTestData(): Array<{
|
||||
label: string;
|
||||
href: string;
|
||||
expectedUrl: string;
|
||||
}> {
|
||||
return [
|
||||
{ label: '首页', href: '#home', expectedUrl: '/' },
|
||||
{ label: '关于我们', href: '#about', expectedUrl: '/' },
|
||||
{ label: '服务', href: '#services', expectedUrl: '/' },
|
||||
{ label: '产品', href: '#products', expectedUrl: '/' },
|
||||
{ label: '案例', href: '#cases', expectedUrl: '/' },
|
||||
{ label: '新闻', href: '#news', expectedUrl: '/' },
|
||||
{ label: '联系我们', href: '#contact', expectedUrl: '/' },
|
||||
];
|
||||
}
|
||||
|
||||
static generateCompanyInfoTestData(): {
|
||||
name: string;
|
||||
address: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
workHours: Array<{ day: string; hours: string }>;
|
||||
} {
|
||||
return {
|
||||
name: '四川睿新致远科技有限公司',
|
||||
address: '四川省成都市高新区天府大道中段1268号天府软件园E区1栋',
|
||||
phone: '028-88888888',
|
||||
email: 'contact@ruixin.com',
|
||||
workHours: [
|
||||
{ day: '周一至周五', hours: '9:00 - 18:00' },
|
||||
{ day: '周六', hours: '9:00 - 12:00' },
|
||||
{ day: '周日', hours: '休息' },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
static generateErrorTestData(): {
|
||||
requiredField: string;
|
||||
invalidEmail: string;
|
||||
invalidPhone: string;
|
||||
messageTooShort: string;
|
||||
messageTooLong: string;
|
||||
submissionFailed: string;
|
||||
} {
|
||||
return {
|
||||
requiredField: '此字段为必填项',
|
||||
invalidEmail: '请输入有效的邮箱地址',
|
||||
invalidPhone: '请输入有效的手机号码',
|
||||
messageTooShort: '消息内容至少需要10个字符',
|
||||
messageTooLong: '消息内容不能超过1000个字符',
|
||||
submissionFailed: '提交失败,请稍后重试',
|
||||
};
|
||||
}
|
||||
|
||||
static generateSuccessTestData(): {
|
||||
formSubmitted: string;
|
||||
thankYou: string;
|
||||
} {
|
||||
return {
|
||||
formSubmitted: '消息已发送',
|
||||
thankYou: '感谢您的留言,我们会尽快与您联系',
|
||||
};
|
||||
}
|
||||
|
||||
static generateRandomEmail(): string {
|
||||
const domains = ['gmail.com', 'outlook.com', 'yahoo.com', 'qq.com', '163.com'];
|
||||
const username = this.generateAlphanumeric(8);
|
||||
const domain = domains[Math.floor(Math.random() * domains.length)]!;
|
||||
return `${username}@${domain}`;
|
||||
}
|
||||
|
||||
static generateRandomChineseName(): string {
|
||||
const surnames = ['张', '李', '王', '刘', '陈', '杨', '赵', '黄', '周', '吴'];
|
||||
const names = ['伟', '芳', '娜', '秀英', '敏', '静', '丽', '强', '磊', '军'];
|
||||
const surname = surnames[Math.floor(Math.random() * surnames.length)]!;
|
||||
const name = names[Math.floor(Math.random() * names.length)]!;
|
||||
return `${surname}${name}`;
|
||||
}
|
||||
|
||||
static generateRandomChinesePhone(): string {
|
||||
const prefixes = ['138', '139', '136', '137', '158', '159', '186', '187', '150', '151'];
|
||||
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]!;
|
||||
const suffix = Math.floor(Math.random() * 90000000 + 10000000);
|
||||
return `${prefix}${suffix}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user