目 錄:
1. 小程序自動化方案
1.1 小程序的基本構成
1.2 原生組件定位之UiSelector
1.2.1 原生組件定位之UiSelector
1.2.2 web元素定位
1.3 小程序自動化準備
1.3.1 安裝appium
1.3.2 安裝adb tools
1.3.3 chromedriver.exe版本
1.3.4 打開手機的開發(fā)者選項
1.3.5 打開webview的debug模式
1.3.6 關于context切換
1.3.7 關于windowHandles
1.3.8 常見的問題
2. 微信小程序自動化
2.1 開啟微信webview debug模式
2.2 開始你的自動化demo
2.2.1 啟動appium服務
2.2.2 確認小程序的androidProcess參數
2.2.3 愛奇藝視頻小程序demo
3. 百度小程序自動化
3.1 安裝百度智能小程序調試包
3.2 確認androdProcess進程名
3.3 百度小程序demo
4. 小程序自動化庫
4.1 百度小程序接口
4.2 微信小程序接口
4.3 安卓常用操作接口Device
4.4 命令行操作接口Command
4.5 圖像識別AirCv
1. 小程序自動化方案
目前小程序自動化主要有以下三種方案:
-
Appium框架
【官網】:http://appium.io/
摩拜小程序自動化python版
美團小程序自動化java版 -
網易的airtest框架
airtest微信小程序教程 -
騰訊的Fast-AutoTest
https://github.com/Tencent/FAutoTest
FAT(Fast-AutoTest) —專業(yè)服務于微信H5/小程序UI自動化測試
網易的Airtest在圖像識別元素上做的很不錯泉沾,但愛奇藝視頻小程序固定的UI元素非常少愚铡,大部分都是視頻封面圖墓臭,應用自動化比較受限制耿戚。
騰訊的FAT是騰訊測試團隊剛開源的框架铃绒,粗略看了下代碼插爹,可能對騰訊自家的APP支持的比較好别伏,比如微信、qq瀏覽器等赔蒲,但如果要測試其他的小程序泌神,比如百度/支付寶小程序,可能還需要一些修改源代碼的成本舞虱,目前社區(qū)也不太活躍欢际,對于其執(zhí)行效率,宣傳說是比Appium要高矾兜,但我暫時未寫demo詳細去對比损趋,具體性能數據未知。
最終還是選擇了appium框架椅寺,再加Airtest圖像識別功能輔助測試浑槽,appium社區(qū)相對來說活躍度較高,維護團隊穩(wěn)定返帕。
1.1 小程序的基本構成
小程序融合了Native app和web-app的特性桐玻,屬于混合型應用(Hybrid App)。以愛奇藝視頻微信小程序為例荆萤,上面的TopActionBar和下邊的Bottom Action Bar是屬于原生的組件镊靴,而中間是由webview渲染的,屬于web應用。
對于安卓原生的UI組件偏竟,我們可以直接用UIAutomator查看元素屬性算行,如下圖所示
1.2 原生組件和web元素定位
1.2.1 原生組件定位之UiSelector
UiSelector對于各種原生組件屬性的匹配,有以下四種匹配關系:
- 完全匹配
- 包含匹配
- 正則匹配
- 起始匹配
每個原生組件有很多屬性苫耸,如resource-id
、text
儡陨、class
褪子、content-desc
等,這些是比較常用的骗村,還有如下屬性
屬性值 值類型 說明
index int 索引:同級組件的下標嫌褪;從0開始計
instance int 界面中同一類View的所有實例的下標;從0開始計
class String 組件的類名胚股,如 android.widget.TextView
package String 包名
Content-desc String 描述
checkable boolean 是否可選笼痛,一般只對 單選或 復選框有用。
checked boolean 單選或 復選框 是否被選中
clickable boolean 是否可點擊
enabled boolean 是否可操作琅拌,如 按鈕置灰不可操作狀態(tài)
focusable boolean 是否可獲取焦點
focused boolean 是否獲取到焦點
Scrollable boolean 是否可滾動缨伊,一般是list
Long-clickable boolean 是否可長按
password boolean 是否密碼
selected boolean 是否具有背景選擇屬性,如按鈕點擊后背景色變化
bounds Rect 坐標进宝,如 [366,999][708,1197]表示控件的矩形區(qū)域左上和右下坐標點
appium中查找原生組件的方法可用findElementByAndroidUIAutomator
刻坊,以下會省略該方法名,直接寫UiSelector
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"愛奇藝視頻\")")
- ID屬性resource-id定位
//resourceId全匹配
new UiSelector().resourceId("com.baidu.searchbox.remotedebug:id/baidu_searchbox")
//正則匹配baidu_searchbox結尾
new UiSelector().resourceIdMatches(".*baidu_searchbox")
//包含匹配党晋,包含SearchTextInput的組件
new UiSelector().resourceIdContains("SearchTextInput")
//起始匹配
new UiSelector().resourceIdStartsWith("com.baidu.searchbox.remotedebug")
- 文本屬性text定位
//通過文本定位
driver.findElementByAndroidUIAutomator("new UiSelector().text(\"愛奇藝視頻\")")
//正則匹配查找未登錄或我的
new UiSelector().textMatches("未登錄|我的")
new UiSelector().textMatches("愛奇藝.*")
//包含我的
new UiSelector().textContains("我的")
//以首開頭
new UiSelector().textStartsWith("首")
//查找界面中文本為“微信紅包”的第3個組件
new UiSelector().text("微信紅包").instance(2);
- 描述屬性content-desc
//通過文本定位
driver.findElementByAndroidUIAutomator("new UiSelector().description(\"更多\")")
new UiSelector().descriptionMatches("更多\w+")
new UiSelector().descriptionContains("更多")
new UiSelector().descriptionStartsWith("更多")
- 其他屬性
//類名為android.widget.RelativeLayout谭胚,下標index為5的
new UiSelector().className("android.widget.RelativeLayout").index(5);
//包名為com.android.deskclock的第五個組件
new UiSelector().packageName("com.android.deskclock").instance(5)
//checkable屬性為true的
new UiSelector().checkable(true);
new UiSelector().longClickable(true).index(4);
-
節(jié)點關系復雜定位
- 父:Parent
- 子: Children
- 同胞: Sibling
- 先輩: Ancestor
- 后代:Descendant
//childselector查找子類
new UiScrollable(new UiSelector().scrollable(true)
.childSelector(new UiSelector().text("Android")))
//formParent查找父類
new UiSelector().resourceId("com.baidu.searchbox.remotedebug:id/search_list")
.fromParent(new UiSelector().className("android.widget.LinearLayout").index(1));
1.2.2 web元素定位
文檔較多,不列舉
1.3 小程序自動化準備
JAVA: 1.8
node js : 10.14.2
adb: 1.0.40
appium : 1.8.1
1.3.1 安裝appium
- 安裝node環(huán)境
$ node -v
v10.14.2
$ npm -v
6.4.1
- 利用npm全局安裝appium
npm install appium@1.8.1 -g
#安裝需要一定時間未玻,安裝完成后
$ appium -v
1.8.1
1.3.2 安裝adb tools
$ adb --version
Android Debug Bridge version 1.0.40
Version 4986621
Installed as D:\Program Files\androidsdk\Android\Sdk\platform-tools\adb.exe
1.3.3 chromedriver.exe版本
appiumDriver切換webview context需要用到chromedriver灾而,每個app使用的webview版本可能不同,所以需要不同版本的chromedriver與之對應扳剿。詳見:
http://appium.io/docs/cn/advanced-concepts/chromedriver/
1.3.4 打開手機的開發(fā)者選項
每個手機開啟的方式不一樣旁趟,自行搜索。
- 小米手機需要打開開發(fā)者選項舞终、安全模式轻庆、關閉miui優(yōu)化
開啟后,通過命令adb devices
驗證敛劝,如果能發(fā)現設備說明開啟成功
ceshi@DESKTOP-UE2D6JR F:\android-perf-recorder
> adb devices
List of devices attached
ce96dc1b device
d24c3bcc device
- adb無法識別的問題排查
- 確認數據線沒問題
- 按教程:https://jingyan.baidu.com/article/ce09321b5b76642bff858f31.html
- 還是不行的話余爆,按照教程https://blog.csdn.net/zhouyingge1104/article/details/42145429
- 還是不行的話,重新弄一個androidsdk吧夸盟。
1.3.5 打開webview的debug模式
要實現小程序的自動化蛾方,一個非常重要的步驟就是打開app webview的debug模式。但是app一般不會提供debug模式。驗證debug模式是否開啟桩砰,可以通過如下步驟:
打開APP的小程序拓春,數據線連接至電腦
-
PC打開chrome瀏覽器輸入
chrome://inspect
image.png -
找到小程序的webview,點擊inspect亚隅,可看到小程序界面
image.png
如果能看到小程序使用的webview硼莽,那么表明該webview的debug已開啟
1.3.6 關于context切換
appium原本是設計為NATIVE_APP的自動化,為了支持混合應用或APP里的webv頁面測試煮纵,所以有這一概念懂鸵。默認拉起app后,進入的NATIVE_APP
行疏,一般還會有WEBVIEW_xxx
可以查看當前所有的context匆光,python版本:
driver=webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.contexts
['NATIVE_APP', 'WEBVIEW_com.tencent.mm:tools', 'WEBVIEW_com.tencent.mm:toolsmp']
>>>driver.switch_to.context(u'WEBVIEW_com.tencent.mm:tools')
>>>driver.page_source
'<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" ......
1.3.7 關于windowHandles
windowhandle可以看成是chrome里一個標簽頁,小程序每跳轉一個新頁面酿联,會生成一個新的window handle终息,但driver并不會自動切換新的window,所以每次查找元素前贞让,都需要手動切換到相應的window周崭,否則會報no such element
目前能想到的笨辦法是,找一個能標識每個頁面的唯一性元素喳张,然后遍歷每個頁簽休傍,如果page_source有該元素,則切到該頁簽
>>>driver.window_handles
['CDwindow-56b52630-ffcc-4b1f-88cc-c26d4b5e10ed', 'CDwindow-3168289f-c448-4597-bf21-cf825fd29b5c', 'CDwindow-4a0d4647-27a5-4cfa-92a7-357ee6901c2a']
>>>driver.switch_to.window('CDwindow-3168289f-c448-4597-bf21-cf825fd29b5c')
>>>driver.current_window_handle
'CDwindow-3168289f-c448-4597-bf21-cf825fd29b5c'
>>>driver.title
'中國新說唱官方投票通道'
>>>driver.switch_to.window('CDwindow-4a0d4647-27a5-4cfa-92a7-357ee6901c2a')
>>>driver.title
''
>>>driver.switch_to_window('CDwindow-56b52630-ffcc-4b1f-88cc-c26d4b5e10ed')
>>>driver.title
'百度一下'
1.3.8 常見的問題
-
如何解決打開頁面路徑太長的問題
由于微信小程序沒有類似的H5的url蹲姐,所以得通過點擊路徑打開目標頁面磨取,路徑長容易導致穩(wěn)定性差。解決辦法是可通過執(zhí)行wx api來直接跳轉頁面柴墩,因為在小程序內忙厌,開發(fā)也是直接調用wx.navigateTo來跳轉的,所以想到江咳,能不能通過js executor來執(zhí)行wx api
image.png -
元素的點擊方法無反應
可以找到元素逢净,但調用元素的點擊方法無反應,原因是有的微信元素監(jiān)聽的是tap事件歼指,不是click事件爹土。
image.png -
元素getLocation接口獲取的坐標位置不準
image.png -
如何校驗視頻正在播放
image.png 切換context一直卡住,appium報chrome not reachable
- 確認webview的debug模式開啟
- 確認
chrome://inspect
可以看到小程序 - 確認androidProcess正確
- 微信小程序的話確認是從搜一搜入口進去
- 查找appium的日志看報錯
- 查找元素時報no sucn element
- 打印pageSource踩身,看是否有相應元素
- 打印出所有windowHandles胀茵,遍歷所有看是否有相應元素
- 如果沒有,那就不是小程序的webview context挟阻,確認androidProcess是否正確
- chrome version must be >xx
- chromedriver版本與小程序的webview版本不匹配
解決: 啟動appium時指定--chromedriver-executable參數琼娘,或者將appium的默認chromedriver.exe版本替換
-
微信點擊搜一搜報錯
appium 1.8.1峭弟,java-client6.1.0
driver.findElementByAndroidUIAutomator("text(\"搜一搜\")").click()
該行代碼報UiAutomator exited unexpectedly with code 4294967295
https://testerhome.com/topics/13496,不是缺少/data/local/tmp/AppiumBootstrap.jar
https://blog.csdn.net/Sily_Z/article/details/80584750脱拼,重啟手機也不是很好使
看日志是堆棧溢出:[UIAUTO STDOUT] INSTRUMENTATION_RESULT: shortMsg=java.lang.StackOverflowError
改為用adb點擊搜一搜也是一樣的結果瞒瘸。
https://www.cnblogs.com/chongyou/p/5263198.html,說前面有程序沒結束熄浓,所以手動清理了后臺的微信進程情臭。并設置微信不能一直保持后臺運行。還是沒解決赌蔑。
解決:換為uiautomator2版本谎柄。
uiautomator2一直提示安裝uiautomator2.server和uiautomator2.server.test
解決:小米手機的話,打開usb安裝惯雳,并關閉miui優(yōu)化
或者修改uiautomator2-server源碼:
https://blog.csdn.net/hszxd479946/article/details/78900982點擊報錯:
java.lang.StackOverflowError
java.lang.StackOverflowError: stack size 1037KB\n\tat android.util.SparseArray.get
https://github.com/appium/appium/issues/10204
-
想拉微信卻拉起了chrome瀏覽器
解決:加上以下配置
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"");
- uiautomator2報簽名錯誤
java.lang.SecurityException: Permission Denial: starting instrumentation
ComponentInfo{io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner}
from pid=19303, uid=19303 not allowed because package io.appium.uiautomator2.server.test
does not have a signature matching the target io.appium.uiautomator2.server
原因是安裝了不同的uiautomator版本,卸載原來的就行鸿摇。
解決:https://stackoverflow.com/questions/3082780/java-lang-securityexception-permission-denial
adb uninstall io.appium.uiautomator2.server.test
2. 微信小程序自動化
2.1 開啟微信webview debug模式
注意:
- 微信6.7.3版本時代石景,webview是57版本,此時可通過如下方法打開debug拙吉,但必須從微信搜一搜入口打開小程序,才可以切換webview的context,從其他入口均報
chrome not reachable
- 微信6.7.3時代勺良,安卓8.0系統刊头,57版本對應的chromedriver有bug,也包
chrome not reachable
- 微信升級7.0后佛舱,webview升級到66版本椎例,此時搜一搜入口也無法切換context
- 目前只有6.6.7以下版本,可開啟debug模式進行自動化
微信打開http://debugx5.qq.com
x5調試頁面请祖,點擊信息订歪,然后勾選【打開TBS內核Inspector調試功能】,勾選后重啟微信
- 遇到低版本無法登錄的問題肆捕?
解決:暫時未找到刷晋,貌似跟微信賬號還有關系,有的能登慎陵,有的不行
手機通過數據線連接電腦眼虱,adb devices
命令驗證連接成功
微信掃碼打開愛奇藝視頻小程序,chrome瀏覽器輸入chrome://inspect
席纽,看能否找到小程序的webivew捏悬,點擊inspect可查看小程序頁面。
2.2 開始你的自動化demo
chrome inspect成功后润梯,恭喜你已經成功準備好環(huán)境邮破,下一步便可開始擼代碼了
2.2.1 啟動appium服務
啟動appium服務比較簡單诈豌,但得注意appium自帶的chromedriver版本可能與微信的webview無法匹配。詳見:appium與chromedriver
因此抒和,在啟動時最好帶--chromedriver-executable參數矫渔,目前微信webview版本是66,可用2.36版本的chromedriver摧莽,啟動服務命令如下:
C:\Users\zengzhihua>appium --chromedriver-executable=D:\chromedrivers\chromedriver_2.36.exe --log-level=debug
(node:632) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
[Appium] Welcome to Appium v1.8.1
[Appium] Non-default server args:
[Appium] chromedriverExecutable: D:\chromedrivers\chromedriver_2.36.exe
[Appium] Appium REST http interface listener started on 0.0.0.0:4723
如果沒有報錯就ok了庙洼,默認開啟4723端口
2.2.2 確認小程序的androidProcess參數
appium進行混合應用的自動化,需要androidProcess參數镊辕,我理解是小程序在android系統中的進程名油够,獲取方法如下
- 打開愛奇藝視頻小程序,運行在前端
- 輸入
adb shell
進入adb命令行模式征懈,如果是多個設備石咬,需加-s參數
- 輸入
- 輸入
dumpsys activity top|grep ACTIVITY
,查看進程號pid
- 輸入
- 輸入
ps pid
, pid為上一步獲取
- 輸入
$ adb shell
# 打開小程序卖哎,然后輸入以下命令查看當前活動的進程號
shell@PD1621:/ $ dumpsys activity top|grep ACTIVITY
ACTIVITY com.tencent.mm/.plugin.appbrand.ui.AppBrandInToolsUI ad729c6 pid=28902
# 查看當前進程號28902的進程信息鬼悠,進程名為com.tencent.mm:tools。
shell@PD1621:/ $ ps 28902
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a227 28902 669 1900832 246896 00000000 R com.tencent.mm:tools
shell@PD1621:/ $
并不是每次都是com.tencent.mm:tools
亏娜,貌似跟打開小程序的入口有關焕窝,有的是com.tencent.mm:toolsmp
,還有的com.tencent.mm:appbrand0
或 com.tencent.mm:appbrand1
2.2.3 愛奇藝視頻小程序demo
目前打開小程序维贺,必須從首頁的搜索按鈕或者發(fā)現頁的搜一搜它掂,搜索愛奇藝視頻小程序,然后點擊切換到小程序TAB溯泣,點擊第一個鏈接(一般第一個鏈接便是)
/**
* Created by zengzhihua on 2019/3/30.
*/
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
public class WeXinTest {
static AndroidDriver<MobileElement> driver = null;
public static DesiredCapabilities getDefaultCapabilities() {
DesiredCapabilities caps = new DesiredCapabilities();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
caps.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 1200);
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "34c2ca44");
caps.setCapability(MobileCapabilityType.FORCE_MJSONWP, true);
caps.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.tencent.mm");
caps.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".ui.LauncherUI");
caps.setCapability("showChromedriverLog", true);
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
caps.setCapability("noReset", true);
caps.setCapability("unicodeKeyboard", true);
caps.setCapability("resetKeyboard", true);
caps.setCapability(MobileCapabilityType.CLEAR_SYSTEM_FILES, true);
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"");
// caps.setCapability("chromedriverExecutableDir", chromeDriverDir);
// caps.setCapability("chromedriverChromeMappingFile", "D:\\minidrivers\\chromeDriverMapping.json");
// caps.setCapability(MobileCapabilityType.BROWSER_NAME,"");
// caps.setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true);
return caps;
}
public static void main(String[] args) throws Exception {
DesiredCapabilities desired_capabilities = getDefaultCapabilities();
try {
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"),desired_capabilities);
String searchIconSelector = "new UiSelector().description(\"搜索\")";
driver.findElementByAndroidUIAutomator(searchIconSelector).click();
driver.findElementByAndroidUIAutomator("text(\"搜索\")").sendKeys("愛奇藝視頻小程序");
driver.findElementByAndroidUIAutomator("text(\"小程序虐秋、公眾號、文章垃沦、朋友圈和表情等\"").click();
Thread.sleep(2000);
//點擊方法可切換到webview查找元素點擊熟妓。clickByPointPercent方法是根據坐標百分比點擊
clickByPointPercent(30, 15); //點擊小程序標簽
Thread.sleep(2000);
clickByPointPercent(26, 26); //點擊打開小程序,一般第一個即是目標小程序
Thread.sleep(5000);
System.out.println(driver.getContextHandles());
System.out.println(driver.getContext());
driver.context("WEBVIEW_com.tencent.mm:tools");
System.out.println(driver.getWindowHandles());
System.out.println(driver.getPageSource());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
3. 百度小程序自動化
百度小程序的自動化總體類似栏尚,只是需要下載百度的調試包起愈。調試包可下載百度小程序開發(fā)者工具,然后點擊遠程調試译仗,會自動安裝百度智能小程序的調試包抬虽。
3.1 安裝百度智能小程序調試包
手機百度調試包:
鏈接:https://pan.baidu.com/s/1L1HwW7yYoZ1LlKY7q_KwPA
提取碼:khef
百度智能小程序調試包下載地址:
鏈接:https://pan.baidu.com/s/1tQ3ddlSctowJ_NfV7GjmmA
提取碼:rniz
3.2 確認androdProcess進程名
3.3 百度小程序demo
打開小程序方法,從首頁搜索“愛奇藝視頻”纵菌,搜索聯想詞第一個便是小程序阐污,點擊便可打開
/**
* Created by zengzhihua on 2019/3/30.
*/
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
public class WeXinTest {
static AndroidDriver<MobileElement> driver = null;
public static DesiredCapabilities getDefaultCapabilities() {
DesiredCapabilities caps = new DesiredCapabilities();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOption("androidProcess", "com.baidu.searchbox.remotedebug:aiapps0");
caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
caps.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 1200);
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "DEVICE_NAME");
caps.setCapability(MobileCapabilityType.FORCE_MJSONWP, true);
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
caps.setCapability(MobileCapabilityType.NO_RESET, true);
caps.setCapability(MobileCapabilityType.CLEAR_SYSTEM_FILES, true);
caps.setCapability(MobileCapabilityType.BROWSER_NAME,"");
caps.setCapability("unicodeKeyboard", true);
caps.setCapability("resetKeyboard", true);
caps.setCapability("showChromedriverLog", true);
caps.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, APP_PACKAGE);
caps.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, APP_ACTIVITY);
// caps.setCapability("chromedriverExecutableDir", chromeDriverDir);
// caps.setCapability("chromedriverChromeMappingFile", "D:\\minidrivers\\chromeDriverMapping.json");
// caps.setCapability(AndroidMobileCapabilityType.AUTO_GRANT_PERMISSIONS, true);
// caps.setCapability(AndroidMobileCapabilityType.VERSION, "6.0");
return caps;
}
public static void main(String[] args) throws Exception {
DesiredCapabilities desired_capabilities = getDefaultCapabilities();
try {
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"),desired_capabilities);
String searchInputResourceId = "com.baidu.searchbox.remotedebug:id/baidu_searchbox";
driver.findElementByAndroidUIAutomator(searchInputResourceId).click();
Thread.sleep(2000);
String searchEditTextInputResourceId = "com.baidu.searchbox.remotedebug:id/SearchTextInput";
driver.findElementByAndroidUIAutomator(searchEditTextInputResourceId).sendKeys(appName);
Thread.sleep(2000);
String miniProgramTitleResourceId = "com.baidu.searchbox.remotedebug:id/suggestion_item_title";
driver.findElementByAndroidUIAutomator(miniProgramTitleResourceId).click();
Thread.sleep(3000);
System.out.println(driver.getContextHandles());
System.out.println(driver.getContext());
driver.context("WEBVIEW_com.tencent.mm:tools");
System.out.println(driver.getWindowHandles());
System.out.println(driver.getPageSource());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
4. 小程序自動化庫
在appium的基礎上,進行了簡單的封裝咱圆,同時加入了一點圖像識別功能笛辟,解決難以定位的一些元素功氨。
4.1 百度小程序接口
- 提供百度小程序的一些常用操作方法
import com.iqiyi.qa.minidrivers.BaiduDriver;
import org.openqa.selenium.WebElement;
import java.net.URL;
/**
* Created by zengzhihua on 2019/1/29.
*/
public class BaiduDemo {
public static void main(String[] s) throws Exception {
//構造函數
//1.自啟動默認的appium服務; 2.自選擇連接的設備并拉起百度智能小程序app
//BaiduDriver baiduDriver =new BaiduDriver();
//1.手動啟動appium服務
//BaiduDriver baiduDriver = new BaiduDriver(new URL("http://127.0.0.1:4723/wd/hub"));
//1..指定連接的設備id
//BaiduDriver baiduDriver = new BaiduDriver("ce96dc1b");
//1.手動啟動appium服務;2.指定連接的設備id
//BaiduDriver baiduDriver = new BaiduDriver(new URL("http://127.0.0.1:4723/wd/hub"),"ce96dc1b");
//其他構造函數
//public BaiduDriver(AppiumDriverLocalService service, Capabilities desiredCapabilities);
//public BaiduDriver(AppiumServiceBuilder builder, Capabilities desiredCapabilities);
//public BaiduDriver(Capabilities desiredCapabilities);
//打開百度小程序
baiduDriver.openMiniProgram("愛奇藝視頻");
//查找native原生控件
WebElement mineTabEle = baiduDriver.findElementByAndroidUIAutomator("new UiSelector().textMatches(\"未登錄|我的\")");
baiduDriver.findElementByAndroidUIAutomator("new UiSelector().textMatches(\"未登錄|我的\")").click();
baiduDriver.pause(3);
//baiduDriver.findElementByAndroidUIAutomator("new UiSelector().description(\"更多\")").click();
baiduDriver.findElementByAndroidUIAutomator("text(\"愛奇藝視頻\")").click();
baiduDriver.pause(2);
//點擊坐標
baiduDriver.clickByPoint(500,500);
//按坐標滑動
baiduDriver.swipe(100,1500,600,1500);
//點擊坐標百分比
baiduDriver.clickByPointPercent(80,95);
System.out.println(baiduDriver.getWindowSize().getWidth());
System.out.println(baiduDriver.getWindowSize().getHeight());
//截圖保存默認圖片路徑
baiduDriver.getScreenShotAs();
String viewMoreTmplPath = "E:\\projects\\uiauto-miniprogram\\images\\templates\\openIqiyiBanner.png";
//按照模板圖片查找圖片元素
ImgElement imgEle = baiduDriver.findElementByImg(viewMoreTmplPath);
//點擊圖片元素
imgEle.click();
//返回上一頁
baiduDriver.goBack();
baiduDriver.pause(2);
//返回首頁
baiduDriver.goHome();
baiduDriver.pause(2);
//最小化百度小程序
baiduDriver.closeMiniProgram();
//切換至百度小程序webview
baiduDriver.switchToWebview();
//切換至native context
baiduDriver.switchToNative();
//退出百度
baiduDriver.quit();
//baiduDriver.getScreenShotAs("E:\\screen.png");
//System.out.print(baiduDriver.getContext());
//baiduDriver.context("WEBVIEW_com.baidu.searchbox.remotedebug:aiapps0");
//baiduDriver.getScreenShotAs("E:\\screen2.png");
}
}
4.2 微信小程序接口
- 需安裝微信6.6.5版本手幢,高于此版本無法開啟tbs調試捷凄,chrome://inspect無法成功
- 提供微信小程序的一些常用操作方法
import com.iqiyi.qa.minidrivers.WxDriver;
import java.net.URL;
/**
* Created by zengzhihua on 2019/1/29.
*/
public class WxDemo {
public static void main(String[] s) throws Exception{
// WxDriver wxDriver = new WxDriver();
// WxDriver baiduDriver =new WxDriver();
WxDriver wxDriver = new WxDriver(new URL("http://127.0.0.1:4723/wd/hub"));
wxDriver.pause(3);
// wxDriver.openMiniProgramFromSearch("aiqiyishipin");
// WxDriver wxDriver = new WxDriver();
wxDriver.openMiniProgram("周黑鴨外賣");
wxDriver.pause(2);
wxDriver.clickByPoint(500,500);
wxDriver.clickByPointPercent(80,95);
System.out.println(wxDriver.getWindowSize().getWidth());
System.out.println(wxDriver.getWindowSize().getHeight());
wxDriver.getScreenShotAs();
String viewMoreTmplPath = "E:\\projects\\uiauto-miniprogram\\images\\templates\\openIqiyiBanner.png";
// wxDriver.findElementByImg(viewMoreTmplPath).click();
wxDriver.goBack();
wxDriver.pause(2);
wxDriver.goHome();
wxDriver.pause(2);
wxDriver.closeMiniProgram();
wxDriver.quit();
}
}
4.3 安卓常用操作接口Device
封裝安卓設備的常用方法
import com.iqiyi.qa.device.AndroidDevice;
public class TestDevice {
public static void main(String[] args) throws Exception{
Device device = new AndroidDevice();
//全屏截圖
device.getScreenShotAs("E:\\1.png");
//執(zhí)行adb shell 命令
String output = device.executeShellCommand("wm size");
//獲取當前的ACTIVITY
String act = device.getCurrentActivity();
if (!device.isAppInstall("adbkeyboard")){
device.installPackage("E:\\projects\\uiauto-miniprogram\\src\\main\\resources\\ADBKeyboard.apk");
}
//判斷是否安裝adb輸入法
boolean isExist = device.isAdbKeyboardInstall();
//安裝adb輸入法
device.installPackage("ADBKeyboard.apk");
//設置adb輸入法
device.setAdbkeyboard();
//adb輸入中文
device.inputText("小程序");
//獲取手機屏幕尺寸
Dimension d = device.getWindowSize();
System.out.println(device.dimension.getHeight());
System.out.println(device.dimension.getWidth());
//點擊坐標
device.clickByPoint(500, 500);
//點擊百分比坐標
device.clickByPointPercent(95, 95);
device.inputText("愛奇藝視頻");
AndroidDevice.quit();
}
}
4.4 命令行操作接口Command
執(zhí)行一些cmd或者shell命令,并拿到返回結果
import com.iqiyi.qa.command.Command;
public class TestCommand {
public static void main(String[] args) throws Exception{
String cmdString = "adb shell dumpsys activity top";
Command command = new Command(cmdString);
try {
command.execute();
String output = command.getStdOut();
String[] outputLines = output.split("\n");
for (int i=0;i<outputLines.length;i++) {
String line = outputLines[i];
if (line.contains("ACTIVITY")) {
String pid = line.split("pid=")[1].replace("\n", "");
Command command1 = new Command("adb shell ps " + pid);
command1.execute();
String output1 = command1.getStdOut();
String[] outputArray = output1.replace("\n", "").split(" ");
String processName = outputArray[outputArray.length-1];
System.out.println(processName);
break;
}
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}
4.5 圖像識別AirCv
簡單的opencv封裝围来,根據給定的模板圖片跺涤,在目標圖片(一般是屏幕截圖)中進行匹配,匹配成功后返回對應的坐標點监透,然后可以根據坐標點桶错,可用device接口對應的操作
import com.iqiyi.qa.aircv.AirCV;
public class TestCv {
private static float defaultDegree = 0.9f;
public static void main(String[] args) throws Exception{
String screenShotPath = "E:\\projects\\uiauto-miniprogram\\images\\screenshots\\2019-02-26\\20190226-140934798.png";
String templatePath = "E:\\projects\\uiauto-miniprogram\\images\\templates\\openIqiyiBanner.png";
//在screenShotPath圖片上查找templatePath模板圖片,相似度最小90%胀蛮,返回匹配的坐標
AirCV.getMatchTemplateLoc(screenShotPath, templatePath, 0.9f);
}
}