简介:面向移动端性能测试初学者与测试工程师的实战型文档,围绕手机APP性能测试脚本开发展开,重点介绍借助LoadRunner 11.0录制与生成脚本的完整思路。文档从录制前的前置条件讲起,涵盖手机与电脑共享网络、LoadRunner补丁安装、协议选择与录制模式设置,并说明脚本录制、生成及后续在性能测试、负载测试和压力测试中的典型用法,帮助读者建立从环境准备到脚本落地的整体认知。资源包内共1个doc文件,约359KB,篇幅精炼,适合作为入门参考或培训辅助材料。目前已有483人学习,说明其在移动端性能测试入门场景中具有一定参考价值。读者可从中获取录制流程的关键节点、常见准备事项与应用场景划分,便于在实际项目中快速对照排查,减少摸索成本。
1. 手机 APP 性能测试脚本开发:先把录制链路跑通再谈并发
把一个真机 APP 交给测试同学,最常听到的问题是:接口都会调,为什么手机端一开录就只剩空白脚本?手机 APP 性能测试脚本开发的关键不在脚本语法,而在录制链路是否干净:电脑热点、手机网段、LoadRunner 11.0 补丁、协议选择、Action 划分,任何一环偏了,后面参数化和并发都白搭。这份资料围绕 LoadRunner 11.0 和 Mobile App(HTTP/HTML) 协议,把真机操作转成可回放的 APP 性能测试脚本,覆盖录制前检查、补丁安装、热点共享、脚本生成和回放排查。适合刚接手 app性能测试、需要照着步骤复现的新手,也适合已经会写接口脚本、想把手机端录制流程工程化的熟手。
2. 环境准备:LoadRunner 11.0、补丁与热点缺一不可
手机端录制不像纯接口脚本,工具装好只是起点。补丁、热点、网段、防火墙、手机网络开关,任何一项没对齐,录制器看到的就是空 Action。输入资料里明确写了四个前提:装好 LoadRunner 11.0、准备待录制 APP、电脑开启 WiFi 热点且手机能连上、安装 LR_03105_Patch4 补丁。这四项不是清单摆设,实际排查时它们正好对应四类翻车:补丁没生效导致录制入口异常,热点没开导致手机流量没进电脑,网段不通导致录制器收不到请求,APP 没准备好导致录到一半切后台。先环境后脚本,顺序不能反。
2.1 补丁 LR_03105_Patch4 到底解决什么
LoadRunner 11.0 不是新工具,移动端录制依赖补丁把手机端请求解析和录制入口补齐。输入资料要求安装 LR_03105_Patch4,我一般把它当作录制准入条件:没装补丁就先别开录,否则后面排查会把补丁问题和网段问题混在一起,越查越乱。安装时关掉 LoadRunner 主程序、关掉录制器、关掉可能驻留的托盘进程,再用管理员权限运行补丁,装完重启机器。重启不是仪式,旧进程不退出时录制器可能还挂着旧监听,表面装完实际没生效。
注意:补丁装完先重启,再新建脚本;不要在原脚本上反复点录制来验证补丁。
补丁是否生效,不要只看安装向导的完成页。我通常做三步检查:新建脚本时能正常进入 Mobile App(HTTP/HTML) 的录制配置页;Start Record 后状态能切到 Stop Recording;手机操作后 Action 里能看到至少一条业务请求。三条里缺一条,就先回到补丁和录制器进程,不要急着改脚本。下面这条检查命令用于看录制器监听端口有没有被别的进程占住,PORT换成录制器提示的监听端口。
netstat -ano | findstr :PORT逻辑说明:netstat -ano列出本机网络连接和监听端口,findstr过滤目标端口;如果输出里已有非 LoadRunner 进程占用,录制器就可能起不来。参数说明:PORT是录制器实际使用的监听端口,不要照抄一个固定值;-a看全部连接,-n用数字显示地址和端口,-o带出进程号,方便到任务管理器里对照。看到LISTENING且进程号是录制器进程,才算监听正常;看到其他进程,先结束占用再开录。
2.2 电脑热点与手机网段:共享网络不是连上就行
输入资料里用的是某品牌 USB 随身 WiFi 开热点,台式机没有无线网卡时这种方案很常见;笔记本自带无线网卡也可以直接开热点。关键不是品牌,而是手机连上热点后,手机和电脑必须处在同一个可互通的网段。很多翻车现场是:手机显示已连接,但移动数据还开着,APP 请求走了蜂窝网络,录制器自然一片空白。我一般要求录制期间关闭手机移动数据,忘记其他已保存 WiFi,只保留当前热点。
先在电脑上看热点网卡的 IPv4 地址。下面命令在 Windows 命令提示符里执行,重点看热点网卡对应的 IPv4 地址、子网掩码和默认网关。
ipconfig /all逻辑说明:ipconfig /all比ipconfig多出网卡描述、物理地址、DHCP 状态和 DNS 信息,便于确认哪一块网卡是热点网卡。参数说明:/all不是可选装饰,台式机常有多块网卡,只看默认输出容易把有线网卡当成热点网卡;记下热点网卡的 IPv4 地址,比如192.168.x.x这一类私有地址,再看手机 WiFi 详情里的 IP 是否在同一网段。手机 IP 和电脑热点 IP 前三段一致,才有互通基础;不一致时先断开重连,不要直接改手机静态 IP。
接着在手机浏览器里访问电脑热点地址对应的录制器页面,或者在电脑上ping手机 IP,确认链路可达。下面命令里的PHONE_IP换成手机 WiFi 详情里的 IP。
ping PHONE_IP逻辑说明:ping走 ICMP,能快速判断手机和电脑之间有没有基础连通性;不通不代表录制一定失败,但通了一定比不通好排查。参数说明:PHONE_IP是手机在当前热点下的地址,不要填成旧网段地址;如果请求超时,先看电脑防火墙有没有拦截,再看手机是否开了“休眠时断开网络”一类省电策略。热点频段也有讲究:2.4G 兼容性更好,老手机更容易连;5G 干扰少,但部分老设备搜不到。录制阶段优先选手机能连上的频段,不要为了速度牺牲连通性。
| 检查对象 | 看什么 | 常见异常 |
|---|---|---|
| 电脑热点网卡 | IPv4 地址、子网掩码 | 热点没开、网卡被禁用 |
| 手机 WiFi | IP 是否同网段、移动数据是否关闭 | 手机走了蜂窝网络 |
| 防火墙 | 录制器进程是否放行 | 手机访问不到电脑 |
| 手机省电策略 | 锁屏后是否断网 | 录制中途断流 |
2.3 录制前的四件检查清单
第一件,确认补丁编号和 LoadRunner 版本对得上,LR_03105_Patch4装完重启过,录制入口能正常打开。第二件,电脑热点开启,手机连上后关移动数据,手机 WiFi 详情里的 IP 与电脑热点 IP 同网段。第三件,录制器监听地址可达,端口没有被其他进程占用,防火墙对录制器进程放行。第四件,待测 APP 已登录到可操作状态,录制期间不会弹系统更新、权限弹窗或强制升级框。四件里任何一件没做,后面录出来的脚本都可能是半截的。
我一般还会加一个动作:先把手机自动锁屏时间调到最长,录制期间保持 APP 在前台。手机锁屏后系统可能断开热点连接,录制器看到的就是一次断流,脚本里会缺掉中间请求。这个坑不解决,回放时业务链断在登录后第一步,看起来像脚本关联失败,实际是录制时手机睡了。
提示:录制前重启一次手机 WiFi,比录制中途反复重连更省时间。
3. 录制手机 APP 脚本:Mobile App(HTTP/HTML) 协议怎么选、Action 怎么切
协议选错,后面所有增强都白做。输入资料要求新建脚本时选择 Mobile App(HTTP/HTML) 协议,这个协议面向手机 APP 的 HTTP/HTML 流量,适合大多数走接口请求的 APP 业务。要是 APP 用了私有长连接、自定义二进制协议,或者关键流量不走 HTTP/HTML,这个协议就录不到核心请求,得换工具或让开发提供可测试的 HTTP 入口。选型理由先立住:录制协议要和待测业务的流量形态匹配,不是看哪个名字顺眼。
3.1 新建脚本时协议选错,后面全白录
新建脚本时,协议列表里选 Mobile App(HTTP/HTML),不要选成 Web(HTTP/HTML) 就当手机端用。两者录制入口和移动端请求解析不一样,选错后可能能录到部分请求,但手机端特有的请求头、设备信息、接口路径容易被处理得不完整。选完协议进入录制配置页,先别急着点 Start Recording,确认录制器监听地址、端口、录制目标都正确。
| 协议选择 | 适用场景 | 不适用信号 |
|---|---|---|
| Mobile App(HTTP/HTML) | APP 内 HTTP/HTTPS 接口请求 | 核心业务走私有长连接 |
| Web(HTTP/HTML) | 浏览器页面资源 | 手机端接口请求录不全 |
| 其他协议 | 特定传输形态 | 与待测 APP 流量不匹配 |
如果录制后 Action 里只有登录页静态资源,没有业务接口,先回头确认协议和录制模式,不要直接怀疑手机。协议选对是前提,录制模式决定请求怎么分组,Action 划分决定后面事务和并发怎么统计。
3.2 Start Record 之后:录制模式与 Record into 的取舍
进入录制配置页,点击 Start Record 后选择录制模式。常见两种思路:HTML-based 更贴近页面资源分组,URL-based 更贴近单条请求。手机 APP 多为接口调用,我一般选 URL-based,原因是接口请求按条记录,参数化和关联时更容易定位;HTML-based 会把页面资源和上下文归并,动态接口藏在分组里,回放失败时不好判断是哪条请求出了问题。输入资料没有写死模式,实际以录制器提供的选项为准,但选择逻辑可以固定:接口型 APP 优先按请求粒度录。
Record into 部分有 Vuser_init、Action、Vuser_end 三选一。输入资料说一般选 Action,根据具体情况定。我的做法是:录制阶段统一进 Action,录完再按业务切分。登录、首页、查询、退出都先落在 Action 里,后面把全局设置挪到 Vuser_init,把注销挪到 Vuser_end。这样录制时不打断操作流,脚本结构后面再整理。
| 脚本段 | 放什么 | 不要放什么 |
|---|---|---|
| Vuser_init | 全局超时、通用请求头、环境变量 | 每用户登录事务 |
| Action | 登录、查询、下单等业务事务 | 只执行一次的全局配置 |
| Vuser_end | 注销、清理会话 | 核心并发业务 |
登录放 Action 还是 Vuser_init,取决于统计口径。登录要计入事务响应时间,就放 Action 开头;登录只做一次前置,不关心耗时,可以放 Vuser_init。但登录参数必须参数化,否则并发时同一账号互踢,脚本全红。这个取舍在压测场景设计时就要定,不要录完再拍脑袋。
3.3 手机端操作顺序与生成脚本检查
点击 Start Recording 后,状态变为 Stop Recording,此时在手机上操作待测功能。操作顺序建议固定:冷启动 APP、登录、进入首页、执行核心查询或提交、退出。每一步之间停 1 到 2 秒,让录制器完整收包;不要快速连点,也不要在录制中切后台、锁屏、下拉通知栏。手机必须连在电脑热点上,这是输入资料反复强调的点;一旦手机切回移动数据,录制器就收不到后续请求。
录制完成后点击结束,LoadRunner 自动生成脚本。先看 Action 里的请求条数、请求 URL、请求体、响应码,再看有没有无关静态资源。生成的脚本骨架大致如下,具体函数名以录制结果为准。
vuser_init() { /* 全局超时,避免手机端慢请求直接判失败 */ web_set_timeout(ACTION, "120"); return 0; } Action() { /* 录制生成的业务请求会落在这里,先保留原始顺序 */ lr_start_transaction("app_login"); web_url("login", "URL=http://{host}/api/login", "Resource=0", "RecContentType=application/json", LAST); lr_end_transaction("app_login", LR_AUTO); lr_start_transaction("app_query"); web_url("query", "URL=http://{host}/api/query", "Resource=0", "RecContentType=application/json", LAST); lr_end_transaction("app_query", LR_AUTO); return 0; } vuser_end() { return 0; }逻辑说明:vuser_init只放全局设置,Action保留录制出来的业务请求顺序,vuser_end先留空,后续按需要放注销。事务包住登录和查询,方便在结果里拆分响应时间。参数说明:web_set_timeout(ACTION, "120")把 Action 超时放宽到 120 秒,手机端弱网时比默认值更稳;{host}是参数化占位,不要写死录制时的电脑 IP;Resource=0表示按业务请求处理,不按静态资源过滤;RecContentType=application/json帮助回放时按 JSON 内容处理;LAST表示参数列表结束。生成脚本后不要马上并发,先单用户回放,确认请求条数和业务响应都对,再进入参数化和关联。
提示:录制时手机不要锁屏,也不要切到后台;断流后的脚本补不回来。
4. 脚本落地:参数化、关联、检查点与事务怎么补
录制只解决“请求长什么样”,回放能不能跑、并发有没有意义,靠后面的脚本增强。手机 APP 性能测试脚本最常见的三处翻车是:账号写死导致互踢、token 没关联导致 401、只看 HTTP 200 不看业务码导致假成功。参数化、关联、检查点、事务这四件事,最好在单用户回放通过后一次补齐,不要等到压测现场再补。
4.1 参数化:账号、设备号、时间戳别写死
参数化不是把账号改成变量就完事。手机端常见参数分三类:账号密码类、设备标识类、动态时间戳类。账号密码要按并发用户数准备独立数据;设备标识如果服务端做了绑定,同一设备号并发会被风控;时间戳和随机数如果参与签名,不能简单参数化成固定值,要看服务端校验逻辑。参数文件建议用表格管理,字段名和脚本里的{参数名}一一对应。
| 参数名 | 来源 | 示例 | 更新方式 |
|---|---|---|---|
| account | 测试账号池 | test_user_001 | 按迭代顺序取 |
| password | 测试账号池 | test_pass_001 | 与账号绑定 |
| device_id | 设备池 | test_device_001 | 按用户分配 |
| host | 环境地址 | test_host | 按环境切换 |
参数文件可以用制表符或逗号分隔,第一行写字段名。下面是一个示例结构,实际字段按录制脚本里的请求体调整。
account password device_id host test_user_001 test_pass_001 test_device_001 test_host test_user_002 test_pass_002 test_device_002 test_host逻辑说明:第一行是字段名,后续每行是一组测试数据;脚本里用{account}、{password}、{device_id}、{host}引用。参数说明:account和password必须成对,不要交叉取;device_id按并发用户分配,避免同一设备号被服务端绑定;host放环境地址占位,不要写死录制时的电脑 IP。参数化配置里把“Select next row”设为顺序或唯一,“Update value on”设为每次迭代,具体看业务是否允许同一账号重复登录。这里翻车最多的是账号复用:并发一上来,前一个虚拟用户把后一个踢下线,脚本报登录失败,其实是数据没隔离。
4.2 关联:token 与动态签名怎么抓
手机 APP 登录后通常返回 token,后续请求带在请求头或请求体里。录制时 token 是固定值,回放时早过期,表现就是 401 或业务码“未登录”。关联的做法是在登录响应里抓 token,存成参数,后续请求引用。下面代码在登录请求前注册关联,登录响应返回后 token 就可被后续请求使用。
Action() { /* 在登录请求前注册,抓响应体里的 token */ web_reg_save_param("token", "LB=\"token\":\"", "RB=\"", "Search=Body", LAST); lr_start_transaction("app_login"); web_custom_request("login", "URL=http://{host}/api/login", "Method=POST", "Resource=0", "RecContentType=application/json", "Body={\"account\":\"{account}\",\"password\":\"{password}\",\"device_id\":\"{device_id}\"}", LAST); lr_end_transaction("app_login", LR_AUTO); lr_start_transaction("app_query"); web_custom_request("query", "URL=http://{host}/api/query", "Method=GET", "Resource=0", "RecContentType=application/json", "Header=Authorization: Bearer {token}", LAST); lr_end_transaction("app_query", LR_AUTO); return 0; }逻辑说明:web_reg_save_param必须放在登录请求之前,它注册的是“响应回来后抓什么”,不是立即抓;登录响应里"token":"..."被存进token参数,查询请求的Authorization头引用它。参数说明:LB是左边界,RB是右边界,必须按实际响应体调整;Search=Body表示在响应体里找,不要在 Header 里找;LAST结束参数列表。动态签名比 token 麻烦:先对比多次录制,找出变化字段,能直接从响应里取的用关联,不能直接取的让开发提供测试环境开关或固定签名方案。不要在脚本里硬编签名算法,APP 端逻辑一变,脚本全废。
4.3 检查点与事务:别让 200 骗过回放
HTTP 200 只代表请求到了服务端,不代表业务成功。手机 APP 常见返回体是{"code":0,"msg":"ok"},失败时可能还是 200,但code是 1001。没有检查点,回放全绿,压测结果却全是假成功。检查点用web_reg_find在请求前注册,匹配业务成功标识;事务结束用LR_PASS或LR_FAIL手动判定,别一律LR_AUTO。
Action() { /* 注册业务检查点,匹配成功响应里的 code:0 */ web_reg_find("Search=Body", "Text=\"code\":0", LAST); lr_start_transaction("app_login"); web_custom_request("login", "URL=http://{host}/api/login", "Method=POST", "Resource=0", "RecContentType=application/json", "Body={\"account\":\"{account}\",\"password\":\"{password}\"}", LAST); if (atoi(lr_eval_string("{token}")) == 0) { lr_end_transaction("app_login", LR_FAIL); return 1; } lr_end_transaction("app_login", LR_PASS); return 0; }逻辑说明:web_reg_find在登录请求前注册,响应体里找不到"code":0时该请求会被标记失败;事务结束根据 token 是否为空做一次兜底判定。参数说明:Search=Body限定响应体;Text是要匹配的文本,按实际成功标识改;LAST结束参数列表。上面代码里atoi只适合 token 为数字的场景,token 是字符串时改用长度判断,例如strlen(lr_eval_string("{token}")) == 0。事务名用英文,结果分析时好筛选;检查点文本不要写太长,取成功响应里独有的短标识,避免误匹配。
| 增强项 | 常用函数 | 检查点 |
|---|---|---|
| 参数化 | 参数文件 +{参数名} | 并发账号不互踢 |
| 关联 | web_reg_save_param | 后续请求不带过期 token |
| 检查点 | web_reg_find | 业务码不是只看 HTTP 200 |
| 事务 | lr_start_transaction/lr_end_transaction | 成功失败可区分 |
5. 避坑排查:录制不到请求、脚本回放失败、手机掉线怎么定位
手机端录制有时像黑匣子,翻车最多的不是脚本函数,而是网段、锁屏、补丁和参数。排查顺序我一般固定:先看手机和电脑是否同网段,再看录制器有没有收到请求,再看脚本回放是不是单用户通过,最后才看并发配置。顺序反了,容易在 Controller 里调半天,回头发现手机根本没连热点。下面五条是实际复现时最常遇到的坑,按“现象、原因、解决”拆开。
5.1 录制链路排查:0 请求、断流、重复请求
现象一:Start Recording 后手机操作正常,Action 里一条业务请求都没有。原因通常有三类:手机还连着移动数据或另一个 WiFi,请求没走电脑热点;电脑防火墙拦截了录制器监听;补丁没生效或录制器进程还是旧的。解决时先关手机移动数据,忘记其他 WiFi,只保留当前热点;再用ipconfig确认手机和电脑同网段;然后检查防火墙对录制器进程的放行规则;最后重启录制器,确认补丁装完后的进程是新起的。不要一上来就重装 LoadRunner,先把手机网络开关和防火墙排掉,能省很多时间。
现象二:录到一半请求断了,后面业务全缺。原因多是手机锁屏、切后台、热点断连或 APP 被系统省电策略限制。解决时把手机自动锁屏调到最长,录制期间保持 APP 前台,关闭针对待测 APP 的省电限制;电脑侧确认热点没有自动关闭。断流后的脚本不要硬补,重新录一遍比在缺失请求上猜关联更可靠。这个坑我踩过,补半天脚本,最后发现是手机息屏。
现象三:Action 里请求重复出现,静态资源混进业务事务。原因通常是录制模式选了 HTML-based,页面资源和接口请求被分组记录,或者手机端一次操作触发了多次轮询。解决时先看重复请求的 URL 和参数,业务请求保留,静态资源和轮询请求按需过滤;录制模式改成 URL-based 再录一遍对比。过滤不是删得越多越好,核心业务请求删了,压测场景就失真。
5.2 回放失败排查:401、业务码、动态参数
现象四:单用户回放登录成功,查询接口全 401。原因基本是 token 没关联,或者关联边界写错,抓到了空值;也可能是 token 放在响应头而不是响应体,Search=Body找不到。解决时先用日志打印响应体,确认 token 的实际位置和前后字符;把web_reg_save_param放到登录请求之前;用lr_output_message打印抓到的 token 长度,长度为 0 就改LB、RB或Search。如果 token 在响应头,改成Search=Headers并调整边界。
现象五:回放 HTTP 200,但业务提示“参数错误”或“签名失败”。原因是没有业务检查点,或者动态时间戳、随机数、签名没处理。解决时先加web_reg_find匹配成功业务码,让失败暴露出来;再对比录制和回放的请求体,找出变化字段;能关联的关联,不能关联的找开发要测试开关。不要用固定时间戳硬扛,服务端校验一严就全红。单用户回放必须全绿再上并发,这是后悔药。
5.3 压测执行排查:超时、端口、数据污染
现象六:单用户回放通过,Controller 加到几十个用户后大量超时。原因可能是脚本里写死了录制时的电脑 IP,压测机网络到不了;也可能是 Runtime Settings 的连接超时太短,或者压测机端口耗尽。解决时把host参数化,按压测环境切换;检查 HTTP keep-alive 设置和超时时间;分散压测机
本文还有配套的精品资源,点击获取