Mac 上使用 Shell 指令碼 + adb shell 實現簡單的 Android 模擬點選自動化測試
需求
在 A 介面,點選跳轉到 B 介面(該介面會執行一些業務),再點選返回鍵出現 Dialog 彈窗,點選確認退出按鈕,返回 A 介面。不斷迴圈。
思路
一開始想到的就是按鍵精靈,下了 mac 版使用後發現功能太不完善,於是試了試 Windows 版,實在是操作不習慣。在搜尋資料過程中瞭解到還可以使用 adb 來實現模擬裝置操作,那肯定是寫程式碼更順手啊,配合使用指令碼重複輸入命令,就能實現簡單的自動化重複操作了。
實現
模擬裝置操作
常用的按鈕都有特定的 keyevent 代號,例如返回鍵代號4(其他按鍵可參考文末文章中介紹),模擬返回鍵的點選只需要在命令列中輸入 adb shell input keyevent 4
模擬點選螢幕中某點的命令是 adb shell input tap x y
,(x,y)是相應的座標點,這就涉及到了對座標點的計算。巧的是,正好之前寫了個塗鴉的 demo (Github 地址,App 下載地址),可以使用該 demo 來除錯點選的座標點是否符合我們的期望。
不同機型解析度不同,座標點位置肯定是不一樣的。比較理想的結果應該是我們輸入固定的座標點,然後程式碼裡自動獲取機型的螢幕密度等資訊並自動轉換。這裡為了快速開發出這個小功能,就簡單使用了最耿直的不同機型設定不同座標的方法 ╮(╯▽╰)╭。
所以單步實現上述需求的命令就是:
adb shell input tap 200 300 //點選(200,300)座標點(假設該點就是跳轉按鈕所在位置)
adb shell input keyevent 4 //點選退出,彈出是否確認退出 Dialog
adb shell input tap 500 600 //點選(500,600)座標點(假設該點就是確認退出按鈕所在位置)
一次模擬進出介面的測試就完成了。
自動化
在命令列視窗輸入命令便可實現單步操作,那想要自動化實現整個流程自然就是要做到自動輸入命令。Shell 指令碼可以實現這樣的功能。後面要做的就簡單了:確定需要實現的功能 –> 學習相應的 Shell 指令碼語法 –> 編寫指令碼。
需要的功能
Shell 指令碼的第一行必須為 #!/bin/bash
sh 指令碼名.sh
執行指令碼。
列印 log(時間、迴圈次數等)
echo
在命令列輸出一段日誌。例如 echo "Hello World"
。
列印當前時間:
time=$(date +%m-%d--%H:%M:%S)`
echo "時間:$time
簡單的互動
例如輸入不同機型代號。read -p "What's your name?" myName
該語句會將使用者的輸入儲存在 myName
變數中,再根據變數做判斷處理。使用變數在變數名前加 $
符號即可。例如:
read -p "What's your name?" myName
echo "Hi, $myName"
定義變數
直接使用 變數名=值 方式定義。要注意變數名和值與 =
號中間不要有空格,且變數命名要符合規範:
- 首個字元必須為字母(a-z,A-Z)
- 中間不能有空格,可以使用下劃線(_)
- 不能使用標點符號
- 不能使用bash裡的關鍵字(可用help命令檢視保留關鍵字)
if else 判斷
read -p "What's your name?" myName
if [ "$myName" = "yazhi" ];then
echo "I know you!"
else
echo "Nice to see you!"
fi
這裡要注意 [
和]
符號前後的空格,少了空格會提示語法錯誤,語句最後要跟 fi
。
如果有多個條件:
if [ "$myName" = "yazhi" ] || [ ! -n "$myName" ];then //如果輸入了"yazhi",或者沒有輸入
...
休眠(業務是耗時的)
sleep 5
:休眠5秒
While 迴圈
while [ "1" = "1" ] #死迴圈
do
echo "do something"
done
基本用得到的語法就上述這些,最後貼一下我的指令碼:
#!/bin/bash
echo "開始自動化進出教室"
quitTime=10
read -p "課程資料量是否很大?預設是(y/n) : " waitTime
if [ "$waitTime" = "y" ] || [ ! -n "$waitTime" ];then
quitTime=7 #資料量多的課程
echo "當前課程資料量較大"
elif [ "$waitTime" = "n" ]; then
quitTime=5 #資料量少的課程
echo "當前課程資料量較小"
else
echo "輸入錯誤"
exit 0
fi
enterRoomX=0 #進入教室按鈕座標
enterRoomY=0
quitRoomX=0 #確認退出按鈕座標
quitRoomY=0
read -p "選擇機型:1(華為M2平板),2(小米平板2),3(Nexus5),4(紅米2A) 預設2 :" phone
if [ "$phone" = "1" ] || [ ! -n "$phone" ];then
echo "當前選中機型:華為M2平板"
enterRoomX=400
enterRoomY=500
quitRoomX=1300
quitRoomY=610
elif [ "$phone" = "2" ];then
echo "當前選中機型:小米平板2"
enterRoomX=400
enterRoomY=640
quitRoomX=1480
quitRoomY=820
elif [ "$phone" = "3" ];then
echo "當前選中機型:Nexus5"
enterRoomX=200
enterRoomY=900
quitRoomX=1200
quitRoomY=610
elif [ "$phone" = "4" ];then
echo "當前選中機型:紅米2A"
enterRoomX=200
enterRoomY=600
quitRoomX=1000
quitRoomY=410
else
echo "錯誤:未知機型"
exit 0
fi
read -p "是否測試學生端進入教室?預設是(y/n) :" isStudent
if [ "$isStudent" = "y" ] || [ ! -n "$isStudent" ];then
echo "即將測試學生端"
elif [ "$isStudent" = "n" ];then
enterRoomX=$(($enterRoomX + 400)) #資料量少的課程、
echo "即將測試旁聽端"
else
echo "輸入錯誤"
exit 0
fi
echo "開始自動化進出教室"
num=1
while [ "1" = "1" ] #死迴圈
do
time=$(date +%m-%d--%H:%M:%S)
echo "時間:$time 第 $num 次進入教室"
num=$(($num + 1))
adb shell input tap $enterRoomX $enterRoomY #進入教室
sleep $quitTime #進教室休眠時間
adb shell input keyevent 4 #退出教室
sleep 1
adb shell input tap $quitRoomX $quitRoomY #退出教室確認
sleep 4
done