4. 测试报告的数据模型设计

测试报告不是一张静态的表格,而是一份可查询、可聚合、可追溯的结构化数据集合。如果数据模型设计得过于扁平,后续做趋势分析、失败归因、质量看板时就会处处受限。本节围绕“一次测试执行”这个核心对象,拆解报告数据模型应包含的实体、字段与关系,并给出可落地的结构化设计思路。

一、核心原理:以执行记录为中心的实体关系

测试报告的数据模型本质上是一个以“测试执行(Test Run)”为根节点的树形结构。一次执行包含多个用例结果,每个用例结果包含多个步骤,每个步骤可挂载附件,同时用例结果和执行本身都携带分类、标签、环境等元信息。理解这个层级关系,是设计字段的前提。

测试报告数据模型:实体与字段关系 TestRun 测试执行 run_id · 开始/结束时间 · 触发人 Environment 环境信息 OS · 浏览器 · 版本 · 设备 Category 分类 模块 · 优先级 · 用例类型 CaseResult 用例结果 case_id · 状态 · 耗时 · 失败原因 重试次数 · 断言统计 Tag 标签 smoke · 回归 · 冒烟 Step 步骤 step_no · 操作 · 期望值 · 实际值 状态 · 耗时 · 截图 Attachment 附件 截图 · 日志 · 视频 Log 日志片段 时间戳 · 级别 · 消息 关系基数: TestRun 1 : N CaseResult | CaseResult 1 : N Step | Step 1 : N Attachment TestRun 1 : 1 Environment | CaseResult N : N Tag | CaseResult N : 1 Category

图中可以看到,环境信息挂在执行层,分类和标签挂在用例结果层,步骤和附件则继续向下延伸。这种分层设计让“按环境筛选”“按标签聚合”“按步骤定位失败点”都能通过一次查询完成。

二、核心字段设计:从标识到状态

每个实体都需要一组稳定的字段。标识字段用于唯一追踪,状态字段用于聚合统计,时间字段用于趋势分析,描述字段用于人工阅读。以下清单列出了各实体的关键字段。

实体 核心字段 类型 作用
TestRun run_id、start_time、end_time、trigger、env_id string / datetime 唯一标识一次执行,支撑趋势与对比
CaseResult case_id、title、status、duration、retry、fail_reason string / enum / int 记录用例级结论,支撑通过率统计
Step step_no、action、expected、actual、status、duration int / string / enum 定位失败发生在哪一步
Attachment attach_id、type、path、size、step_no string / int 关联截图、日志、视频等证据
Environment os、browser、browser_ver、device、base_url string 区分不同运行环境下的结果差异
Category / Tag category_id、name、tag_list string / array 支持多维筛选与聚合分析
状态字段建议使用枚举值统一管理,例如 passed、failed、skipped、error、blocked,避免出现“成功”“通过”“OK”等多种写法,否则统计时会产生大量脏数据。

三、结构化落地:JSON 示例与存储建议

在接口传输和持久化时,推荐使用嵌套 JSON 表达层级关系,同时把高频查询字段平铺到数据库列中。下面是一段典型的用例结果结构。

{
  "run_id": "RUN-20240612-001",
  "environment": {
    "os": "Windows 11",
    "browser": "Chrome",
    "browser_ver": "125.0",
    "base_url": "https://staging.example.com"
  },
  "case_result": {
    "case_id": "TC-LOGIN-003",
    "title": "错误密码登录应提示失败",
    "status": "failed",
    "duration_ms": 4820,
    "retry": 1,
    "category": "登录模块",
    "tags": ["smoke", "regression"],
    "fail_reason": "断言失败:期望提示文案不匹配",
    "steps": [
      {
        "step_no": 1,
        "action": "输入用户名",
        "expected": "输入框显示 admin",
        "actual": "输入框显示 admin",
        "status": "passed",
        "duration_ms": 320
      },
      {
        "step_no": 2,
        "action": "输入错误密码并点击登录",
        "expected": "提示“密码错误”",
        "actual": "提示“登录失败”",
        "status": "failed",
        "duration_ms": 2100,
        "attachments": [
          {"type": "screenshot", "path": "s3://reports/run001/tc003_step2.png"},
          {"type": "log", "path": "s3://reports/run001/tc003_step2.log"}
        ]
      }
    ]
  }
}

存储层面,建议把 run、case_result、step 拆成三张表,附件和标签用关联表维护。这样既能保证写入效率,也能让“查询某标签下所有失败用例”这类需求通过索引快速完成。

四、案例场景与常见误区

某团队最初把报告存成一张宽表,每行一个用例,步骤和附件用长文本拼接。结果做失败归因时,无法统计“第 2 步失败占比”,也无法按标签筛选。重构为上述分层模型后,质量看板可以直接输出“冒烟标签下失败率最高的模块”,排障效率明显提升。

常见误区有三类:一是把环境信息写死在用例里,导致同一用例在不同环境的结果无法区分;二是附件只存本地路径,报告迁移后图片全部失效;三是标签随意填写,没有统一词表,最终无法聚合。建议在模型设计阶段就固定枚举、统一路径规范、建立标签字典。

好的数据模型不是一次设计完成的,而是在报告被反复查询、聚合、对比的过程中逐步收敛。先保证层级清晰、字段稳定、枚举统一,再考虑扩展自定义字段,才能让测试报告真正成为质量分析的底座。