scense/scripts/init_test_db.py

159 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""元景 scense 测试用例域库表幂等初始化脚本。
修复 Bug [e2Lck6zIRCXB5g7_HPZn0](环境根因):
sd_test_cases 用例库不可达——list_cases 返回字段全空scense 库无该表。
本脚本在应用 init() 阶段自动执行(也可独立运行),
用 CREATE TABLE IF NOT EXISTS 幂等创建测试用例域 3 张表:
sd_test_cases / sd_test_plans / sd_test_results
确保环境(重建/换库后用例库自动可达list_cases 不再返回全空。
用法:
1) 应用启动app/scense.py init() 中调用 ensure_test_db()
2) 独立执行python scripts/init_test_db.py读取 .env 连接)
"""
import os
# 建表 DDL 与 scripts/../sql/sd_test_cases.sql 保持一致(幂等 IF NOT EXISTS
_DDL_STATEMENTS = [
# ---------- sd_test_cases 测试用例表 ----------
"""
CREATE TABLE IF NOT EXISTS `sd_test_cases` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`case_id` VARCHAR(64) NOT NULL COMMENT '用例编码(业务唯一,如 TC-0001',
`case_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '用例名称list_cases 读取字段,兼容 case_name 命名)',
`title` VARCHAR(255) NOT NULL COMMENT '用例标题',
`description` TEXT NULL COMMENT '用例描述',
`module` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '所属模块',
`plan_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '所属测试计划ID',
`priority` VARCHAR(16) NOT NULL DEFAULT 'P2' COMMENT '优先级P0/P1/P2/P3',
`preconditions` TEXT NULL COMMENT '前置条件',
`steps` TEXT NULL COMMENT '测试步骤',
`expected_result` TEXT NULL COMMENT '预期结果',
`actual_result` TEXT NULL COMMENT '实际结果',
`status` VARCHAR(16) NOT NULL DEFAULT 'draft' COMMENT '用例状态draft/active/closed',
`execute_status` VARCHAR(16) NOT NULL DEFAULT 'not_run' COMMENT '执行状态not_run/pass/fail/blocked',
`created_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人',
`updated_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '更新人',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_case_id` (`case_id`),
KEY `idx_plan_id` (`plan_id`),
KEY `idx_module` (`module`),
KEY `idx_status` (`status`),
KEY `idx_execute_status` (`execute_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试用例表list_cases 数据来源)'
""",
# ---------- sd_test_plans 测试计划表 ----------
"""
CREATE TABLE IF NOT EXISTS `sd_test_plans` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`plan_id` VARCHAR(64) NOT NULL COMMENT '测试计划ID',
`plan_name` VARCHAR(255) NOT NULL COMMENT '计划名称',
`iteration_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '所属迭代ID',
`description` TEXT NULL COMMENT '计划描述',
`status` VARCHAR(16) NOT NULL DEFAULT 'draft' COMMENT '计划状态draft/approved/in_progress/done',
`created_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_plan_id` (`plan_id`),
KEY `idx_iteration_id` (`iteration_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试计划表'
""",
# ---------- sd_test_results 测试执行结果表 ----------
"""
CREATE TABLE IF NOT EXISTS `sd_test_results` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`result_id` VARCHAR(64) NOT NULL COMMENT '执行结果ID',
`case_id` VARCHAR(64) NOT NULL COMMENT '用例编码',
`plan_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '所属测试计划ID',
`run_status` VARCHAR(16) NOT NULL DEFAULT 'not_run' COMMENT '执行结果pass/fail/blocked/skipped',
`actual_result` TEXT NULL COMMENT '实际结果描述',
`bug_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '失败联动Bug ID',
`executed_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '执行人',
`executed_at` DATETIME NULL COMMENT '执行时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_result_id` (`result_id`),
KEY `idx_case_id` (`case_id`),
KEY `idx_plan_id` (`plan_id`),
KEY `idx_run_status` (`run_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='测试执行结果表'
""",
]
def _dbname():
"""取主库名(多级兜底,不硬编码)。
优先级:
1) ServerEnv params['dbname']应用运行期appbase 写入)
2) conf/config.json 的 module_dbname 映射(独立部署脚本场景)
3) 环境变量 MYSQL_DATABASE
4) 默认 'scense'(单库应用约定)
"""
# 1) ServerEnv应用内
try:
from ahserver.serverenv import ServerEnv
env = ServerEnv()
if getattr(env, 'params', None) and env.params.get('dbname'):
return env.params.get('dbname')
except Exception:
pass
# 2) conf/config.json module_dbname 映射
try:
import json
from pathlib import Path
cfg_path = Path(__file__).resolve().parent.parent / 'conf' / 'config.json'
if cfg_path.exists():
cfg = json.loads(cfg_path.read_text(encoding='utf-8'))
mapping = cfg.get('module_dbname') or {}
if isinstance(mapping, dict) and mapping.get('scense'):
return mapping['scense']
if cfg.get('dbname'):
return cfg['dbname']
except Exception:
pass
# 3) 环境变量
if os.environ.get('MYSQL_DATABASE'):
return os.environ['MYSQL_DATABASE']
# 4) 默认
return 'scense'
def ensure_test_db():
"""幂等创建测试用例域表。重复执行安全;某条失败记录日志不中断后续。"""
from sqlor import sor
dbname = _dbname()
created = []
for ddl in _DDL_STATEMENTS:
try:
sor.sqlExe(dbname, ddl)
created.append(_table_name_of(ddl))
except Exception as e: # noqa: BLE001 - 初始化容错,不因单表失败阻塞应用启动
print('[init_test_db] create table failed: %s (%s)' % (_table_name_of(ddl), e))
print('[init_test_db] ensured tables in db[%s]: %s' % (dbname, created))
return created
def _table_name_of(ddl):
import re
m = re.search(r'CREATE TABLE IF NOT EXISTS `([^`]+)`', ddl)
return m.group(1) if m else '?'
if __name__ == '__main__':
# 独立执行:加载 .env 环境变量后调用
from pathlib import Path
env_path = Path(__file__).resolve().parent.parent / '.env'
if env_path.exists():
for line in env_path.read_text(encoding='utf-8').splitlines():
line = line.strip()
if line and not line.startswith('#') and '=' in line:
k, _, v = line.partition('=')
os.environ.setdefault(k.strip(), v.strip())
ensure_test_db()