僅此一招,教你搞定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
點擊獲取更多信息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM