仅此一招,教你搞定Appium性能低,轻松玩转Appium

众所周知,appium和selenium使用的都是客户/服务架构,它的特色是在客户端写测试指令,在服务端执行。这种架构有两大优点:

1、跨语言,可以使用任何语言编写Appium代码;

2、可以构建大型私有或公有的Appium设备云。

这种架构也存在致命的缺点:降低性能。客户/服务架构用网络传输测试指令,这必然会受到网络延迟的影响,甚至天气不好也会波及。

网络太不可靠了,总会导致意想不到的卡顿、请求失败等等。这意味着你在本地跑代码时很完美,但传输到Appium云去运行时,可能完全不同,可能导致代码高度脆弱,甚至测试失败。

最重要的是,很多人不是直接使用Appium命令,而是一些框架。那些基于Appium的封装工具(对Appium命令进行了封装,存在过度使用的情况)。

比如,我看到有测试用5~10个请求去找一个元素,仅仅为了检索元素是否可用,我觉得这个方法不好。它会让脚本在云环境上的执行时间存在巨大差异。

除了网速慢,网络延迟也是一个杀手。比如你想执行命令A,之后立刻执行命令B,基本不可能使用网络来实现这个功能(B需要延迟才能到达Appium云服务器,不可能紧接着命令A马上执行)。

于是,W3C WebDriver规范团队想出了一个办法,创造新的Actions API(把整个action chain
编码成一个API去调用),一旦action开始,链可能需要几秒或几分钟才能实际执行

(原文:even though the chain might take seconds or minutes to actually execute
once the action begins.)。

** 使用Execute Driver Script**

Appium团队已经做了同样的事情,不仅仅actions,甚至是任何Appium命令。允许在一个Appium命令中打包其它Appium命令。所有这些命令都将在Appium服务器上执行,因此不会受到网络延迟的影响。它是如何运作的?显然这很神奇!比如,我们在Java客户端中编写下面这个测试脚本:

@Test

p


ublic void testLoginNormally() {    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);    driver.findElement(MobileBy.AccessibilityId("Login Screen")).click();    driver.findElement(MobileBy.AccessibilityId("username")).sendKeys("alice");    driver.findElement(MobileBy.AccessibilityId("password")).sendKeys("mypassword");    driver.findElement(MobileBy.AccessibilityId("loginBtn")).click();    driver.findElement(By.xpath("//*[@text='Logout']")).click();}  

这是一个简单的登录/注销功能。我们可以使用ExecuteDriverScript命令一次性批量运行所有这些命令:

@Test

public void testLoginWithExecute() {

    driver.executeDriverScript(

        "await driver.setImplicitTimeout(10000);\n" +

        "await (await driver.$('~Login Screen')).click();\n" +

        "await (await driver.$('~username')).setValue('alice');\n" +

        "await (await driver.$('~password')).setValue('mypassword');\n" +

        "await (await driver.$('~loginBtn')).click();\n" +

        "await (await driver.$('//*[@text=\"Logout\"]')).click();\n");

}

这到底是怎么回事?它把Appium客户端的代码包裹到了字符串里,Appium团队讨论了许多方法,他们一致认为灵活性至关重要。

因此Execute Driver Script命令的参数是一个字符串(字符串使用起来更灵活),表示要在当前运行的Appium
session中执行的JavaScript代码。该字符串最终由Appium服务器执行。

哇哦!这么做显然会引发远程代码执行漏洞(remote code execution
vulnerability,比如在ExecuteDriverScript中输入获取账号密码,然后让服务器来执行)!所以我们需要谈谈安全问题。

首先,服务器必须指令参数才能启用Execute Driver Script

(原文:the server must be started in a special mode that allows this feature
explicitly:)

appium --allow-insecure=execute_driver_script

其次,所有代码都在NodeJS VM中运行,这意味着它无法干扰Appium主程序。

实际上,我们可以严格控制执行代码可以访问什么方法。除了driver object之外,只提供访问权限。这个driver
object是什么?它是WebdriverIO session object的一个实例。您可以WebdriverIO API和所有JavaScript语法!

这也正好解释了上面的代码,比如代码中driver.$
相当于findElement,而代码中的〜表示ID定位。您还可以在字符串中返回文本,数据甚至元素,这些结果在父脚本中也可以使用。

** 使用 Execute Driver Script**

我想了解Execute Driver
Script对测试执行时间的影响,因此我在支持此功能的Appium云提供商上进行了大量实验:HeadSpin(感谢HeadSpin)
。我的测试结果(客户端位置在Vancouver, Canada):

Server|

Using Execute

Driver?

|

Avg Test Time

|

Avg Command

Time

|

Avg Speedup

---|---|---|---|---

Localhost

|

No

|

49.12s

|

0.55s

|

Localhost

|

Yes

|

48.71s

|

0.54s

|

0.8%

Mountain

View, CA

|

No

|

72.53s

|

0.81s

|

Mountain

View, CA

|

Yes

|

43.15s

|

0.48s

|

40.5%

Tokyo,

Japan

|

No

|

102.03s

|

1.13s

|

Tokyo,

Japan

|

Yes

|

42.10s

|

0.47s

|

58.74%

** 分析**

如果在本地执行,使用Execute Driver Script
并不会带来太多改进。这也很好理解,当客户端和服务器使用相同的网络接口时,基本上没有时间丢失的延迟。但是当Appium服务器位于其他地方时,进步就特别大。

Mountain View, CA离我在Vancouver的办公室要近一些,而
Tokyo离我的办公室则远一些,数据上的差异接近30%(Tokyo的平均时间更长)。这种差异首要问题是延迟,延迟加深了client/server
model中存在的问题。比如命令很多时(每个测试有90个命令),测试时间大约30秒。

当我使用Execute Driver
Script时,所有的90个命令都包含在一个批处理中,结果显示测试时间降低。由于我只进行了一次网络调用,因地理分布引起的延迟变得可以忽略不计,将测试行为时间缩短了40-60%!当然,此功能也受其它因素影响,包括批处理调用中输入的命令数等等……我也不建议将每个命令都填充到
Execute Driver Script,这里仅演示可能的性能改进。

**
**

** 测试方法**

  • 这些测试是在HeadSpin在世界各地的真实网络上运行,并且使用真实的Android设备上,这些设备位于加州山景城和日本东京。(在本地,测试则使用我自己的笔记本电脑,运行手机模拟器和Appium服务器,因此与真实设备有些不同)

  • 对于每个测试条件(不同位置,是否使用Execute Driver Script),运行了15个不同的测试。

  • 每个测试包括重复登录和注销5次。

  • Appium命令的总数(不计算会话开始和退出)是每次测试90个,这意味着每个测试条件总共为1,350个。

  • 表中的数字会丢弃会话开始和退出时间,仅计算会话中的测试时间(如果你的时间主要集中在会话开始上,有非常少的命令,那么本篇文章对您用处不大)。

** 总结**

Execute Driver Script
是新的Appium功能,在分布式测试时尤其有用。如果云服务器或设备位于世界各地,则每个命令将花费很长时间(甚至长于服务器关闭命令)。设备越远,命令执行时间就越长。管理员可以选择打开Appium中的Execute
Driver
Script,以允许其用户批量命令,这样可以避免与服务器进行大量不必要的延迟,为用户提供了很多优势,减少了延迟成本。当然,这是一项高级功能,您只应该用它来解决具体问题!

如果您想查看项目的java代码,可以在GitHub上查看:

https://github.com/cloudgrey-
io/appiumpro/blob/master/java/src/test/java/Edition085_Execute_Driver_Script.java。

其他Appium客户端也支持这个新命令,包括WebdriverIO(所以你可以使用WebdriverIO-ception!)

非常感谢HeadSpin启用该功能并让我使用设备,因此我可以为本文收集数据。

Cheers,

Jonathan & Jonah

翻译:若桐

往期推荐

大话JMeter4|不同的并发数可以自动化做压测吗?

大话JMeter3|如何借助工具搞定高颜值的性能监控报告

大话JMeter2|正确get参数传递和HTTP如何正确使用

大话jmeter,带你了解jmeter的基础用法

- 今日互动 -

**
**

欢迎文章下方留言并分享给其他测试小伙伴哦~

小编PS:

因为很多小伙伴想深入学习性能测试。我们邀请了专注性能十多年的性能架构师高楼老师给大家带来了《高级性能测试实战训练营》,想了解的小伙伴可以添加小助手微信进行咨询哦。课程信息可点击下方蓝色字体“阅读原文”进行试听。

(别忘了 长按 加小助手微信:jasmine07222

回复“ 性能测试 ”即可入群交流哦~)

来霍格沃兹测试开发学社,学习更多软件测试与测试开发的进阶技术,知识点涵盖web自动化测试 app自动化测试、接口自动化测试、测试框架、性能测试、安全测试、持续集成/持续交付/DevOps,测试左移、测试右移、精准测试、测试平台开发、测试管理等内容,课程技术涵盖bash、pytest、junit、selenium、appium、postman、requests、httprunner、jmeter、jenkins、docker、k8s、elk、sonarqube、jacoco、jvm-sandbox等相关技术,全面提升测试开发工程师的技术实力
QQ交流群:484590337
公众号 TestingStudio
点击获取更多信息

原文地址:https://www.cnblogs.com/hogwarts/p/15817869.html