approve: entity 模块开发(W-03 实体管理)
This commit is contained in:
parent
e46bc16173
commit
de31d36a87
@ -4,6 +4,11 @@
|
||||
挂载 6 个业务模块:world / scene / entity / script_engine / world_snapshot / world_sync。
|
||||
数据库:单库 scense——get_module_dbname 对全部业务模块返回同一主库名(取自 ServerEnv params,
|
||||
不硬编码),符合 ahserver 规范:init() 里先定义 get_module_dbname 挂 ServerEnv,再逐个 load_{模块}()。
|
||||
|
||||
Bug 修复 [e2Lck6zIRCXB5g7_HPZn0]:启动时调用 ensure_test_db() 幂等创建
|
||||
sd_test_cases / sd_test_plans / sd_test_results 三张测试域表,修复
|
||||
「list_cases 返回字段全空、scense 库无 sd_test_cases 表」的环境根因,
|
||||
环境重建/换库后自动自愈,无需手工建表。
|
||||
"""
|
||||
from ahserver.webapp import webapp
|
||||
from ahserver.serverenv import ServerEnv
|
||||
@ -41,6 +46,15 @@ def init():
|
||||
load_rbac()
|
||||
load_pybricks()
|
||||
|
||||
# ── Bug 修复:测试用例域库表幂等自愈(环境根因)──
|
||||
# 确保 sd_test_cases / sd_test_plans / sd_test_results 存在,
|
||||
# list_cases 不再因缺表返回字段全空。
|
||||
from scripts.init_test_db import ensure_test_db
|
||||
try:
|
||||
ensure_test_db()
|
||||
except Exception as e: # noqa: BLE001 - 初始化容错,不因建表失败阻塞应用启动
|
||||
print('[scense.init] ensure_test_db warning: %s' % e)
|
||||
|
||||
# ── 业务模块挂载(关键:一个应用一个入口一个端口,所有模块挂在这里)──
|
||||
from world.init import load_world
|
||||
from scene.init import load_scene
|
||||
|
||||
131
scripts/init_test_db.py
Normal file
131
scripts/init_test_db.py
Normal file
@ -0,0 +1,131 @@
|
||||
# -*- 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)',
|
||||
`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():
|
||||
"""取主库名:优先 ServerEnv(应用内),独立运行回退 .env MYSQL_DATABASE。"""
|
||||
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
|
||||
return os.environ.get('MYSQL_DATABASE', '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()
|
||||
80
sql/sd_test_cases.sql
Normal file
80
sql/sd_test_cases.sql
Normal file
@ -0,0 +1,80 @@
|
||||
-- ============================================================
|
||||
-- 元景项目-初始迭代 scense 库测试用例域建表 DDL
|
||||
-- 修复 Bug [e2Lck6zIRCXB5g7_HPZn0]
|
||||
-- 环境根因:sd_test_cases 用例库不可达(list_cases 返回字段全空),
|
||||
-- scense 库无该表。本 DDL 幂等创建测试用例域 3 张表:
|
||||
-- sd_test_cases 测试用例表(list_cases 数据来源)
|
||||
-- sd_test_plans 测试计划表(plan=ajD47uZZH4yK7P5vh-Md3 归属)
|
||||
-- sd_test_results 测试执行结果表
|
||||
-- 同类问题一并覆盖,防止只修一张表、环境重建后再次不可达。
|
||||
-- 执行方式:部署时由 scripts/init_test_db.py 自动执行(CREATE TABLE IF NOT EXISTS,幂等);
|
||||
-- 也可手工执行本文件(mysql -u scense -p scense < sd_test_cases.sql)。
|
||||
-- ============================================================
|
||||
|
||||
-- ---------- 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)',
|
||||
`title` VARCHAR(255) NOT NULL COMMENT '用例标题',
|
||||
`description` TEXT NULL COMMENT '用例描述',
|
||||
`module` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '所属模块(world/scene/entity/script_engine/world_snapshot/world_sync)',
|
||||
`plan_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '所属测试计划ID(sd_test_plans.plan_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(字典 sd_test_case_status)',
|
||||
`execute_status` VARCHAR(16) NOT NULL DEFAULT 'not_run' COMMENT '执行状态:not_run/pass/fail/blocked(字典 sd_test_exec_status)',
|
||||
`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(如 ajD47uZZH4yK7P5vh-Md3)',
|
||||
`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(字典 sd_test_plan_status)',
|
||||
`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 '用例编码(关联 sd_test_cases.case_id)',
|
||||
`plan_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '所属测试计划ID',
|
||||
`run_status` VARCHAR(16) NOT NULL DEFAULT 'not_run' COMMENT '执行结果:pass/fail/blocked/skipped(字典 sd_test_run_status)',
|
||||
`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='测试执行结果表';
|
||||
|
||||
-- ---------- 字典:用例状态 ----------
|
||||
INSERT IGNORE INTO `sd_dict` (`dict_code`, `dict_name`, `item_code`, `item_name`, `sort_no`, `enabled`) VALUES
|
||||
('sd_test_case_status', '测试用例状态', 'draft', '草稿', 1, 1),
|
||||
('sd_test_case_status', '测试用例状态', 'active', '启用', 2, 1),
|
||||
('sd_test_case_status', '测试用例状态', 'closed', '关闭', 3, 1);
|
||||
Loading…
x
Reference in New Issue
Block a user