Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
AppiumÔÚAndroid UI²âÊÔÖеÄÓ¦ÓÃʵ¼ù
 
×÷ÕߣºØýÃû À´Ô´£ºsegmentfault ·¢²¼ÓÚ£º 2016-7-26
  2395  次浏览      27
 

Android ²âÊÔ¹¤¾ßÓë Appium ¼ò½é

Appium ÊÇÒ»¸ö C/S ¼Ü¹¹µÄ£¬Ö§³Ö Android/iOS Native, Hybrid ºÍ Mobile Web Apps µÄ²âÊÔ¿ò¼Ü£¬Óë²âÊÔ³ÌÐòͨ¹ý Selenum Webdriver ЭÒéͨѶ¡£Webdriver µÄºÃ´¦ÊÇͨ¹ý HTTP RPC µÄ·½Ê½µ÷Óà Server ÉϵĹý³Ì£¬±àд²âÊԽű¾²»ÊÜÓïÑÔµÄÏÞÖÆ£¬ÎÞÂÛÊÇ Python, Java, NodeJS ¾ù¿ÉÒÔ·½±ãµÄ±àд²âÊÔ¡£±¾ÎÄÖн«Ê¹Óà Python ½øÐбà³Ì¡£

ÆðÒòÊÇÒòΪÊг¡²¿µÄͬÊÂÅ×À´ÈçÏÂÐèÇó£ºÅúÁ¿Ìí¼ÓһЩ΢ÐźÃÓÑ¡£Ö±½ÓץȡÇëÇó½øÐÐÖØ·ÅµÄ·½·¨ÊDz»¿¿Æ×µÄ£¬Î¢ÐÅÓë·þÎñ¶ËµÄͨѶ¾ù¼ÓÃÜ£¬Pass¡£¿¼ÂÇʹÓà xposed µÈ¿ò¼Ü hook Ïà¹Øº¯Êý½øÐвÙ×÷¡£µ«ÊÇ xposed ÐèÒªÔ½Óü£¬ÇÒ¿ª·¢¸´ÔÓ£¬Pass¡£ºóÀ´Ïëµ½ÁËʹÓà UI ²âÊÔ¹¤¾ß½øÐÐÄ£Äâ²Ù×÷£¬¿ª·¢½ÏΪ¼òµ¥¡£

Android UI ²âÊÔ¹¤¾ßÓкܶàÖÖ£¬Èç Monkey, UIAutomator, Selendroid, Robotium µÈ¡£ÆäÖÐ UIAutomator, Monkey, Selendroid ¾ùΪ·ÇÇÖÈëʽµÄ UI ²âÊÔ£¬Ò²¾ÍÊDz»ÐèÒªÐÞ¸ÄÔ´´úÂ룬ֻҪ°²×°ÁËÄ¿±ê³ÌÐò¾Í¿ÉÒÔ½øÐвâÊÔ¡£Robotium ÐèÒªÓëÔ´Âëһͬ±àÒë²âÊÔ¡£Appium ʵ¼ÊÉϾÍÊÇÒ»¸ö²âÊÔ¹¤¾ßµÄͳһµ÷¶ÈÈí¼þ£¬½«²»Í¬µÄ·ÇÇÖÈëʽ²âÊÔ¹¤¾ßÕûºÏÔÚÒ»Æð£¬¶ÔÍâÌṩͳһµÄ API¡£ÔÚ Android 2.3 ÒÔǰµÄ°æ±¾£¬Appium »áµ÷Óà Selendroid £¬Ö®ºóµÄ°æ±¾»áÖ±½ÓʹÓà UIAutomator£¬iOS ÏÂʹÓà UIAutomation¡£Appium »¹Ö§³Ö FirefoxOS µÄ UI ²âÊÔ¡£

°²×° Appium

¹ÙÍø¸ø³öÁËÃüÁîÐÐϵݲװ·½·¨¡£µ«Êµ¼ÊÉÏ Appium ÓÐ GUI °æ±¾£¬¸üÊʺÏÔÚ Windows/MacOS ÏÂʹÓá£Windows ÏÂÐèÒª°²×° .NET Framework¡£

> brew install node      # get node.js 
> npm install -g appium # get appium
> npm install wd # get appium client
> appium & # start appium
> node your-appium-test.js

Appium ÐèÒªÒÀÀµ Android SDK ±àÒëÔÚÊÖ»ú¶ËÔËÐеÄÁ½¸ö²å¼þ£¬Òò´ËÐèÒªÊ×ÏȰ²×°ÏàÓ¦µÄ Android SDK °æ±¾¡£ÕâÀïÖ±½ÓʹÓÃÁË Android Studio ÖÐ×Ô´øµÄ SDK Manager¡£ÔÚ SDK Manager ÖÐÑ¡ÔñºÍ²âÊÔ»úÏà¶ÔÓ¦µÄ SDK Platform ºÍ½ÏÐ嵀 Build-tools£¬Èç¹ûÐèҪʹÓÃÄ£ÄâÆ÷²âÊÔ»¹Òª×°¶ÔÓ¦µÄ ARM/x86 System Image£¬ÒÔ¼° Intel HAXM Installer£¬ÓÃÓÚ¼ÓËÙ x86 ÐéÄâ»ú¡£Appium ʹÓà adb À´ÓëÄ¿±ê»úÆ÷ͨѶ£¬Òò´Ë¶ÔÓÚÕæ»úºÍÄ£ÄâÆ÷²Ù×÷¼¸ºõ¶¼ÊÇÏàͬµÄ£¬ÈçºÎ½¨Á¢Ä£ÄâÆ÷Ôڴ˲»ÔÙ׸Êö¡£

°²×°Íê³ÉºóÐèÒªÔÚ Appium GUI ÖÐÅäÖà Android SDK Ŀ¼£¬ËæºóÑ¡Ôñ Android£¬µã»÷ Launch ¾Í¿ÉÒÔÆô¶¯ Appium Server¡£

Appium Server ĬÈÏ»á¼àÌý http://localhost:4723 £¬ÓÃÓÚ RPC ͨѶ¡£ÏÂÃæÎÒÃǾͿÉÒÔ´ò¿ªÊìϤµÄ±à³Ì»·¾³£¬±àд UI ²âÊÔÓÃÀýÁË¡£ÕâÀïʹÓà Python ½øÐбàд£¬ÐèÒªÏȰ²×° Appium µÄ Python Client £¬È»ºóÔÙ python ÖÐʹÓà appium.webclient ¾Í¿ÉÒÔÁ¬½Ó Appium serverÁË¡£

pip install Appium-Python-Client 

ʹÓà Appium ½øÐÐ UI ¿ØÖÆ

¸ù¾Ý×¢ÊÍÐÞ¸ÄÏàÓ¦ÊôÐÔºó¼´¿ÉÔËÐвâÊÔ¡£ÊÖ»úÐèÒª´ò¿ª ADB µ÷ÊÔ£¬Ö´ÐÐÍêÒÔÏ´úÂëºó£¬Appium »áÔÚÊÖ»úÉϰ²×° Appium Settings ºÍ Unlock Á½¸ö³ÌÐò£¬Ëæºó΢ÐŻᱻÆô¶¯¡£

from appium import webdriver 

desired_caps = {}

desired_caps['platformName'] = 'Android' #²âÊÔÆ½Ì¨

desired_caps['platformVersion'] = '5.1' #ƽ̨°æ±¾

desired_caps['deviceName'] = 'm3_note' #É豸Ãû³Æ£¬¶àÉ豸ʱÐèÇø·Ö

desired_caps['appPackage'] = 'com.tencent.mm' #app packageÃû

desired_caps['appActivity'] = '.ui.LauncherUI' #appĬÈÏActivity

dr = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) #Æô¶¯Remote RPC

Selenum Webdriver ʹÓÃÁËÒ»ÖÖÀàËÆÓÚ JS ÖÐµÄ DOM Ä£Ð͵ķ½·¨À´Ñ¡ÔñÒ³ÃæÖеÄÔªËØ¡£dr Ϊµ±Ç°ÕýÔڻµÄ activity ¶ÔÏ󣬿ÉÒÔʹÓà findElementByXXX µÄ·½·¨À´»ñÈ¡ Activity ÖеÄÔªËØ¡£ËùÓÐ Element ºó´ø s µÄº¯Êý£¬¾ù»ñµÃËùÓÐÆ¥ÅäµÄÔªËØ£¬²»´ø s µÄº¯Êý»ñµÃµÚÒ»¸öÆ¥ÅäµÄÔªËØ¡£

²éѯº¯Êý

1. findElement(s)ByName

ÔÚ Android Öлù±¾Ã»Óá£Android UI ûÓÐ Name Õâ¸öÊôÐÔ¡£ÓÐ˵¿ÉÒÔʹÓà text Öµ»ñÈ¡¡£µ«ÎÒ²¢Ã»Óгɹ¦

2. findElement(s)ByClassName

ͨ¹ýÀàÃûÀ´»ñÈ¡ÔªËØ£¬Ó÷¨ÈçÏ£º

item_list = dr.find_elements_by_class_name("android.widget.LinearLayout") 
item_list[2].click()

3. findElementById

ͨ¹ý resource_id À´»ñÈ¡ÔªËØ£¬Ã¿¸ö Activity Öж¼ÊÇΨһµÄ£¬Ó÷¨ÈçÏÂ

t = dr.find_element_by_id("com.tencent.mm:id/f7") 
t.send_keys(wechatId)

4. findElement(s)ByAccessbiltiyId

ÔÚ Android ÉÏ AccessbilityID ʵ¼Ê¾ÍÊÇ contentDescription ¡£Õâ¸öÊôÐÔÊÇΪÁË·½±ãÊÓÁ¦ÊÜËðÈËʿʹÓÃÊÖ»úËùÉèÖ᣿ªÆô TTS ºóϵͳ»áÀʶÁÏà¹Ø¿Ø¼þµÄ contentDescription¡£

5. findElement(s)ByXPath

ͨ¹ý XML Path ÃèÊöÀ´Ñ°ÕÒÔªËØ¡£ÎÒûÓгɹ¦µÄ»ñÈ¡µ½£¬¿ÉÄÜÊÇ XPath дµÄÓÐÎÊÌâ¡£

s = dr.find_element_by_xpath("//android.widget.TextView[contains(@text,'ËÑË÷')]") 
s.click()

6. findElementByAndroidUIAutomator

ͨ¹ý UIAutomator µÄÑ¡ÔñÆ÷À´»ñÈ¡ÔªËØ¡£ÒòΪ Appium ÔÚ Android ÉÏʵ¼ÊÊǵ÷ÓÃµÄ UIAutomator£¬ËùÒÔ¿ÉÒÔͨ¹ý UIAutomator µÄÑ¡ÔñÆ÷À´Ñ¡ÔñÔªËØ¡£

el = dr.find_element_by_android_ui_automator("new UiSelector().text(\"ËÑË÷\")") 
el.click()

²Ù×÷º¯Êý

²Ù×÷º¯ÊýÓÃÓÚ²Ù×÷Ñ¡¶¨µÄÔªËØ£¬Óкܶ࣬ÒÔϽöÁоټ¸¸ö£¬¸ü¶àµÄÇë²éÔÄÊֲᡣ

click

send_keys

clear

²éѯº¯Êý·µ»ØµÄÔªËØ¶ÔÏó¿ÉÒÔÏñ JS ÖÐµÄ dom ÔªËØÒ»Ñù£¬¼ÌÐøÊ¹Óòéѯº¯ÊýÀ´Ñ¡¶¨Æä×ÓÔªËØ¡£ÓÃÀýÈçÏ¡£

search = dr.find_element_by_id("com.tencent.mm:id/aqw")
.find_element_by_class_name("android.widget.RelativeLayout")

search.click()

ÈçºÎÈ·¶¨²éѯ¹æÔò

Á˽âÁËÏà¹ØµÄº¯Êýºó£¬ÏÂÃæ¾ÍÓ¦¶Ô UI ½øÐж¨Î»ÁË¡£Èç¹ûÊÇ×Ô¼ºÍŶӿª·¢µÄ³ÌÐò£¬ÍƼöÈÿª·¢Í¬Ñ§ÔÚËùÓеĿռäÉ϶¼Ìí¼Ó resource_id ½øÐоø¶Ô¶¨Î»¡£Èç¹ûÅöµ½Ã»ÓÐ̸¼Û resource_id µÄÔªËØ£¬ÄǾÍҪʹÓñðµÄ°ì·¨½øÐж¨Î»ÁË¡£

1. UI Automator Viewer

UI Automator Viewer ÊÇ Android ¹Ù·½µÄ UI ¶¨Î»¹¤¾ß£¬Î»ÓÚ sdk/tools Ï¡£ÔËÐкó»á´ò¿ª viewer ½çÃæ¡£µã»÷»ñÈ¡°´Å¥¼´¿É»ñÈ¡µ±Ç°ÕýÔÚÔËÐÐµÄ Activity µÄ UI ½á¹¹¡£

2. AppiumDriver getPageSource

AppiumDriver(Client) ¿ÉÒԺܷ½±ãµÄ»ñµÃµ±Ç°ÕýÔÚÔËÐÐµÄ Activity µÄ UI ÃèÊö£¬Ëæºó¿É¸ù¾Ý·µ»ØµÄ XML ÎĵµÀ´Ñ°ÕÒÔªËØ¡£

È·¶¨ÔªËØÎ»Öú󣬼´¿É¸ù¾ÝǰÊöµÄ Find ·½·¨À´²éÕÒ/Ñ¡ÔñÔªËØ

±àдÍêÕûµÄ²âÊÔ´úÂë

ÕýÈ·µÄ»ñÈ¡ÔªËØÖ®ºó±ã¿ÉÒÔ»ñÈ¡ÔªËØÏà¹ØµÄÐÅÏ¢£¬ËæºóʹÓø÷ÓïÑÔ³£ÓõIJâÊÔ¿ò¼Ü±àд²âÊÔ¼´¿É£¬Èç Java µÄ JUnit£¬Nodejs µÄ Mocha µÈ¡£

ÕâÀïÎÒʹÓà Appium Ö÷ÒªÊÇΪÁËÄ£ÄâÓû§µã»÷Ìí¼Ó΢ÐźÃÓÑ£¬ËùÒÔÍêÕûµÄ³ÌÐò²¢Ã»ÓÐʹÓõ½²âÊÔ¿ò¼Ü¡£Ïà¹ØµÄ UI ÔªËØ»ñÈ¡/²Ù×÷·½·¨¹©´ó¼Ò²Î¿¼¡£

# coding:utf-8 
from appium import webdriver
from time import sleep


def addFriend(dr, id, dryRun=False):
succ = False
wechatId = str(id)
dr.find_element_by_accessibility_id(r"¸ü¶à¹¦Äܰ´Å¥").click()
item_list = dr.find_elements_by_class_name("android.widget.LinearLayout")
try:
item_list[2].click()
except:
print "Error! in item list len"
return succ
el = dr.find_element_by_class_name("android.widget.ListView")
item_list = el.find_elements_by_class_name("android.widget.LinearLayout")
try:
item_list[1].click()
except:
print "Error! in item list len"
return succ
t = dr.find_element_by_id("com.tencent.mm:id/f7")
t.send_keys(wechatId)
search = dr.find_element_by_id("com.tencent.mm:id/aqw")
.find_element_by_class_name("android.widget.RelativeLayout")
search.click()
try:
freq = dr.find_element_by_id('com.tencent.mm:id/aqq')
assert freq.text == u"²Ù×÷¹ýÓÚÆµ·±£¬ÇëÉÔºóÔÙÊÔ¡£"
print "Frequency too high! Sleep 300s"
sleep(60)
return succ
except:
pass

try:
dr.find_element_by_id('com.tencent.mm:id/a8x').click()
addBtn = dr.find_element_by_id('com.tencent.mm:id/eu')
if not dryRun:
addBtn.click()
succ = True
print "Success Send Requests:" + wechatId
except:
print "No Such User Or Already a Friend:" + wechatId

while True:
try:
dr.find_element_by_id('com.tencent.mm:id/fb').click()
except:
try:
dr.find_element_by_id('com.tencent.mm:id/f4').click()
except:
break
return True

def resetActivity(dr, desired_caps):
dr.start_activity(desired_caps['appPackage'], desired_caps['appActivity'])

desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = 'm3_note'
desired_caps['appPackage'] = 'com.tencent.mm'
desired_caps['appActivity'] = '.ui.LauncherUI'
print "Trying connect to phone..."
dr = {}
try:
dr = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
except Exception, e:
print "Cannot Connect to phone :", e
exit()
print "Successfully connect to phone."
print "Reading friend list..."
friendList = []
fp = open("friends.txt")
line = fp.readline().strip()
while line:
friendList.append(line)
line = fp.readline().strip()
print "Finish reading friends. Total: " + str(len(friendList))
print "Wait for Wechat's splash screen...."
for i in range(0, 10):
print 10 - i
sleep(1)
succ_list = []
fail_list = []
for i in friendList:
try:
succ = addFriend(dr, i, dryRun=False)
if succ:
succ_list.append(i)
else:
fail_list.append(i)
except:
fail_list.append(i)
resetActivity(dr, desired_caps)

print "Succeed List:"
print "\n".join(succ_list)
print "Failed List:"
print "\n".join(fail_list)

dr.close()
   
2395 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ