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() |
|