最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

干貨 | 解決 App 自動化測試的常見痛點(diǎn)(彈框及首頁啟動加載完成判斷處理)

2022-10-20 15:45 作者:愛測軟件測試  | 我要投稿


App 自動化測試中有些常見痛點(diǎn)問題,如果框架不能很好的處理,就可能出現(xiàn)元素定位超時找不到的情況,自動化也就被打斷終止了。很容易打消做自動化的熱情,導(dǎo)致從入門到放棄。比如下面的兩個問題:

一是 App 啟動加載時間較久(可能 App 本身加載慢,可能移動設(shè)備本身加載應(yīng)用速度慢,也可能首頁廣告時間較長)。

另一個是各種彈框的出現(xiàn),廣告彈框,升級彈框,評價彈框等。在框架中如果不能處理好上面的情況,

以雪球 App 出現(xiàn)的幾種彈框舉例:

彈框一:

彈框二:

彈框三:

  • 彈框的影響范圍

  • 彈框?qū)ξ覀冏詣踊挠绊懼饕怯美龍?zhí)行的打斷,而至于彈框中廣告內(nèi)容的跳轉(zhuǎn)或評價信息填寫等屬于另外的測試,因此我們主要是要將彈框處理消失,使應(yīng)用回到用例執(zhí)行的 PO;

  • 彈框的消失方式

  • 觀察彈框,我們會發(fā)現(xiàn)一般為了保證用戶體驗(yàn),彈框都會方便用戶進(jìn)行一鍵消除,例如上述中雪球的各種彈框,可能點(diǎn)擊一個叉號,可能任意點(diǎn)擊其他地方,或者評價框這種直接點(diǎn)擊“下次再說”等。

  • 彈框的處理效果

  • 自動化執(zhí)行的任何時候,任意的彈框都可能出現(xiàn),在這個時候用例不能失敗,需要將對應(yīng)的彈框正確處理后繼續(xù)執(zhí)行原用例,原用例的執(zhí)行過程不受影響。

  1. 將需要處理的彈框元素加入到一個黑名單List中,遍歷List,通過findElements方法得到的List大小來判斷彈框元素是否存在,存在即點(diǎn)擊處理

public static void handleAlert(){ ? ??

? ?List<By> alertBox = new ArrayList<>(); ? ? ? ?alertBox.add(By.id("ib_close")); ? //廣告彈框 ? ? ? ?alertBox.add(By.id("md_buttonDefaultNegative")); //評價彈框 ? ??

? ?alertBox.forEach(alert->{ ? ? ?

?? ? ?By adsLocator = alert; ??

? ? ? ? ?List<WebElement> ads = driver.findElements(adsLocator); ? ? ? ? ? ?if (ads.size() >= 1) { ? ??

? ? ? ? ? ?ads.get(0).click(); ? ?

?? ? ? ?} ??

? ? ?}); ??

?}

  1. 將handleAlert()方法加到driver.findElement方法之前,使定位前先判斷彈框的存在與否并進(jìn)行處理

public static WebElement findElement(By by) { ? ? ? ? ? ?System.out.println(by); ? ? ?

?? ? ?handleAlert(); ? ??

? ? ? ?return driver.findElement(by); ??

? ? ? ? ?}

上述方法初步解決了彈框問題,但是缺點(diǎn)也很明顯。

缺點(diǎn):每次定位元素前都需要處理彈框,影響執(zhí)行效率,速度較慢 因此我們引入try catch來解決此問題

我們利用try catch的異常捕獲處理的機(jī)制,讓元素僅在定位失敗時才進(jìn)入彈框處理handleAlert()方法,處理完畢后重新返回driver.findElement(by),對原case元素繼續(xù)進(jìn)行定位執(zhí)行;這樣就大大提升了處理效率,使處理更為精準(zhǔn)。

public static WebElement findElement(By by) {?

? ? ? ?try { ??

? ? ? ? ?System.out.println(by); ? ? ??

? ? ?return driver.findElement(by); ??

? ? ?} catch (Exception e) { ? ? ? ? ?

??System.out.println("進(jìn)入彈框處理"); ? ?

?? ? ? ?handleAlert(); ? ? ? ??

? ? ? ?return driver.findElement(by); ? ?

?? ? ? ?} ?

??}

遞歸處理: 一般情況下我們一次只會出現(xiàn)一個彈框,但是例外的是可能有一個以上的彈框同時出現(xiàn),這樣的話雖然處理了其中一個彈框,但是剩下的彈框依然會阻斷用例的正常執(zhí)行,這個時候就可以使用遞歸的方法,在處理完彈框后返回findElement方法自身,繼續(xù)進(jìn)行try catch,使之進(jìn)入彈框處理邏輯

public static WebElement findElement(By by) { ? ?

?? ? ?try { ? ? ??

? ? ? ?System.out.println(by); ? ? ?

? ? ? ?return driver.findElement(by); ??

? ? ? ?} catch (Exception e) { ? ? ? ? ?

?? ?System.out.println("進(jìn)入彈框處理"); ? ??

? ? ? ? ?handleAlert(); ? ? ? ? ? ??

? ? ?return findElement(by); ? ? ??

? ? ? ?} ? ?

??}

注意: 使用遞歸方法后有一個問題,就是假如并不是因?yàn)槟硞€彈框的出現(xiàn)而導(dǎo)致的定位失敗,而這個時候通過try catch進(jìn)入到彈框處理邏輯后,由于并未匹配到彈框元素,所以遞歸就會進(jìn)入一個死循環(huán),不斷重復(fù)著彈框處理的邏輯,所以使用遞歸時我們也需要對其次數(shù)進(jìn)行限制;一般兩個彈框同時出現(xiàn)已經(jīng)算多的了,所以建議可以將遞歸的次數(shù)限制到最多兩次便退出。

static int i = 1;?

public static WebElement findElement(By by) {? ?

?try { ? ?

?? ?System.out.println(by); ? ?

? ?return driver.findElement(by); ?

??} catch (Exception e) { ? ? ?

??if (i > 2){ ? //設(shè)置最多遞歸兩次 ?

? ? ? ? ?i = 1; ? ??

? ? ? ?return driver.findElement(by); ? ?

? ?} ? ?

?? ?System.out.println("進(jìn)入彈框處理第"+i+"次");? ??

? ? handleAlert(); ? ? ?

?i++; ??

? ? ?return findElement(by); //最后調(diào)用自身完成遞歸,防止多彈框同時出現(xiàn)造成定位失敗 ? ?

? ?}

?}

按照上面的方法,看似已經(jīng)很好的解決了彈框的處理,但是可以注意到的是:

  • 在檢查彈框的時候依然使用的是appium的定位,在當(dāng)前頁面中根據(jù)元素的屬性去一一查找定位

  • 所有的黑名單中的彈框都會被定位查找一遍

而我們實(shí)際中最想要的也是最有效率的方法應(yīng)該是:

  • 只有在當(dāng)前頁面中存在的彈框才對其進(jìn)行定位、操作、處理。為了達(dá)到我們想要的效果,就需要借助于PageSource了。

1)appium的driver提供了一個getPageSource方法,此方法可以在當(dāng)前頁面可以得到一個文本字符串,也可以理解為當(dāng)前頁面的xml,我們利用這種xml文本來進(jìn)行判斷,就比用appium一一定位的方式要快速和精準(zhǔn)的多了

String pageSource = driver.getPageSource();

2)設(shè)置黑名單,黑名單要使用元素的xpath,用來和PageSource文本做匹配,判斷此彈框是否存在當(dāng)前頁面

String adBox = "com.xueqiu.android:id/ib_close";?

String gesturePromptBox = "com.xueqiu.android:id/snb_tip_text"; String evaluateBox = "com.xueqiu.android:id/md_buttonDefaultNegative"; HashMap<String,By> map = new HashMap<>(); map.put(adBox,By.id("ib_close")); map.put(gesturePromptBox,By.id("snb_tip_text")); map.put(evaluateBox,By.id("md_buttonDefaultNegative"));

4)遍歷map,判斷黑名單彈框元素是否存在于當(dāng)前pageSource,存在即根據(jù)彈框處理方式進(jìn)行點(diǎn)擊或其他操作(如上述中的新功能提示彈框,點(diǎn)擊彈框自身無法消除,需點(diǎn)擊頁面其余部分方可消除)處理

map.entrySet().forEach(entry ->{ ??

?if (pageSource.contains(entry.getKey())){?

? ? ? ?if (entry.getKey().equals("com.xueqiu.android:id/snb_tip_text")){ ? ? ? ? ? ?System.out.println("gesturePromptBox found"); ? ? ? ? ? ?Dimension size = driver.manage().window().getSize(); ? ?

? ? ? ?//點(diǎn)擊屏幕的中心位置,消除新功能提示彈框 ? ? ?

? ? ?new TouchAction<>(driver).tap(PointOption.point(size.width/2,size.height/2)).perform(); ? ? ? ?}else { ? ? ?

?? ?//其余彈框直接點(diǎn)擊消除 ? ? ? ? ? ?driver.findElement(entry.getValue()).click(); ??

? ? ?} ??

?} });?

//很多彈框的話,最好的是直接定位到到底哪個彈框在界面上,元素的判斷使用xpath ? ?public static void handleAlertByPageSource(){ ?

?? ? ?String pageSource = driver.getPageSource();

//可以得到一個文本字符串,也可以理解為當(dāng)前頁面的xml ??

? ? ?//黑名單 ? ??

? ?String adBox = "com.xueqiu.android:id/ib_close"; ??

? ? ?String gesturePromptBox = "com.xueqiu.android:id/snb_tip_text"; ? ? ? ?String evaluateBox = "com.xueqiu.android:id/md_buttonDefaultNegative"; ? ? ? ?//將標(biāo)記和定位符存入map ??

? ? ?HashMap<String,By> map = new HashMap<>(); ? ? ? ?map.put(adBox,By.id("ib_close")); ? ? ? ?map.put(gesturePromptBox,By.id("snb_tip_text")); ? ? ? ?map.put(evaluateBox,By.id("md_buttonDefaultNegative")); ? ? ?

??//臨時修改隱式等待時間,防止查找黑名單中元素過久 ? ? ? ?driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);?

?? ? ? ?//遍歷map,判斷黑名單彈框元素是否存在于當(dāng)前pageSource,存在即點(diǎn)擊處理 ? ? ? ?map.entrySet().forEach(entry ->{ ? ? ??

? ? ?if (pageSource.contains(entry.getKey())){ ? ? ? ? ??

? ? ?if (entry.getKey().equals("com.xueqiu.android:id/snb_tip_text")){ ? ? ? ? ? ? ? ? ? ?System.out.println("gesturePromptBox found"); ? ? ? ? ? ? ? ? ? ?Dimension size = driver.manage().window().getSize(); ? ? ? ? ? ? ? ? ? ?new TouchAction<>(driver).tap(PointOption.point(size.width/2,size.height/2)).perform(); ? ? ? ? ? ? ? ?}else { ? ? ? ? ? ? ? ? ? ?driver.findElement(entry.getValue()).click(); ? ? ? ? ? ? ? ?} ? ? ? ? ? ?} ? ? ? ?}); ? ??

? ?//判斷完成后將隱式等待時間恢復(fù) ? ? ? ?driver.manage().timeouts().implicitlyWait(8,TimeUnit.SECONDS); ? ?}

6)最后將findElement方法中的handleAlert方法替換為handleAlertByPageSource方法即可

static int i = 1;?

public static WebElement findElement(By by) { ?

??try { ? ?

?? ?System.out.println(by); ? ??

? ?return driver.findElement(by);

?? ?} catch (Exception e) { ??

? ? ?if (i > 2){ ? //設(shè)置最多遞歸兩次 ?

?? ? ? ? ?i = 1; ? ? ??

? ? ?return driver.findElement(by); ? ?

?? ?} ? ??

? ?System.out.println("進(jìn)入彈框處理第"+i+"次"); ? ? ? ? ? ? ? ?handleAlertByPageSource(); ??

? ? ?i++; ? ? ??

?return findElement(by);?

//最后調(diào)用自身完成遞歸,防止多彈框同時出現(xiàn)造成定位失敗 ?

?? ? ?}?

}

再來解決首頁加載時可能出現(xiàn)的坑。

App 啟動加載時間較久(可能 App 本身加載慢,也可能是移動設(shè)備本身加載應(yīng)用速度慢,也可能首頁廣告時間較長),導(dǎo)致定位超時,用例失敗。對此我們又如下兩步解決辦法。

如標(biāo)題所述,對首頁進(jìn)入使用顯示等待,利用搜索控件的出現(xiàn)來判斷是否進(jìn)入了首頁,這樣不影響其他元素隱式等待的時間,也解決了首頁初始化加載時間過長的問題。

例如雪球僅在進(jìn)入首頁后會出現(xiàn) id為user_profile_container的用戶信息控件,那么我們就可以以此為依據(jù)來判斷應(yīng)用是否加載完成進(jìn)入了首頁。

在啟動方法中加入顯示等待上述首頁控件 30 秒,到控件可被定位時確認(rèn)進(jìn)入首頁。

new WebDriverWait(driver,30) ? ? ? ? ? ? ? ?.until(ExpectedConditions.visibilityOfElementLocated(By.id("user_profile_container")));

缺點(diǎn): 但是這樣有個情況不能解決:若加載完成后有彈框出現(xiàn),可能就一直無法定位到首頁元素,但是實(shí)際上已經(jīng)加載完成,比如下圖的首頁廣告彈框 。

文章第二部分介紹了利用 PageSource 來判斷彈框是否存在的方法,在這里依然適用,還是熟悉的味道,還是同樣的套路,將彈框元素 xpath 也加入 PageSource 判斷,這樣無論首頁控件和首頁彈框哪一個被發(fā)現(xiàn),就都可以判斷應(yīng)用已經(jīng)加載完成,成功進(jìn)入首頁,剩下的就可以交給用例和其他處理邏輯了

new WebDriverWait(driver,30) ??

? ? ? ? ? ? ?.until(x ->{?

?? ? ? ? ? ?String xml = driver.getPageSource(); ? ? ? ? ? ? ? ? ? ?Boolean checkResult = xml.contains("user_profile_container") || xml.contains("com.xueqiu.android:id/ib_close"); ? ? ? ? ? ? ? ? ? ?System.out.println("主頁元素查找的結(jié)果是:" + checkResult); ? ? ? ? ? ? ? ? ? ?return checkResult; ? ? ? ? ? ??

? ?});

好了,經(jīng)過上面的分析之后,我們終于搞定了入門 APP 自動化測試時的老大難問題。搞定了彈框及首頁啟動時加載完成如何判斷處理。

技能學(xué)習(xí),站在高手/過來人的肩膀上,才能高效進(jìn)階。


干貨 | 解決 App 自動化測試的常見痛點(diǎn)(彈框及首頁啟動加載完成判斷處理)的評論 (共 條)

分享到微博請遵守國家法律
台北市| 景德镇市| 孙吴县| 来安县| 乐清市| 永州市| 红河县| 湘阴县| 石首市| 永顺县| 响水县| 会东县| 固原市| 柘城县| 潜山县| 廉江市| 云梦县| 南投市| 临江市| 临湘市| 隆回县| 石渠县| 登封市| 平山县| 新闻| 香港 | 修文县| 含山县| 彭阳县| 临武县| 河津市| 荔浦县| 荆门市| 乡城县| 垣曲县| 乐安县| 临武县| 眉山市| 宁南县| 滦南县| 自治县|