
前阵子有个做家居品类的客户跑过来问我一个挺实际的问题。他们那套AB页跳转规则已经堆了几十条分支了,每次改完配置,测试同学就挑几条主路径跑一下,上线之后时不时还是冒出来某类请求被扔到了不该去的页面。他问的是,能不能拿线上真实请求的抽样样本,把跳转分支的复现测试弄成一套稳定能跑的用例,别每次都靠人回忆。可以是可以,但得先把"抽样"和"复现"拆成两件事来设计,直接拿线上日志往测试环境一丢跑一遍,那不叫方案。
我按准备、执行、复盘三个阶段来说。每个阶段输入是啥、操作怎么做、验收卡在哪儿,都讲清楚。
准备阶段:先定义样本池和分支映射关系
抽样不是随机抓,而是按分支维度分层
我见过不少人一上来就从访问日志里随机抽一千条,跑完一看,覆盖的分支还是那几条。这跟抽签一个道理,随机抽样会天然往高频分支倒,低频但关键的边界分支压根抽不着。那怎么做才对?先把跳转规则的判定维度列出来,然后按维度分层抽。 判定维度一般就这几类:
- 流量来源特征:来源域名、Referer 是否存在、来源页面路径层级
- 请求头特征: User-Agent 大类、语言偏好、Accept 头组合
- 访问上下文: 是否携带特定查询参数、Cookie 中是否有历史标记
- 时间与频次: 请求落在哪个时间段、同一会话内的访问次数
分层怎么理解?每个维度先划出取值区间,再从每个区间里各抽若干条。举个具体的,User-Agent 大类分成移动端主流浏览器、桌面端主流浏览器、内置 WebView 三类,每类抽个 30 到 50 条,别让移动端一家占了九成。
输入条件:近 7 天的访问日志导出一份,字段至少得有请求时间、来源、User-Agent、URL 及查询串、命中的规则 ID。
操作:按上面那些维度做交叉分层,每层样本量控制在 20 到 50 条之间,总量几百条这个量级就行。样本量不用大,关键是每层都得有代表。 验收标准:抽样完了之后,把样本按现有规则跑一遍,看命中的分支数量能不能覆盖规则表里全部活跃分支。要是某个分支一条样本都没命中,那就是该层抽少了,得补。
抽完样本,接下来要给每条样本标注预期跳转目标。这一步别靠人工逐条判断,样本一多准出错。可行的办法是先用规则引擎在离线环境跑一遍,输出每条样本的命中分支和跳转目标,然后人工抽查其中一部分确认逻辑对不对。 这里有个坑得提一下:规则引擎离线跑的结果和线上实际结果可能对不上,原因出在环境差异上,比如缓存状态、Cookie 在不在、时间窗口判定依赖的服务器时间。所以标注预期结果的时候,必须把环境变量一并记下来,不然复现的时候对不上号。
验收标准:每条样本都得带三个字段——命中分支 ID、预期跳转目标、复现所需的环境变量清单。缺任何一个都算标注不完整。
执行阶段:让复现请求可控且可比对
复现请求要固定变量,只留一个待验证维度
样本准备好之后,执行阶段的核心就是控制变量。直接把线上请求原样重放到测试环境,请求里带的 Cookie、时间戳、来源信息全在变,出了问题你根本不知道是哪个维度导致的。
做法是把每条样本拆成两部分:固定部分和变动部分。固定部分就是这条样本要验证的判定维度,比如"Referer 为空时是否走兜底分支";变动部分是其他所有不影响该分支判定的字段,统一替换成测试环境的标准值。
举个例子:要验证"Referer 为空 + 移动端 UA"这个组合,构造请求时就把 Referer 留空,UA 固定成移动端标准串,其他头信息全部标准化。这么跑出来的结果如果和预期不符,就能直接定位到 Referer 判定这一环。
限制条件:时间窗口类分支没法用固定值复现,得借助测试环境的时间模拟能力,或者把判定逻辑里的时间参数抽出来做成可注入的配置。如果规则引擎不支持时间注入,这类分支只能标记为"不可复现",单独走人工验证。
批量执行时保留原始响应快照
几百条样本跑下来,光看通过率,出了问题很难回溯。执行阶段要强制保留每条请求的原始响应,包括状态码、跳转目标 URL、响应头里的缓存标记、以及规则引擎输出的判定日志。 操作上可以搞个简单的对比脚本:把实际跳转目标和预期跳转目标逐条比对,不一致的单独列出来。但要注意,跳转目标里可能带动态参数,比如会话 ID、时间戳,比对时得把这些参数归一化之后再比,否则会出现一大堆假阳性。
验收标准:执行完成后拿到三份产物——通过率统计、不一致清单、每条不一致样本的完整请求与响应快照。没有快照的不一致项视为无效问题,先补齐快照再排查。
复盘阶段:从失败样本反推规则缺陷
不一致样本要按信号类型归类
复盘不是逐条看不一致清单,而是先归类。常见的不一致可以分成几种信号类型:
- 判定条件遗漏:某类请求本应命中分支 A,实际走了兜底分支,说明规则里少了对应的条件。
- 优先级冲突: 两条规则同时命中,实际执行的和预期的不一致,说明优先级配置和设计文档对不上。
- 环境依赖未声明: 离线标注时没记录某个 Cookie 状态,导致复现结果和预期不同,属于标注缺陷而非规则缺陷。
- 边界值处理错误: 比如频次上限设为 3 次,第 3 次请求是否算超限,规则实现和设计意图不一致。
归类之后,前两类要改规则,第三类要补标注,第四类要回到设计文档确认意图。不同类型的问题流转给不同的人,不要混在一起讨论。
把复盘结论沉淀成回归用例
每轮复盘发现的缺陷,修完之后要把对应的样本升级成回归用例,纳入固定的测试集。这样下次改规则时,这批用例会被自动跑一遍,防止同一个问题反复出现。
这里要控制回归集的膨胀速度。不是所有样本都值得进回归集,只保留那些触发过真实缺陷、或者覆盖关键边界条件的样本。一般几十条到一百多条就够,太多会导致每次执行时间过长,反而没人愿意跑。
一个家居流量团队的匿名复盘
背景:某做家居内容导购的团队,日均跳转请求量在十几万,AB页跳转规则大约四十多条分支,服务器用的是两台 4 核 8G 的实例加一层 CDN。他们的跳转逻辑里有一部分依赖 Referer 和会话内访问次数。
踩的坑:他们最初的做法是每次改完规则,让测试同学手动挑十来条请求跑一遍。问题出在一次规则调整后,某个低频来源的请求开始大量落到默认落地页,而默认落地页的内容和该来源的用户预期不匹配,跳出率明显上升。事后查下来,是新增的一条判定条件把原本属于该来源的分支覆盖掉了,而手动测试没覆盖到这条来源。
调整过程:他们把近两周的访问日志按来源和 UA 做了分层抽样,每层抽了 30 条左右,总共凑了三百多条样本。然后给每条样本标注了命中分支和预期目标,用脚本批量复现。第一次跑下来,不一致的有一成多,归类后发现主要是优先级冲突和边界值处理两类问题。
最终状态:他们把修完问题后的样本筛出七十多条作为回归集,每次规则变更后自动跑一遍。执行时间从原来的人工半天缩短到十几分钟。那个低频来源的分支后来又被覆盖过一次,但因为回归集里有样本,上线前就发现了,没有影响到线上。
几个容易忽略的约束条件
访问日志里的请求特征会随时间变化,比如来源结构、UA 分布。用三个月前的样本做回归,可能已经不能代表当前流量。建议回归集每季度做一次校准,把长期未命中的样本换掉,补充新的边界样本。
至少这三项要对齐:规则配置版本、缓存策略、服务器时间基准。前两项不一致会导致判定结果不同,时间基准不一致会让时间窗口类分支全部失效。
不可复现的分支要显式标记
有些分支依赖真实用户行为序列,比如"同一会话内第三次访问才触发",这类在测试环境用单次请求复现不了。不要硬造请求去凑,而是在用例表里标记为"需人工验证",并在规则变更时提醒相关同学单独确认。
收束:一份可执行的检查项
把上面三个阶段压缩成一份可以直接对照的检查项:
- 抽样是否按判定维度分层,每层样本量是否足够覆盖对应分支
- 每条样本是否带有命中分支 ID、预期跳转目标、环境变量清单
- 复现请求是否固定了非验证维度,只留一个待验证变量
- 执行后是否保留完整请求与响应快照,而不只是通过率
- 不一致样本是否按信号类型归类,而不是逐条处理
- 回归集是否控制在合理规模,是否定期校准样本时效性
- 不可复现分支是否显式标记并纳入人工验证流程
把这七项跑顺,抽样请求复现就能从一次性的排查手段,变成规则变更时的常规动作。重点不在于样本量有多大,而在于每条样本都能回答"它验证的是哪个分支、失败了说明什么"。