影刀RPA工程实战:构建多平台店群自动化的流程仿真测试与沙箱环境体系

影刀RPA工程实战:构建多平台店群自动化的流程仿真测试与沙箱环境体系

一个改了三个节点的流程直接上了生产,结果把十个店铺的商品标题全改成了乱码。
不是流程写得不对,是它从来没有在真实环境里完整跑过一遍。

我们曾经有一个很天真的假设:流程在开发环境跑通一次,就等于没问题了。店群规模小的时候,这个假设勉强成立。但当店铺数量突破30个,流程版本迭代加快,线上事故开始频繁出现——不是流程逻辑错了,而是某些页面状态、数据边界条件、环境差异在开发环境里根本没出现过。

核心矛盾很简单:我们不敢在生产环境里做充分测试,但开发环境又模拟不了生产的复杂度。

这篇文章还原我们怎么一步步搭建一套流程仿真测试体系,用沙箱环境、流量录制回放和自动化测试流水线,让每一次流程变更在触碰真实店铺之前,都经过充分验证。


picture.image

一、为什么生产环境是唯一能测出问题的地方

RPA流程测试和后端服务测试有一个本质区别:后端服务的依赖大多是可控的API,而RPA流程的依赖是活的、会变的网页

页面加载速度、元素渲染时序、弹窗出现与否、AB测试导致的不同页面版本——这些变量在开发环境里很难完整复现。开发环境通常只操作一两个测试店铺,数据量小、页面简单;但生产环境里,一个商品列表可能翻几十页,中间随时可能触发平台的风控验证页面。

picture.image

测试环境和生产环境的差异,是自动化事故的第一大温床。

picture.image

二、沙箱环境:把真实店铺复制一份出来测

最早我们试图直接申请一批测试店铺来做验证,但平台对测试账号的管理很严格,很多操作(如报名活动、确认发货)在测试店铺里根本无法执行。而且测试店铺和真实店铺的环境差异仍然存在——不同的店铺等级、不同的权限、不同的页面功能开关。

后来我们换了一种思路:沙箱环境直接使用生产店铺的页面和数据,但在操作层做隔离阻断。

做法是,在浏览器实例池里划出一部分实例,专门用于沙箱测试。这些实例连接的是真实的店铺后台,但通过CDP拦截,把所有的写操作(点击“提交”、“确认”、“保存”等按钮)替换为记录操作路径并截图,不实际执行。对于只读操作,如采集数据、查询订单,则正常执行以验证结果正确性。

def setup_sandbox_interception(instance, sandbox_mode=True):

![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/d151b4fe57d549cc97efec8e00c511cc~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1780590822&x-signature=dWmnkfFUdjh2RFzH08c%2BcZ0aqNw%3D)
    if not sandbox_mode:
        return
    # 通过CDP注入拦截逻辑
    cdp_command = """
    (() => {
        const BLOCKED_ACTIONS = ['submit', 'confirm', 'save', 'publish', 'delete'];
        document.addEventListener('click', (e) => {
        
![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/a128a2d3a4034ac89adcd38e246379f2~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1780590822&x-signature=xiVuLEEEYg%2BaKF4A3No%2F55y4EsQ%3D)
            const target = e.target;
            const action = (target.getAttribute('data-action') || target.textContent || '').toLowerCase();
            if (BLOCKED_ACTIONS.some(a => action.includes(a))) {
                e.preventDefault();
                e.stopPropagation();
                // 上报被拦截的操作
                console.log('[SANDBOX_BLOCKED]', action, target.outerHTML);
            }
        }, true);
    })();
    """
    send_cdp(instance.debug_port, "Runtime.evaluate", {"expression": cdp_command})

picture.image 这个沙箱模式让测试人员在真实店铺页面上验证流程,但不会对店铺产生任何实际影响。唯一要注意的是,沙箱实例不能影响生产实例的同一店铺环境。我们通过分配不同的user-data-dir副本(临时复制的,用完即删)来确保沙箱和生产的浏览器环境完全隔离。


三、页面快照与元素定位的回归测试

RPA流程里最容易出问题的地方,就是元素定位。平台一个前端改版,原本的XPath或CSS选择器就可能失效,流程跑到那一步直接卡死。

我们设计了一套元素定位回归测试,思路来源于前端的视觉回归测试,但适配到了RPA场景。

每次流程发布前,CI流水线会自动在沙箱环境里跑一遍流程,并在每个交互步骤前对页面做DOM快照和截图。快照里记录了当前页面所有可交互元素的选择器、文本内容、位置坐标。然后和上一次成功运行的基线快照做对比:

  • 如果某个元素的选择器结构发生了显著变化(比如父级层级变动),判定为高风险变更,需要人工确认。
  • 如果元素文本或位置微调但选择器仍能定位,判定为低风险变更,自动放行。
  • 如果元素直接消失,判定为阻断性变更,流程测试失败,禁止发布。
def capture_page_snapshot(debug_port):
    # 获取DOM树
    dom_tree = send_cdp(debug_port, "DOM.getDocument", {"depth": -1})
    # 提取关键元素
    elements = extract_interactive_elements(dom_tree)
    snapshot = {
        "url": get_current_url(debug_port),
        "elements": elements,
        "screenshot_hash": hash_screenshot(debug_port)
    }
    return snapshot

def compare_snapshots(baseline, current):
    diffs = []
    for elem in baseline["elements"]:
        current_elem = find_matching_element(elem, current["elements"])
        if not current_elem:
            diffs.append({"type": "missing", "selector": elem["selector"]})
        elif elem["selector"] != current_elem["selector"]:
            diffs.append({"type": "selector_changed", "old": elem["selector"], "new": current_elem["selector"]})
    return diffs

这套回归测试帮我们提前拦截了至少三次平台页面改版导致的流程中断。有一次TEMU把订单列表的class命名从.order-list-item改成了.order-card,CI直接报了阻断性变更,阻止了当天的流程发布。如果那次直接上线,晚上几十个店铺的订单采集全得挂掉。


四、流程回放引擎:用一次真实操作生成百种测试场景

人工写测试用例太慢,且无法覆盖线上真实的数据边界。我们的想法是:把一次真实运行的操作序列录制下来,然后在沙箱里以不同参数和条件回放,生成多样化的测试场景。

录制是通过CDP的NetworkRuntime域实现的。流程运行时,我们记录每一步:

  • 页面URL和标题
  • 触发操作的元素选择器
  • 操作类型(点击、输入、滚动)
  • 输入的数据内容
  • 操作前后的DOM差异

录制的操作序列被序列化为一个标准的测试脚本:

{
  "steps": [
    {"action": "navigate", "url": "https://seller.temu.com/orders"},
    {"action": "click", "selector": ".filter-date-range", "timeout": 5000},
    {"action": "input", "selector": "#start-date", "value": "{{start_date}}"},
    {"action": "click", "selector": ".search-btn"},
    {"action": "wait", "condition": ".order-list loaded"}
  ]
}

回放时,{{start_date}}这类模板变量可以被替换为不同的值,模拟不同时间段、不同数据量下的执行情况。我们用一个回放Worker批量执行这些脚本,并收集执行日志、截图和性能指标。

这套回放引擎让我们可以在每次流程变更后,自动生成几十种不同的测试场景,覆盖了人工测试根本顾不上来的边界条件。


五、异常注入:主动制造故障来验证韧性

监控和自愈那篇文章里我们提过混沌工程演练,但那是针对运行时系统的。对于流程本身,我们同样需要主动注入异常,验证它的容错能力。

测试流水线里集成了一个异常注入器,可以在回放过程中随机触发以下事件:

  • 网络延迟突增(通过代理层模拟)
  • 页面元素加载超时
  • 弹窗突然出现(注入一个模拟弹窗的DOM节点)
  • 登录态失效(模拟平台返回401状态码)
  • 页面结构局部变化(随机修改某个元素的class名)

然后观察流程的行为:是否在规定时间内超时退出?是否触发了重试机制?是否保存了断点?是否输出了可读的错误信息?

这些测试用例不是一次性的,而是每次流程发布前的必过门槛。我们设定了一个“容错得分”:每个流程在异常注入测试中的表现被打分,低于80分禁止发布,80~90分警告但可发布,90分以上正常发布。


六、多平台差异化测试的自动化

不同平台的页面结构和交互模式差异很大,测试用例如果按平台手写,工作量是平台数量的倍数。

我们抽象了一个平台适配层,将通用的测试步骤映射到不同平台的页面操作上。例如,测试步骤“打开订单列表页”,在配置里定义三个平台的导航路径:

platform_routes:
  pdd:
    order_list: "/seller/order/list"
  temu:
    order_list: "/merchant/orders"
  tiktok_shop:
    order_list: "/seller/orders/all"

测试脚本用抽象的步骤名来编写,回放引擎根据目标平台加载对应的路由配置。这样,一个测试脚本可以跨三个平台复用,只是底层执行的页面操作不同。

这个抽象层也在不断地被平台变更所更新,但只要更新一次配置,所有的测试脚本都跟着受益。


七、测试环境与生产环境的配置同步

测试环境最大的敌人是配置漂移——生产改了一个参数,测试环境没同步,导致测试结果与生产实际脱节。

我们的配置中心(上一篇文章详述)本身维护了一套配置同步机制。测试环境使用的配置,是生产配置的定时镜像,每小时同步一次,并且保留一份快照用于回溯。

同时,测试环境在使用配置时,会自动将某些高风险参数替换为测试专用值。比如,生产配置里的买家消息接收手机号,测试环境自动替换为内部测试号码,确保不会在测试时骚扰到真实买家。


八、测试的自动化编排与CI集成

所有测试能力最终集成到CI流水线里。当一个流程的新版本提交到Git仓库时,GitLab CI自动触发:

  1. 制品构建和元数据校验
  2. 沙箱环境部署(从浏览器池中申请临时实例)
  3. 页面快照对比测试
  4. 回放引擎用基线测试脚本跑一次完整流程
  5. 异常注入测试跑3轮
  6. 生成测试报告,包含每个步骤的截图、耗时、差异对比

整个测试流水线跑完大约需要15~20分钟。通过后,流程才能进入灰度发布阶段。如果任何一项测试不通过,发布会自动阻塞,并在报告里标记出失败步骤和推荐修复方向。

这个自动化的测试门禁,让我们的流程发布信心大幅提升。以前发布新流程靠勇气,现在靠的是数据。


九、曾经因为测试缺失而踩过的坑

说一个真实案例。

有一次我们更新了TikTok Shop的消息回复流程,只是增加了一个“回复前先检查用户最近一条消息时间”的逻辑。开发环境跑了两次,看起来没问题,直接灰度了10个店铺。

结果半个小时后,P0告警炸了。这10个店铺的消息回复成功率从98%跌到了12%。紧急回滚后排查,发现新逻辑在计算“最近一条消息时间”时,误把系统通知消息也算了进去,导致大量用户消息被判定为“非最新”而跳过,没有回复。

这个Bug在开发环境没暴露,是因为测试用的消息列表里只有用户消息,没有系统通知。而生产店铺的消息列表里混了大量平台推送的系统通知。

如果当时有沙箱回放引擎,用生产店铺的消息列表回放一次,这个Bug会立刻暴露。那次之后,我们下决心把测试体系建设成了现在的样子。


十、测试体系的边界与未来方向

当前的沙箱测试体系主要覆盖流程的功能正确性和元素定位稳定性,对于性能退化(如新版本流程比旧版本慢30%)和跨流程的数据一致性问题,覆盖还不够。

下一步我们想做的,是把流程执行过程中的性能指标(步骤耗时、页面加载时间、内存占用)纳入基线对比,让性能退化也能被自动化检测出来。另外,对于跨流程的数据依赖场景(采集流程产出数据被上货流程消费),我们计划在沙箱里模拟完整的数据管道,做端到端的集成测试。

自动化流程的测试,不应该比流程本身更脆弱。
它需要和流程一起成长,一起面对线上环境的复杂与混乱。

作者:林焱
一个坚信测试是自动化工程最后一道尊严的工程师

0
0
0
0
评论
未登录
暂无评论