李毛毛的技术专栏 An interesting software testing engineer

app弱网测试

2021-01-26

app

弱网测试

前言

测试中我们经常需要模拟弱网环境,观察app在弱网条件下的表现,比如丢包、延迟、抖动、限制宽带等等。目前模拟手段主要为以下几种: 1.通过应用层或者传输层的代理服务器,通过在代理服务器上设置一些模拟恶劣网络环境的参数,使得通过这些代理服务器的流量都被转化为恶劣网络环境下的流量。如利用Fiddler,Charles等具有代理服务器功能的网络流量分析软件来实现。(方案一、) 2.通过利用一些更底层的驱动层面的服务,通过控制网卡的收包发包的行为,来模拟恶劣的网络环境。如dummynet的ipfw驱动等。(方案二) 3.通过建立一个可控的网关,在网关上部署模拟恶劣环境的相关程序,所有需要借助该网关进行转发的流量都会被模拟为恶劣网络条件。Linux下的netem就提供了这类支持。

方案一

Fiddler + speedtest

1.Fiddler

  • Fiddler本身已经预置提供了模拟Modem速度的选项,其位置位于: Rules – Performances – Simulate Modem Speeds

勾选该选项后,所有通过Fiddler代理的流量都会变得和多年前的56k小猫时上网一般的慢。

  • 直接模拟Modem速度实在是慢爆了,事实上就算是在很差信号的情况下,手机移动网络的速度都已经超过了当年的56k Modem速度了,所以采用默认的配置模拟出来的环境过于恶劣,并不一定符合需求,此时就需要对限速的参数进行调整。

Fiddler本身就提供了一个配置文件供调整这些参数,点击:Rules – Customize Rules… 就会用文本编辑器打开CustomRules.js文件,其默认位于用户目录的文档目录下的\Fiddler2\Scripts 位置,后缀名是js,其内容实质是JScript.NET——微软对ECMAScript规范的实现,与日常使用的javascript是属于同一个规范下的,但是在扩展的细节实现存在一定的不同。

打开该文件后,可以找到一个m_SimulateModem标志位:

if (m_SimulateModem) {
    // Delay sends by 300ms per KB uploaded.
    oSession["request-trickle-delay"] = "300";
    // Delay receives by 150ms per KB downloaded.
    oSession["response-trickle-delay"] = "150"
}

该标志位控制着oSession的两个参数值的设置,当勾选了Simulate Modem Speeds时,request-trickle-delay与response-trickle-delay就会被设置,其中request-trickle-delay中的值代表每KB的数据被上传时会被延时多少毫秒,response-trickle-delay则对应下载时每KB的数据会被延时多少毫秒

  • 自定义脚本

进一步地,我们可以扩展CustomRules.js里的逻辑,参照Jscript的文档可以在模拟恶劣环境中加入更多自定义的逻辑,这里实现了一个随机延时量设置,使得网络带宽不是恒定为一个低速的值,而是会在一定范围内随机抖动:

static function randInt(min, max) {
    return Math.round(Math.random()*(max-min)+min);
}
if (m_SimulateModem) {
    // Delay sends by 300ms per KB uploaded.
    oSession["request-trickle-delay"] = ""+randInt(1,50);
    // Delay receives by 150ms per KB downloaded.
    oSession["response-trickle-delay"] = ""+randInt(1,50);
}
  • 小结

Fiddler进行限速较为简单和灵活,配置也较为方便,但是由于它是一个应用层的HTTP的代理,只能模拟该层上的行为,对于一些复杂的网络层的丢包、重传等恶劣情况就不能很好的模拟出来

2.speedtest

speedtest用于测试网速,更加直观记录测试时网络环境

方案二

Network Link Conditioner + Charles + speedtest

下载地址:https://developer.apple.com/download/more/?=for%20Xcode

1.Charles 主要用来做代理,下一个方案详细介绍弱网设置

2.speedtest speedtest用于测试网速,更加直观记录测试时网络环境

3.Network Link Conditioner Mac下非常好用的弱网模拟工具,支持可视化配置和命令行及脚本配置,下面分别介绍

  • 可视化配置

默认有一些分类配置可以直接使用,也可以自定义配置上行/下行宽带、丢包率、延迟时间,及DNS延迟时间

  • 命令行

Mac OS X 10.10 以后,系统主要使用的是 PF (Packet Filter, the BSD firewall)dummynet(the BSD traffic shaper) 这两个服务来模拟各种弱网环境。简单来说,dummynet 是一个流量/带宽/延时的控制工具,用户可以使用 dnctl 命令来配置和与之交互。再简单来说,dnctl 是一个命令行工具,用于配制dummynet服务。

dnctl 提供了 2 种流量控制机制,一个是 pipe,一个是 queue,前者主要用于固定带宽条件下的弱网模拟,后者则可以试验不同 pipe 使如何抢占和共享可用带宽的。通常我们选择前者来简单地模拟弱网。

定义一个 pipe number id 为 1,带宽限制 100Kbit/s,delay 100ms,loss:50% 的弱网环境:

// 创建配置并显示
$ sudo dnctl pipe 1 config bw 100Kbit/s delay 100 plr 0.5
$ sudo dnctl show
​
00001: 100.000 Kbit/s 100 ms 50 sl.plr 0.500000 0 queues (1 buckets) droptail
    mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000
​
// 清空配置并显示
$ sudo dnctl -q flush
$ sudo dnctl show

我们再来看看另一个工具:pf,它是 Mac 系统的防火墙工具,我们利用它来把经过系统的流量转到我们的弱网环境进行 filter 处理。 pf 主要使用配置文件保存防火墙规则,语法规范上比较严谨,cat /etc/pf.conf,可看到以下已有内容:

# This file contains the main ruleset, which gets automatically loaded
# at startup.  PF will not be automatically enabled, however.  Instead,
# each component which utilizes PF is responsible for enabling and disabling
# PF via -E and -X as documented in pfctl(8).  That will ensure that PF
# is disabled only when the last enable reference is released.
#
# Care must be taken to ensure that the main ruleset does not get flushed,
# as the nested anchors rely on the anchor point defined here. In addition,
# to the anchors loaded by this file, some system services would dynamically
# insert anchors into the main ruleset. These anchors will be added only when
# the system service is used and would removed on termination of the service.
#
# See pf.conf(5) for syntax.
#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

下面,我们需要来撰写属于我们自己的的规则。

1.新建一个 pf.conf 文件

$ touch pf.conf

2.添加路由规则

$ vi pf.conf
​
# 本示例的 “上行 + 下行” 都配置了弱网,也可以配置单向测测变化
​
# 测试 tcp,比如:curl www.baidu.com
dummynet in proto tcp from any to any pipe 1 
dummynet out proto tcp from any to any pipe 1
​
# 测试 udp,比如:音视频通话
dummynet in proto udp from any to any pipe 1   
dummynet out proto udp from any to any pipe 1
​
# 测试 ping,比如:ping baidu.com
dummynet in proto icmp from any to any pipe 1
dummynet out proto icmp from any to any pipe 1

3.启动和加载 PF 配置

操作 PF 服务,需要借助 pfctl 命令。

# Mac 系统默认把 `PF` 服务关闭了,启动 `PF` 服务
$ sudo pfctl -e
​
# 加载自定义防火墙规则
$ sudo pfctl -f pf.conf
​
# 恢复原始的防火墙规则
$ sudo pfctl -f /etc/pf.conf 
​
# 注意:使用 pfctl 命令会经常出现下面的 warning,没有影响,忽略就好了。
"No ALTQ support in kernel"

方案三

Charles + speedtest

  1. 打开Charles,选择proxy->throttle settings

  1. 勾选【enable throttling】,设置带宽(下面各个字段有解释),再点击OK

  1. 勾选小乌龟,连接Charles的客户端就能限制网速了

  • 网络设置及参数详细解释

Bandwidth(带宽)【吞吐量

带宽定义数据可以传送超过时间上限,这是千比特每秒指定。可以指定上载和下载链接的不同带宽限制。

Utilisation(利用

利用率是总带宽的百分比,可以在任何一个时间使用。它只是作为可用带宽的缩放因子。对于大多数现代互联网连接利用率始终是100%。

Round-trip Latency(请求往返延迟)【延时

往返延迟测量客户端和远程服务器之间的第一次往返通信的毫秒延迟。它用于客户端向服务器和服务器向客户端的每次请求。

MTU(最大传输单元

在任何传输的TCP数据包的最大尺寸。指定MTU不改变的可用带宽,但允许Charles在MTU分配带宽大小的块,导致在每个传输包分割的现实水平

Reliability(可靠性)【丢包

可靠性是衡量连接完全失败的可能性。这是非常有用的模拟不可靠的网络条件。可靠性是指定为成功发射10kib消息的可能性,所以,值为50%意味着所有10kib传输一半会成功。较大的邮件或更小的消息或多或少都有可能失败,所以20kib传输将只有25%的成功率和5kib传输成功率约70%。

Stability(稳定性)【抖动】

稳定性是衡量一个连接的可能性是不稳定的,因此降低了质量。这是非常有用的模拟网络,如移动网络,定期连接质量差。如果连接不稳定,则连接的质量会在不稳定的质量范围内随机下降。此质量值,然后应用作为另一个缩放因子的可用带宽。

unstable quality range(不稳定质量范围)

此处设置主要针对于Stability中设置中的范围

方案四

Network Link Conditioner

iOS平台,通过自带的开发者选项Network Link Conditioner, 即可简单的模拟各种速度的网络情况:

方案五

通过Facebook开源的atc工具,进行模拟不同的网络情况(没用过,自行百度)

参考


Similar Posts

下一篇 接口测试思路

Comments