e2ad1331cc
feat(测试): 新增Playwright和Vitest测试配置 feat(测试): 添加测试覆盖率报告生成功能 feat(测试): 实现前后端测试脚本集成 fix(测试): 修复测试密码不匹配问题 fix(测试): 修正URL等待策略 fix(测试): 调整错误消息选择器 refactor(测试): 重构测试目录结构 refactor(测试): 优化测试用例组织方式 docs: 更新测试报告文档 docs: 添加测试覆盖率报告模板 ci: 添加Docker测试环境配置 ci: 实现测试自动化脚本 chore: 更新依赖版本 chore: 添加测试相关配置文件
489 lines
15 KiB
TypeScript
489 lines
15 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { LoginPage } from './pages/LoginPage';
|
|
import { DashboardPage } from './pages/DashboardPage';
|
|
import { UserManagementPage } from './pages/UserManagementPage';
|
|
import { RoleManagementPage } from './pages/RoleManagementPage';
|
|
|
|
test.describe('性能测试基准', () => {
|
|
let loginPage: LoginPage;
|
|
let dashboardPage: DashboardPage;
|
|
let userManagementPage: UserManagementPage;
|
|
let roleManagementPage: RoleManagementPage;
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
loginPage = new LoginPage(page);
|
|
dashboardPage = new DashboardPage(page);
|
|
userManagementPage = new UserManagementPage(page);
|
|
roleManagementPage = new RoleManagementPage(page);
|
|
});
|
|
|
|
test('登录页面加载性能', async ({ page }) => {
|
|
const startTime = Date.now();
|
|
|
|
await loginPage.goto();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`登录页面加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(3000);
|
|
});
|
|
|
|
test('登录操作性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
await loginPage.usernameInput.fill('admin');
|
|
await loginPage.passwordInput.fill('admin123');
|
|
await loginPage.loginButton.click();
|
|
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const endTime = Date.now();
|
|
const loginTime = endTime - startTime;
|
|
|
|
console.log(`登录操作时间: ${loginTime}ms`);
|
|
expect(loginTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('Dashboard页面加载性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const startTime = Date.now();
|
|
|
|
await page.goto('/dashboard');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`Dashboard页面加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('用户管理页面加载性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const startTime = Date.now();
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`用户管理页面加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('角色管理页面加载性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const startTime = Date.now();
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`角色管理页面加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('用户列表加载性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
const table = page.locator('.el-table').first();
|
|
await expect(table).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`用户列表加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(1500);
|
|
});
|
|
|
|
test('角色列表加载性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
const table = page.locator('.el-table').first();
|
|
await expect(table).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`角色列表加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(1500);
|
|
});
|
|
|
|
test('创建用户对话框打开性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
await userManagementPage.clickCreateUser();
|
|
await expect(page.locator('.el-dialog')).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const openTime = endTime - startTime;
|
|
|
|
console.log(`创建用户对话框打开时间: ${openTime}ms`);
|
|
expect(openTime).toBeLessThan(1000);
|
|
});
|
|
|
|
test('创建角色对话框打开性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
await roleManagementPage.clickCreateRole();
|
|
await expect(page.locator('.el-dialog')).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const openTime = endTime - startTime;
|
|
|
|
console.log(`创建角色对话框打开时间: ${openTime}ms`);
|
|
expect(openTime).toBeLessThan(1000);
|
|
});
|
|
|
|
test('用户搜索性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
await userManagementPage.search('admin');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const searchTime = endTime - startTime;
|
|
|
|
console.log(`用户搜索时间: ${searchTime}ms`);
|
|
expect(searchTime).toBeLessThan(1000);
|
|
});
|
|
|
|
test('角色搜索性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const startTime = Date.now();
|
|
|
|
const searchInput = page.locator('input[placeholder*="搜索"]').or(page.locator('.search-input'));
|
|
if (await searchInput.count() > 0) {
|
|
await searchInput.fill('admin');
|
|
await page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
const endTime = Date.now();
|
|
const searchTime = endTime - startTime;
|
|
|
|
console.log(`角色搜索时间: ${searchTime}ms`);
|
|
expect(searchTime).toBeLessThan(1000);
|
|
});
|
|
|
|
test('用户表单提交性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await userManagementPage.clickCreateUser();
|
|
await expect(page.locator('.el-dialog')).toBeVisible();
|
|
|
|
const userData = {
|
|
username: `testuser_${Date.now()}`,
|
|
nickname: '测试用户',
|
|
email: 'test@example.com',
|
|
phone: '13800138000',
|
|
password: 'Test123!@#',
|
|
confirmPassword: 'Test123!@#',
|
|
};
|
|
|
|
await userManagementPage.fillUserForm(userData);
|
|
|
|
const startTime = Date.now();
|
|
|
|
await userManagementPage.submitForm();
|
|
await expect(page.locator('.el-message--success')).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const submitTime = endTime - startTime;
|
|
|
|
console.log(`用户表单提交时间: ${submitTime}ms`);
|
|
expect(submitTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('角色表单提交性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await roleManagementPage.clickCreateRole();
|
|
await expect(page.locator('.el-dialog')).toBeVisible();
|
|
|
|
const roleData = {
|
|
roleName: `测试角色_${Date.now()}`,
|
|
roleKey: `test_role_${Date.now()}`,
|
|
roleSort: '1',
|
|
status: '1',
|
|
remark: '测试角色',
|
|
};
|
|
|
|
await roleManagementPage.fillRoleForm(roleData);
|
|
|
|
const startTime = Date.now();
|
|
|
|
await roleManagementPage.submitForm();
|
|
await expect(page.locator('.el-message--success')).toBeVisible();
|
|
|
|
const endTime = Date.now();
|
|
const submitTime = endTime - startTime;
|
|
|
|
console.log(`角色表单提交时间: ${submitTime}ms`);
|
|
expect(submitTime).toBeLessThan(2000);
|
|
});
|
|
|
|
test('页面切换性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const switchTimes = 5;
|
|
const startTime = Date.now();
|
|
|
|
for (let i = 0; i < switchTimes; i++) {
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await dashboardPage.navigateToRoleManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
}
|
|
|
|
const endTime = Date.now();
|
|
const avgSwitchTime = (endTime - startTime) / switchTimes;
|
|
|
|
console.log(`平均页面切换时间: ${avgSwitchTime}ms`);
|
|
expect(avgSwitchTime).toBeLessThan(1000);
|
|
});
|
|
|
|
test('表格滚动性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const table = page.locator('.el-table').first();
|
|
await expect(table).toBeVisible();
|
|
|
|
const startTime = Date.now();
|
|
|
|
await table.evaluate(el => {
|
|
el.scrollTop = 1000;
|
|
});
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
const endTime = Date.now();
|
|
const scrollTime = endTime - startTime;
|
|
|
|
console.log(`表格滚动时间: ${scrollTime}ms`);
|
|
expect(scrollTime).toBeLessThan(500);
|
|
});
|
|
|
|
test('内存使用性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const metrics = await page.evaluate(() => {
|
|
if (window.performance && (window.performance as any).memory) {
|
|
const perfMemory = (window.performance as any).memory;
|
|
return {
|
|
usedJSHeapSize: perfMemory.usedJSHeapSize,
|
|
totalJSHeapSize: perfMemory.totalJSHeapSize,
|
|
jsHeapSizeLimit: perfMemory.jsHeapSizeLimit,
|
|
};
|
|
}
|
|
return null;
|
|
});
|
|
|
|
if (metrics) {
|
|
console.log('内存使用情况:', metrics);
|
|
|
|
const memoryUsageRatio = metrics.usedJSHeapSize / metrics.jsHeapSizeLimit;
|
|
expect(memoryUsageRatio).toBeLessThan(0.8);
|
|
}
|
|
});
|
|
|
|
test('网络请求性能', async ({ page }) => {
|
|
const apiRequests: { url: string; duration: number }[] = [];
|
|
|
|
page.on('response', async (response) => {
|
|
if (response.url().includes('/api/')) {
|
|
const timing = (response as any).timing();
|
|
const duration = timing.responseEnd - timing.requestStart;
|
|
apiRequests.push({
|
|
url: response.url(),
|
|
duration,
|
|
});
|
|
}
|
|
});
|
|
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
await dashboardPage.navigateToUserManagement();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
if (apiRequests.length > 0) {
|
|
const avgDuration = apiRequests.reduce((sum, req) => sum + req.duration, 0) / apiRequests.length;
|
|
const maxDuration = Math.max(...apiRequests.map(req => req.duration));
|
|
|
|
console.log(`API请求平均时间: ${avgDuration}ms`);
|
|
console.log(`API请求最大时间: ${maxDuration}ms`);
|
|
|
|
expect(avgDuration).toBeLessThan(500);
|
|
expect(maxDuration).toBeLessThan(2000);
|
|
}
|
|
});
|
|
|
|
test('并发操作性能', async ({ page, context }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const startTime = Date.now();
|
|
|
|
const page1 = page;
|
|
const page2 = await context.newPage();
|
|
const page3 = await context.newPage();
|
|
|
|
await Promise.all([
|
|
page1.goto('/users'),
|
|
page2.goto('/roles'),
|
|
page3.goto('/menus'),
|
|
]);
|
|
|
|
await Promise.all([
|
|
page1.waitForLoadState('networkidle'),
|
|
page2.waitForLoadState('networkidle'),
|
|
page3.waitForLoadState('networkidle'),
|
|
]);
|
|
|
|
const endTime = Date.now();
|
|
const concurrentLoadTime = endTime - startTime;
|
|
|
|
console.log(`并发页面加载时间: ${concurrentLoadTime}ms`);
|
|
expect(concurrentLoadTime).toBeLessThan(5000);
|
|
|
|
await page2.close();
|
|
await page3.close();
|
|
});
|
|
|
|
test('长时间运行稳定性', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const startTime = Date.now();
|
|
const duration = 60000; // 1分钟
|
|
|
|
let operationCount = 0;
|
|
const interval = setInterval(async () => {
|
|
await page.goto('/users');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.goto('/roles');
|
|
await page.waitForLoadState('networkidle');
|
|
operationCount++;
|
|
}, 5000);
|
|
|
|
await page.waitForTimeout(duration);
|
|
clearInterval(interval);
|
|
|
|
const endTime = Date.now();
|
|
const actualDuration = endTime - startTime;
|
|
|
|
console.log(`长时间运行操作次数: ${operationCount}`);
|
|
console.log(`长时间运行实际时间: ${actualDuration}ms`);
|
|
|
|
expect(operationCount).toBeGreaterThan(10);
|
|
});
|
|
|
|
test('响应式布局性能', async ({ page }) => {
|
|
await loginPage.goto();
|
|
await loginPage.login('admin', 'admin123');
|
|
await page.waitForURL(/.*dashboard/);
|
|
|
|
const viewports = [
|
|
{ width: 1920, height: 1080 },
|
|
{ width: 1366, height: 768 },
|
|
{ width: 768, height: 1024 },
|
|
{ width: 375, height: 667 },
|
|
];
|
|
|
|
for (const viewport of viewports) {
|
|
const startTime = Date.now();
|
|
|
|
await page.setViewportSize(viewport);
|
|
await page.reload();
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
const endTime = Date.now();
|
|
const loadTime = endTime - startTime;
|
|
|
|
console.log(`视口 ${viewport.width}x${viewport.height} 加载时间: ${loadTime}ms`);
|
|
expect(loadTime).toBeLessThan(3000);
|
|
}
|
|
});
|
|
});
|