JSON 解码只能确认格式,不代表字段齐全;把第三方日志转换成本文中间格式时,应另外核对键名、单位和类型。本文从Node构建JSON清单的受控中间格式读取记录,统一使用毫秒和退出码。一批耗时样本可能被单个极慢任务拉高平均值,因此这里换用中位数观察中心位置。
先固定可回放的数据
前端构建包装器可在一次运行结束后,把各阶段结果整理为受控中间格式,交给离线看板回放。这里采用对象数组保存完整快照,故意留下两次同名测试,使失败尝试不会被后来的成功覆盖。验收先确认数组成员仍是独立事件,再检查耗时与退出状态没有被显示层改写。
importjson raw='[{"step":"build","ms":120,"code":0},{"step":"test","ms":40,"code":1},{"step":"test","ms":60,"code":0},{"step":"pack","ms":80,"code":2}]'恢复结构并统一字段
清单顶层是记录数组,每条记录包含步骤名、毫秒数和退出码。读取结构化 JSON 可以保留数值类型,不需要从彩色终端输出里猜测字段。
rows=json.loads(raw)ifany(r["ms"]<0forrinrows):raiseValueError()计算本篇的指标
排序后取中间值,偶数样本取两个中心值的平均。中位数降低极端样本对中心指标的影响,但不应掩盖单独失败或超慢的执行。
times=sorted(r["ms"]forrinrows)n=len(times);result=(times[(n-1)//2]+times[n//2])/2ifnelseNone对照独立期望值
独立期望值先从耗时列表排序后得到。对照时要检查返回值允许出现小数,而且输入顺序改变不影响中心结果;如果复制到其他报表,还应固定空样本使用空值而不是随意返回零的约定。
want=70.0ifresult!=want:raiseValueError(result)print(result)样本数量故意设为偶数,让实现必须走两个中心元素的路径。
排列保持无序,迫使计算阶段完成数值排序;退出码保留但不参与筛选,以免把“全部执行”的中位数变成成功样本中位数。
扩展耗时中位数计算之前,补充空输入、单条记录与重复步骤的测试,再核对单位和排序方式。