-- ============================================================
-- 数据库名称: automation
-- 字符集: utf8mb4 (支持 emoji 和特殊字符)
-- 排序规则: utf8mb4_unicode_ci
-- ============================================================
-- 创建数据库(如果不存在)
CREATE DATABASE IF NOT EXISTS `automation`
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE `automation`;
-- ============================================================
-- 1. 测试用例表 (test_case)
-- ============================================================
DROP TABLE IF EXISTS `test_case`;
CREATE TABLE `test_case` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`case_id` VARCHAR(64) NOT NULL COMMENT '用例唯一标识 (类名#方法名)',
`name` VARCHAR(200) NOT NULL COMMENT '用例名称',
`description` VARCHAR(500) DEFAULT NULL COMMENT '用例描述',
`class_name` VARCHAR(255) NOT NULL COMMENT '测试类全路径',
`method_name` VARCHAR(100) NOT NULL COMMENT '测试方法名',
`framework` VARCHAR(20) NOT NULL DEFAULT 'SELENIUM' COMMENT '框架类型: SELENIUM, PLAYWRIGHT',
`test_group` VARCHAR(50) DEFAULT 'default' COMMENT '测试分组',
`priority` INT DEFAULT 0 COMMENT '优先级: 0-10, 数字越小优先级越高',
`status` VARCHAR(20) DEFAULT 'READY' COMMENT '状态: READY, RUNNING, PASSED, FAILED, DISABLED',
`is_active` TINYINT(1) DEFAULT 1 COMMENT '是否启用: 1-启用, 0-禁用',
`tags` VARCHAR(200) DEFAULT NULL COMMENT '标签,逗号分隔',
`parameters` TEXT DEFAULT NULL COMMENT '参数配置 (JSON格式)',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_case_id` (`case_id`),
KEY `idx_class_name` (`class_name`),
KEY `idx_framework` (`framework`),
KEY `idx_test_group` (`test_group`),
KEY `idx_status` (`status`),
KEY `idx_is_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试用例表';
-- ============================================================
-- 2. 测试执行记录表 (test_execution)
-- ============================================================
DROP TABLE IF EXISTS `test_execution`;
CREATE TABLE `test_execution` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`execution_id` VARCHAR(64) NOT NULL COMMENT '执行ID (UUID)',
`case_id` BIGINT NOT NULL COMMENT '测试用例ID (关联 test_case.id)',
`case_name` VARCHAR(200) NOT NULL COMMENT '用例名称 (冗余)',
`task_id` VARCHAR(64) DEFAULT NULL COMMENT '任务ID (批量执行时关联)',
`suite_name` VARCHAR(200) DEFAULT NULL COMMENT '测试套件名称',
`status` VARCHAR(20) NOT NULL DEFAULT 'RUNNING' COMMENT '状态: RUNNING, PASSED, FAILED, SKIPPED',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME DEFAULT NULL COMMENT '结束时间',
`duration_ms` BIGINT DEFAULT NULL COMMENT '执行耗时(毫秒)',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`stack_trace` TEXT DEFAULT NULL COMMENT '异常堆栈',
`screenshot_path` VARCHAR(500) DEFAULT NULL COMMENT '截图路径',
`log_path` VARCHAR(500) DEFAULT NULL COMMENT '日志路径',
`report_url` VARCHAR(500) DEFAULT NULL COMMENT '报告URL',
`environment` VARCHAR(50) DEFAULT 'test' COMMENT '环境: test, staging, production',
`browser_type` VARCHAR(20) DEFAULT 'chromium' COMMENT '浏览器类型',
`headless` TINYINT(1) DEFAULT 0 COMMENT '是否无头模式',
`retry_count` INT DEFAULT 0 COMMENT '重试次数',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_execution_case` (`execution_id`, `case_id`),
KEY `idx_execution_id` (`execution_id`),
KEY `idx_case_id` (`case_id`),
KEY `idx_status` (`status`),
KEY `idx_start_time` (`start_time`),
KEY `idx_task_id` (`task_id`),
KEY `idx_environment` (`environment`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试执行记录表';
-- ============================================================
-- 3. 测试执行汇总表 (test_execution_summary)
-- ============================================================
DROP TABLE IF EXISTS `test_execution_summary`;
CREATE TABLE `test_execution_summary` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`execution_id` VARCHAR(64) NOT NULL COMMENT '执行ID',
`suite_name` VARCHAR(200) DEFAULT NULL COMMENT '测试套件名称',
`total_tests` INT DEFAULT 0 COMMENT '总用例数',
`passed_tests` INT DEFAULT 0 COMMENT '通过数',
`failed_tests` INT DEFAULT 0 COMMENT '失败数',
`skipped_tests` INT DEFAULT 0 COMMENT '跳过数',
`total_duration_ms` BIGINT DEFAULT 0 COMMENT '总耗时(毫秒)',
`pass_rate` DECIMAL(5,2) DEFAULT 0.00 COMMENT '通过率(%)',
`status` VARCHAR(20) DEFAULT 'RUNNING' COMMENT '状态: RUNNING, PASSED, FAILED',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME DEFAULT NULL COMMENT '结束时间',
`triggered_by` VARCHAR(100) DEFAULT NULL COMMENT '触发人/触发方式',
`environment` VARCHAR(50) DEFAULT 'test' COMMENT '环境',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_execution_id` (`execution_id`),
KEY `idx_start_time` (`start_time`),
KEY `idx_status` (`status`),
KEY `idx_environment` (`environment`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试执行汇总表';
-- ============================================================
-- 4. 测试报告表 (test_report)
-- ============================================================
DROP TABLE IF EXISTS `test_report`;
CREATE TABLE `test_report` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`execution_id` VARCHAR(64) NOT NULL COMMENT '执行ID',
`report_name` VARCHAR(200) NOT NULL COMMENT '报告名称',
`report_type` VARCHAR(30) DEFAULT 'EXTENT' COMMENT '报告类型: EXTENT, ALLURE, JUNIT',
`report_path` VARCHAR(500) NOT NULL COMMENT '报告文件路径',
`report_url` VARCHAR(500) DEFAULT NULL COMMENT '报告访问URL',
`file_size` BIGINT DEFAULT 0 COMMENT '文件大小(字节)',
`generated_at` DATETIME NOT NULL COMMENT '生成时间',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_execution_id` (`execution_id`),
KEY `idx_report_type` (`report_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试报告表';
-- ============================================================
-- 5. 测试套件配置表 (test_suite)
-- ============================================================
DROP TABLE IF EXISTS `test_suite`;
CREATE TABLE `test_suite` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`suite_id` VARCHAR(64) NOT NULL COMMENT '套件唯一标识',
`name` VARCHAR(200) NOT NULL COMMENT '套件名称',
`description` VARCHAR(500) DEFAULT NULL COMMENT '套件描述',
`test_case_ids` TEXT DEFAULT NULL COMMENT '包含的测试用例ID列表 (JSON数组)',
`parallel` TINYINT(1) DEFAULT 0 COMMENT '是否并行执行',
`thread_count` INT DEFAULT 1 COMMENT '并行线程数',
`browser_type` VARCHAR(20) DEFAULT 'chromium' COMMENT '默认浏览器类型',
`headless` TINYINT(1) DEFAULT 0 COMMENT '是否无头模式',
`environment` VARCHAR(50) DEFAULT 'test' COMMENT '默认环境',
`retry_count` INT DEFAULT 0 COMMENT '失败重试次数',
`timeout_seconds` INT DEFAULT 300 COMMENT '超时时间(秒)',
`schedule` VARCHAR(100) DEFAULT NULL COMMENT '定时任务配置 (CRON表达式)',
`is_active` TINYINT(1) DEFAULT 1 COMMENT '是否启用',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_suite_id` (`suite_id`),
KEY `idx_is_active` (`is_active`),
KEY `idx_environment` (`environment`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试套件配置表';
-- ============================================================
-- 6. 用户表 (user) - 用于认证和权限
-- ============================================================
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`password` VARCHAR(255) NOT NULL COMMENT '密码 (加密存储)',
`email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
`real_name` VARCHAR(50) DEFAULT NULL COMMENT '真实姓名',
`role` VARCHAR(20) DEFAULT 'USER' COMMENT '角色: ADMIN, USER, VIEWER',
`status` VARCHAR(20) DEFAULT 'ACTIVE' COMMENT '状态: ACTIVE, INACTIVE, LOCKED',
`last_login_at` DATETIME DEFAULT NULL COMMENT '最后登录时间',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`),
UNIQUE KEY `uk_email` (`email`),
KEY `idx_role` (`role`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-- ============================================================
-- 7. 操作日志表 (operation_log)
-- ============================================================
DROP TABLE IF EXISTS `operation_log`;
CREATE TABLE `operation_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT DEFAULT NULL COMMENT '操作用户ID',
`username` VARCHAR(50) DEFAULT NULL COMMENT '操作用户名',
`operation` VARCHAR(100) NOT NULL COMMENT '操作类型: EXECUTE_TEST, CREATE_CASE, UPDATE_CASE, DELETE_CASE',
`target_id` VARCHAR(64) DEFAULT NULL COMMENT '目标ID',
`target_type` VARCHAR(50) DEFAULT NULL COMMENT '目标类型: TEST_CASE, TEST_SUITE, EXECUTION',
`detail` TEXT DEFAULT NULL COMMENT '操作详情 (JSON)',
`ip_address` VARCHAR(50) DEFAULT NULL COMMENT 'IP地址',
`user_agent` VARCHAR(255) DEFAULT NULL COMMENT 'User-Agent',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_operation` (`operation`),
KEY `idx_created_at` (`created_at`),
KEY `idx_target_id` (`target_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志表';
-- ============================================================
-- 8. 系统配置表 (system_config)
-- ============================================================
DROP TABLE IF EXISTS `system_config`;
CREATE TABLE `system_config` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`config_key` VARCHAR(100) NOT NULL COMMENT '配置键',
`config_value` TEXT DEFAULT NULL COMMENT '配置值',
`config_type` VARCHAR(20) DEFAULT 'STRING' COMMENT '配置类型: STRING, INTEGER, BOOLEAN, JSON',
`description` VARCHAR(500) DEFAULT NULL COMMENT '配置描述',
`is_sensitive` TINYINT(1) DEFAULT 0 COMMENT '是否敏感信息',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_config_key` (`config_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统配置表';
-- ============================================================
-- 插入初始数据
-- ============================================================
-- 1. 插入用户数据 (密码: admin123 / user123)
INSERT INTO `user` (`username`, `password`, `email`, `real_name`, `role`, `status`) VALUES
('admin', '2a10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKV6G1mu', 'admin@automation.com', '管理员', 'ADMIN', 'ACTIVE'),
('tester', '2a10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKV6G1mu', 'tester@automation.com', '测试工程师', 'USER', 'ACTIVE'),
('viewer', '2a10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKV6G1mu', 'viewer@automation.com', '观察员', 'VIEWER', 'ACTIVE');
-- 2. 插入测试用例数据
INSERT INTO `test_case` (`case_id`, `name`, `description`, `class_name`, `method_name`, `framework`, `test_group`, `priority`, `status`, `is_active`) VALUES
('LoginTest#testLoginWithValidUser', '有效用户登录', '使用有效凭证登录系统', 'com.automation.test.testcases.selenium.LoginTest', 'testLoginWithValidUser', 'SELENIUM', 'login', 1, 'READY', 1),
('LoginTest#testLoginWithInvalidUser', '无效用户登录', '使用无效凭证登录,验证错误提示', 'com.automation.test.testcases.selenium.LoginTest', 'testLoginWithInvalidUser', 'SELENIUM', 'login', 2, 'READY', 1),
('LoginPlaywrightTest#testLoginWithValidUser', 'Playwright 有效用户登录', '使用 Playwright 和有效凭证登录', 'com.automation.test.testcases.playwright.LoginPlaywrightTest', 'testLoginWithValidUser', 'PLAYWRIGHT', 'login-playwright', 3, 'READY', 1),
('LoginPlaywrightTest#testLoginWithInvalidUser', 'Playwright 无效用户登录', '使用 Playwright 和无效凭证登录', 'com.automation.test.testcases.playwright.LoginPlaywrightTest', 'testLoginWithInvalidUser', 'PLAYWRIGHT', 'login-playwright', 4, 'READY', 1),
('HomePageTest#testHomePageLoad', '首页加载测试', '验证首页是否正常加载', 'com.automation.test.testcases.selenium.HomePageTest', 'testHomePageLoad', 'SELENIUM', 'home', 5, 'READY', 1),
('ForgotPasswordTest#testResetPassword', '忘记密码功能测试', '验证忘记密码流程', 'com.automation.test.testcases.selenium.ForgotPasswordTest', 'testResetPassword', 'SELENIUM', 'account', 6, 'READY', 1);
-- 3. 插入测试套件数据
INSERT INTO `test_suite` (`suite_id`, `name`, `description`, `test_case_ids`, `parallel`, `thread_count`, `browser_type`, `headless`, `environment`, `retry_count`, `timeout_seconds`, `is_active`) VALUES
('smoke-suite', '冒烟测试套件', '核心功能冒烟测试', '"LoginTest#testLoginWithValidUser", "LoginPlaywrightTest#testLoginWithValidUser"', 0, 1, 'chromium', 0, 'test', 2, 300, 1),
('regression-suite', '回归测试套件', '完整回归测试', '"LoginTest#testLoginWithValidUser", "LoginTest#testLoginWithInvalidUser", "LoginPlaywrightTest#testLoginWithValidUser", "LoginPlaywrightTest#testLoginWithInvalidUser", "HomePageTest#testHomePageLoad"', 1, 3, 'chromium', 0, 'test', 1, 600, 1),
('playwright-suite', 'Playwright 测试套件', 'Playwright 框架测试', '"LoginPlaywrightTest#testLoginWithValidUser", "LoginPlaywrightTest#testLoginWithInvalidUser"', 0, 1, 'chromium', 0, 'test', 1, 300, 1);
-- 4. 插入系统配置
INSERT INTO `system_config` (`config_key`, `config_value`, `config_type`, `description`, `is_sensitive`) VALUES
('test.default.browser', 'chromium', 'STRING', '默认浏览器类型', 0),
('test.default.headless', 'false', 'BOOLEAN', '默认无头模式', 0),
('test.default.timeout', '30', 'INTEGER', '默认超时时间(秒)', 0),
('test.retry.count', '3', 'INTEGER', '失败重试次数', 0),
('test.parallel.enabled', 'false', 'BOOLEAN', '是否启用并行执行', 0),
('test.parallel.threads', '4', 'INTEGER', '并行执行线程数', 0),
('report.retention.days', '30', 'INTEGER', '报告保留天数', 0),
('screenshot.retention.days', '30', 'INTEGER', '截图保留天数', 0),
('smtp.host', 'smtp.gmail.com', 'STRING', '邮件服务器地址', 0),
('smtp.port', '587', 'INTEGER', '邮件服务器端口', 0),
('alert.email.recipients', 'admin@automation.com,tester@automation.com', 'STRING', '告警邮件接收人', 0);
-- ============================================================
-- 创建视图
-- ============================================================
-- 视图: 测试用例执行统计
DROP VIEW IF EXISTS `v_test_case_statistics`;
CREATE VIEW `v_test_case_statistics` AS
SELECT
tc.case_id,
tc.framework,
tc.test_group,
tc.status,
tc.is_active,
COUNT(te.id) AS execution_count,
SUM(CASE WHEN te.status = 'PASSED' THEN 1 ELSE 0 END) AS passed_count,
SUM(CASE WHEN te.status = 'FAILED' THEN 1 ELSE 0 END) AS failed_count,
ROUND(IFNULL(SUM(CASE WHEN te.status = 'PASSED' THEN 1 ELSE 0 END) * 100.0 / COUNT(te.id), 0), 2) AS pass_rate,
AVG(te.duration_ms) AS avg_duration_ms,
MAX(te.start_time) AS last_execution_time
FROM test_case tc
LEFT JOIN test_execution te ON tc.id = te.case_id
GROUP BY tc.id;
-- 视图: 最近执行汇总
DROP VIEW IF EXISTS `v_recent_executions`;
CREATE VIEW `v_recent_executions` AS
SELECT
tes.execution_id,
tes.suite_name,
tes.total_tests,
tes.passed_tests,
tes.failed_tests,
tes.skipped_tests,
tes.pass_rate,
tes.status,
tes.start_time,
tes.end_time,
TIMESTAMPDIFF(SECOND, tes.start_time, tes.end_time) AS duration_seconds,
tes.environment,
tes.triggered_by
FROM test_execution_summary tes
ORDER BY tes.start_time DESC
LIMIT 100;
-- ============================================================
-- 创建存储过程
-- ============================================================
-- 存储过程: 清理过期数据
DELIMITER $$
DROP PROCEDURE IF EXISTS `clean_expired_data`$$
CREATE PROCEDURE `clean_expired_data`(IN retention_days INT)
BEGIN
DECLARE cutoff_date DATETIME;
SET cutoff_date = DATE_SUB(NOW(), INTERVAL retention_days DAY);
-- 清理过期的执行记录
DELETE FROM test_execution
WHERE end_time IS NOT NULL
AND end_time < cutoff_date;
-- 清理过期的汇总记录
DELETE FROM test_execution_summary
WHERE end_time IS NOT NULL
AND end_time < cutoff_date;
-- 清理过期的报告
DELETE FROM test_report
WHERE generated_at < cutoff_date;
-- 清理过期的日志(如果关联表存在)
-- DELETE FROM operation_log WHERE created_at < cutoff_date;
SELECT ROW_COUNT() AS deleted_count;
END$$
-- 存储过程: 获取测试用例执行趋势
DROP PROCEDURE IF EXISTS `get_execution_trend`$$
CREATE PROCEDURE `get_execution_trend`(IN days INT)
BEGIN
SELECT
DATE(start_time) AS exec_date,
COUNT(DISTINCT execution_id) AS exec_count,
SUM(CASE WHEN status = 'PASSED' THEN 1 ELSE 0 END) AS passed_count,
SUM(CASE WHEN status = 'FAILED' THEN 1 ELSE 0 END) AS failed_count,
ROUND(SUM(CASE WHEN status = 'PASSED' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS pass_rate
FROM test_execution
WHERE start_time >= DATE_SUB(NOW(), INTERVAL days DAY)
GROUP BY DATE(start_time)
ORDER BY exec_date DESC;
END$$
-- 存储过程: 生成执行报告
DROP PROCEDURE IF EXISTS `generate_execution_report`$$
CREATE PROCEDURE `generate_execution_report`(IN p_execution_id VARCHAR(64))
BEGIN
SELECT
tes.execution_id,
tes.suite_name,
tes.total_tests,
tes.passed_tests,
tes.failed_tests,
tes.skipped_tests,
tes.pass_rate,
tes.status,
tes.start_time,
tes.end_time,
tes.duration_seconds,
te.case_name,
te.status AS test_status,
te.duration_ms,
te.error_message,
te.screenshot_path
FROM test_execution_summary tes
LEFT JOIN test_execution te ON tes.execution_id = te.execution_id
WHERE tes.execution_id = p_execution_id
ORDER BY te.start_time;
END$$
-- 存储过程: 批量插入测试用例
DROP PROCEDURE IF EXISTS `batch_insert_test_cases`$$
CREATE PROCEDURE `batch_insert_test_cases`(
IN case_data JSON
)
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE total INT DEFAULT JSON_LENGTH(case_data);
WHILE i < total DO
INSERT INTO test_case (
case_id, name, description, class_name, method_name,
framework, test_group, priority, status, is_active
) VALUES (
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.case_id'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.name'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.description'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.class_name'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.method_name'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.framework'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.test_group'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.priority'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.status'))),
JSON_UNQUOTE(JSON_EXTRACT(case_data, CONCAT('$', i, '.is_active')))
);
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
-- ============================================================
-- 创建触发器
-- ============================================================
-- 触发器: 执行记录插入后更新汇总表
DELIMITER $$
DROP TRIGGER IF EXISTS `after_execution_insert`$$
CREATE TRIGGER `after_execution_insert`
AFTER INSERT ON `test_execution`
FOR EACH ROW
BEGIN
-- 检查是否已有对应的汇总记录
IF NOT EXISTS (SELECT 1 FROM test_execution_summary WHERE execution_id = NEW.execution_id) THEN
INSERT INTO test_execution_summary (
execution_id, suite_name, total_tests, start_time, environment, status
) VALUES (
NEW.execution_id,
NEW.suite_name,
1,
NEW.start_time,
NEW.environment,
'RUNNING'
);
ELSE
-- 更新总用例数
UPDATE test_execution_summary
SET total_tests = total_tests + 1
WHERE execution_id = NEW.execution_id;
END IF;
END$$
-- 触发器: 执行记录更新后更新汇总表
DROP TRIGGER IF EXISTS `after_execution_update`$$
CREATE TRIGGER `after_execution_update`
AFTER UPDATE ON `test_execution`
FOR EACH ROW
BEGIN
DECLARE passed INT;
DECLARE failed INT;
DECLARE skipped INT;
DECLARE total INT;
DECLARE pass_rate DECIMAL(5,2);
-- 统计该执行下的各状态数量
SELECT
COUNT(*) INTO total,
SUM(CASE WHEN status = 'PASSED' THEN 1 ELSE 0 END) INTO passed,
SUM(CASE WHEN status = 'FAILED' THEN 1 ELSE 0 END) INTO failed,
SUM(CASE WHEN status = 'SKIPPED' THEN 1 ELSE 0 END) INTO skipped
FROM test_execution
WHERE execution_id = NEW.execution_id;
SET pass_rate = IF(total > 0, ROUND(passed * 100.0 / total, 2), 0);
UPDATE test_execution_summary
SET
passed_tests = passed,
failed_tests = failed,
skipped_tests = skipped,
pass_rate = pass_rate,
status = CASE
WHEN failed = 0 AND passed = total AND total > 0 THEN 'PASSED'
WHEN failed > 0 THEN 'FAILED'
ELSE 'RUNNING'
END,
end_time = CASE
WHEN NEW.status IN ('PASSED', 'FAILED', 'SKIPPED')
AND NOT EXISTS (
SELECT 1 FROM test_execution
WHERE execution_id = NEW.execution_id AND status = 'RUNNING'
)
THEN NEW.end_time
ELSE end_time
END
WHERE execution_id = NEW.execution_id;
END$$
DELIMITER ;
-- ============================================================
-- 索引优化建议
-- ============================================================
-- 如果数据量很大,可以添加以下索引优化查询性能
-- CREATE INDEX idx_execution_status_start ON test_execution(status, start_time DESC);
-- CREATE INDEX idx_summary_start ON test_execution_summary(start_time DESC);
-- CREATE INDEX idx_log_created ON operation_log(created_at DESC);
-- ============================================================
-- 查询示例
-- ============================================================
-- 1. 查询最近10次执行记录
-- SELECT * FROM v_recent_executions;
-- 2. 查询测试用例执行统计
-- SELECT * FROM v_test_case_statistics;
-- 3. 查询某天执行趋势
-- CALL get_execution_trend(7);
-- 4. 清理30天前的数据
-- CALL clean_expired_data(30);
-- 5. 获取执行报告
-- CALL generate_execution_report('execution-id-here');
dockers初始化数据库脚本
-- init.sql (用于 Docker 初始化)
-- 这个脚本会在 MySQL 容器首次启动时自动执行
-- 创建数据库
CREATE DATABASE IF NOT EXISTS `automation`
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
-- 切换到数据库
USE `automation`;
-- 这里可以引用上面的完整 SQL
-- 或者将上面的 SQL 内容全部复制到这里
-- 授予权限(如果需要)
GRANT ALL PRIVILEGES ON automation.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;