дÔÚÇ°Ãæ
Ñо¿iOSµÄ×Ô¶¯»¯²âÊÔÒ²ÓÐЩÈÕ×ÓÁË£¬¸Õ¿ªÊ¼µÄʱºò£¬Ò»Ö±¿àÓÚÕÒ²»µ½Ê²Ã´ºÃµÄ×ÊÁÏ£¬Ö»ÄÜ´ÓAppleµÄ¹ÙÍø²éÔÄÏà¹ØµÄAPIÎĵµ£¬Ö»¿Éϧ£¬Apple¶Ô¿ª·¢ÕßÀ´ËµÊµÔÚÊDz»ÔõôÓѺã¬ÎĵµÐ´µÃÏ൱µÄ´ÖÂÔ£¬¶ÔÓÚ³õѧÕßÀ´ËµÓÐÒ»¶¨µÄÄѶȡ£
±¾À´ÊÇ´òËã×Ô¼º¶¯ÊÖдһƪ¹ØÓÚiOSµÄUI×Ô¶¯»¯²âÊÔµÄÈëÃż¶±ðµÄ½éÉÜÐÔÎĵµµÄ£¬µ«ÏëÆðÀ´ºóÃæÔÚ¾ßÌå½â¾öһЩÎÊÌâµÄʱºò£¬ÊÕ²ØÒ»ÆªºÜºÃµÄBlog£¬ºÜÈ«ÃæµØ½éÉÜÁËÈçºÎʹÓÃUIAutomationµÄJavaScript
Libraries×öiOS³ÌÐòµÄ×Ô¶¯»¯²âÊÔ¡£Èç¹û×÷ÕßÔçµã¿´µ½ÕâÆªÎÄÕ£¬Ó¦¸ÃÒªÉÙ×ßһЩÍä·£¬ÕâÀïûÓд´ÒâÐÔµÄËüËû·Òë³ÉÖÐÎÄ£¬Ï£Íû¶ÔÄãÃÇÓÐһЩ°ïÖú¡£
¿ìËÙÈëÃÅ
×Ô¶¯»¯²âÊÔ´úÂë¿ÉÒÔ¡°ÔÚÄãµÄ˯×ŵÄʱºò¡±ºÜºÃµØ°ïÄã²âÊÔÄãµÄÓ¦ÓóÌÐò¡£Ëü¿ÉÒÔÈÃÄãÄܹ»¿ìËٵظú×ÙÄã³ÌÐòÖеĻعéºÍÐÔÄÜ·½ÃæµÄÎÊÌ⣬ÕâÑùÄã¾Í²»Óõ£ÐÄÄãÐÂÔöµÄ¹¦ÄÜ»áÓ°Ïìµ½Äã֮ǰÒѾÍê³É¿ª·¢µÄ³ÌÐòÁË¡£
Ëæ×ÅiOS4.0µÄ·¢²¼£¬Æ»¹û¹«Ë¾Í¬Ê±·¢²¼ÁËÒ»¸öÃûΪUIAutomationµÄ²âÊÔ¿ò¼Ü£¬Ëü¿ÉÒÔÓÃÀ´ÔÚÕæÊµÉ豸ºÍiPhoneÄ£ÄâÆ÷ÉÏÖ´ÐÐ×Ô¶¯»¯²âÊÔ¡£µ«¹Ù·½¹ØÓÚUIAutomationµÄÎĵµÏ൱µÄÓÐÏÞ£¬ÔÚÍøÂçÉÏҲûÓÐÌ«¶àµÄ×ÊÔ´¿ÉÒÔ²éÕҵġ£±¾ÎĽ«ÏòÄãչʾÄãÈçºÎ½«UIAutomationÕûºÏµ½ÄãµÄ¹¤×÷Á÷³Ìµ±ÖÐÈ¥¡£
×÷Ϊ»ù´¡ÖªÊ¶µÄ×¼±¸£¬Äã¿ÉÒÔÏÈ¿´Ò»ÏÂÆ»¹û¹«Ë¾¹ØÓÚUIAutomationµÄÎĵµ£¬ÁíÍ⻹ÓÐһƪ¿ìËÙÈëÃŵĽéÉÜÆ»¹ûInstrumentsµÄÎĵµÒ²ÖµµÃ¿´¿´£¬µ±È»£¬Èç¹ûÄãÓÐÒ»¸öÃâ·ÑµÄApple¿ª·¢ÕßÕ˺ŵϰ£¬Äã¿ÉÒÔ¿´Ò»ÏÂWWDC
2010 - Session 306 ¨C ʹÓÃInstruments½øÐÐÓû§½çÃæ×Ô¶¯»¯²âÊÔµÄ»ÃµÆÆ¬»òÕßÊÓÆµ¡£
³ý´ËÖ®Í⣬°üÀ¨ÔÚXcodeÖеÄOCUnit²âÊÔ¿ò¼ÜÒ²¿ÉÒÔÓÃÀ´ÎªÄãµÄÓ¦ÓóÌÐò±àдµ¥Ôª²âÊÔ¡£
1. ÄãµÄµÚÒ»¸öUIAutomation²âÊԽű¾
UIAutomationµÄ¹¦ÄܲâÊÔ´úÂëÊÇÓÃJavascript±àдµÄ¡£UIAutomationºÍAccessibilityÓÐ×ÅÖ±½ÓµÄ¹ØÏµ£¬Ä㽫Óõ½Í¨¹ý±êÇ©ºÍÖµµÄ·ÃÎÊÐÔÀ´»ñµÃUIÔªËØ£¬Í¬Ê±Íê³ÉÏàÓ¦µÄ½»»¥²Ù×÷¡£
ÏÂÃæÈÃÎÒÃÇÀ´±àдÎÒÃǵĵÚÒ»¶Î²âÊÔ´úÂë¡£
ʹÓÃiOSÄ£ÄâÆ÷
1. ÏÂÔØÊ¾ÀýÓ¦ÓóÌÐòTestAutomation.xcodeproj£¬²¢´ò¿ªËü¡£Õâ¸öÏîÄ¿ÊÇÒ»¸öºÜ¼òµ¥µÄ°üº¬2¸ötabµÄtabbarÓ¦ÓóÌÐò¡£
2. È·±£Ñ¡ÖÐÈçÏÂͼËùʾµÄ¡°TestAutomation > iPhone 5.0 Simulator¡±Ä£Ê½£¨»òÐíÄãÒѾÇл»³É5.1ÁË£¬Òò´ËËü¿ÉÄÜÊÇiPhone5.1Ä£ÄâÆ÷£©¡£

3. Æô¶¯Instruments(Product > Profile)£¬»òÕßͨ¹ý?I¡£
4. Ñ¡Ôñ×ó±ßµÄiOS Simulator£¬È»ºóÔÙÑ¡ÔñAutomationÄ£°å£¬È»ºóµã»÷¡°Profile¡±¡£

5. Instruments¾ÍÒѾÆô¶¯ºÃºó£¬È»ºóÖ±½Ó¿ªÊ¼Â¼ÖÆÁË¡£ÕâÀïÏÈÍ£Ö¹Â¼ÖÆ£¬£¨ºì°ü°´Å¥»òÕß?R£©¡£

6. ÔÚ×ó±ßµÄScripts´°¿Ú£¬µã»÷¡°Add > Create¡±´´½¨ÐµĽű¾¡£

7. Ôڽű¾±à¼Æ÷ÀÊäÈëÏÂÃæµÄ´úÂë
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
target.logElementTree();
|

8. ÖØÐÂÔËÐÐÕâ¶Î½Å±¾?R£¨²»ÐèÒª±£´æ£©¡£½Å±¾ÅÜÆðÀ´ºó£¬Äã¿ÉÒÔÔÚÈÕÖ¾´òÍêºóÍ£Ö¹Ëü¡£

ÔÞÒ»¸ö£¡ÎÒÃǾÍÕâÑùÍê³ÉÁËÎÒÃǵĵÚÒ»¸öUIAutomation²âÊÔÓÃÀý¡£
ʹÓÃiOSÉ豸
Äã³ýÁ˽«ÄãµÄ²âÊÔÓÃÀýÔËÐÐÄ£ÄâÆ÷ÉÏ£¬Ò²¿ÉÒÔ½«ËüÔËÐÐÔÚÒ»¸öÕæÊµµÄÉ豸ÉÏ¡£²»¹ý£¬×Ô¶¯»¯²âÊÔÓÃÀýÖ»ÄÜÔËÐÐÔÚÖ§³Ö¶àÈÎÎñµÄ£ºiPhone
3GS£¬iPad£¬iOS > 4.0µÈÉ豸ÉÏ¡£Òź¶µÄÊDz»¹ÜiPhone 3GµÄϵͳ°æ±¾ÊÇʲô£¬¶¼²»Ö§³Ö¡£
ÏÂÃæÊÇÈçºÎ²Ù×÷£º
1. ͨ¹ýUSB½Ó¿ÚÁ¬½ÓÉÏÄãµÄiPhone¡£
2. Ñ¡Ôñ ¡°TestAutomation > iOS Device¡±Ä£Ê½¡£
3. È·±£Developper profileÉèÖóÉReleaseģʽ£¨¶ø²»ÊÇAd-Hoc Distribution
profile£©¡£Ä¬ÈÏÇé¿öÏ£¬profilingÊÇÉèÖóÉReleaseģʽµÄ£¨ÒòΪûÓбØÒª½«profileÉèÖóÉDebugģʽ£©¡£

4. Æô¶¯²âÊÔ (I)
5. ºóÃæµÄ²½ÖèÇë²Î¿¼Ç°ÃæÄ£ÄâÆ÷²¿·Ö¡£
2. ´¦ÀíUIAElementºÍÔªËØ¿É·ÃÎÊÐÔ£¨Accessibility£©
UIAElement²ã´Î½á¹¹
AccessibilityºÍUIAutomationÓÐÃÜÇеÄÁªÏµ£ºÈç¹ûÒ»¸ö¿Ø¼þµÄAccessibilityÊÇ¿ÉÒÔ±»·ÃÎʵģ¬Äã¾Í¿ÉÒÔÉèÖúͶÁÈ¡ËüµÄÖµ£¬×÷Ïà¹ØµÄ²Ù×÷£¬¶øµ±Ò»¸ö¿Ø¼þµÄAccessibility²»¿É¼ûʱ£¬Äã¾ÍûÓа취ͨ¹ýautomation·ÃÎÊËü¡£
Äã¿ÉÒÔͨ¹ýInterface Builder£¬»òÕßͨ¹ýÔÚ³ÌÐòÀïÉèÖÃisAccessibilityElementÊôÐԵķ½Ê½À´ÉèÖÃÒ»¸ö¿Ø¼þµÄAccessibility»òÕ߿ɱ»×Ô¶¯»¯¡£µ±ÄãÉèÖÃcontainer
view£¨¼´£ºÒ»¸öÊÓͼ°üº¬ÆäËüµÄUIKitÔªËØ£©µÄaccessibilityʱ£¬Äã±ØÐë×¢Òâ¡£ÄãÉèÖÃÁËÕû¸öViewµÄaccessibility½«»á¡°Òþ²Ø¡±ËüµÄ×ÓÊÓͼµÄaccessibility£¬ÀýÈ磺ÔÚʾÀýÏîÄ¿ÖУ¬Äã²»Äܽ«outletÊÓͼÉèÖóɿɷÃÎʵ쬷ñÔòËüËùÓеÄ×ӿؼþ½«¶¼²»¿ÉÒÔ·ÃÎÊÁË¡£ÔÚÈκÎʱºò£¬logElementTree¶¼ÊÇÄãÖÒʵµÄÅóÓÑ£ºËü½«µ±Ç°½çÃæµÄËùÓпɱ»·ÃÎʵÄÔªËØ¶¼´òÓ¡ÔÚÈÕÖ¾Àï¡£
ÿһ¸ö¿ÉÒÔ±»·ÃÎʵÄUIKit¿Ø¼þ¶¼¿ÉÒÔÓÃÒ»¸öJavascript¶ÔÏóÀ´ÃèÊö£¬Ëü¾ÍÊÇÒ»¸öUIAElement¡£UIAElementÓм¸¸öÊôÐÔ£ºname,
value, elements, parent¡£ÄãµÄÖ÷´°¿Ú°üº¬ºÜ¶àµÄ¿Ø¼þ£¬ËüÃÇÊÇÒÔUIKit²ã´ÎµÄ·½Ê½¶¨ÒåµÄ£¬ÕâЩUIKit²ã´Î½á¹¹¶ÔÓ¦µÄÊÇUIAElementµÄ²ã´ÎÊ÷¡£ÀýÈç£ºÇ°ÃæµÄ²âÊÔ´úÂëÖУ¬Í¨¹ýµ÷ÓÃlogElementTree£¬ÎÒÃÇ¿ÉÒԵõ½ÈçÏÂÃæËùʾµÄÊ÷½á¹¹£º
+- UIATarget: name:iPhone Simulator rect:{{0,0},{320,480}}
| +- UIAApplication: name:TestAutomation rect:{{0,20},{320,460}}
| | +- UIAWindow: rect:{{0,0},{320,480}}
| | | +- UIAStaticText: name:First View value:First View rect:{{54,52},{212,43}}
| | | +- UIATextField: name:User Text value:Tap Some Text Here ! rect:{{20,179},{280,31}}
| | | +- UIAStaticText: name:The text is: value:The text is: rect:{{20,231},{112,21}}
| | | +- UIAStaticText: value: rect:{{145,231},{155,21}}
| | | +- UIATabBar: rect:{{0,431},{320,49}}
| | | | +- UIAImage: rect:{{0,431},{320,49}}
| | | | +- UIAButton: name:First value:1 rect:{{2,432},{156,48}}
| | | | +- UIAButton: name:Second rect:{{162,432},{156,48}} |

Äã¿ÉÒÔͨ¹ýÏÂÃæµÄ´úÂëÀ´·ÃÎÊÎı¾¿ò£º
var textField =
UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0];
|
Äã¿ÉÒÔÑ¡Ôñͨ¹ý´Ó0¿ªÊ¼µÄË÷Òý»òÕßÕâ¸öÔªËØµÄÃû³ÆÀ´·ÃÎÊÕâ¸öÔªËØ£¬ÀýÈ磺ÄãÒ²¿ÉÒÔͨ¹ýÏÂÃæµÄ´úÂëÀ´·ÃÎÊÎı¾¿Ø¼þ¡£
var textField =
UIATarget.localTarget().frontMostApp().mainWindow().textFields()["User Text"];
|
ºóÒ»ÖÖ·½Ê½¸ü¼ÓÇåÎúÃ÷ÁË£¬Ó¦¸Ã¶àʹÓá£Äã¿ÉÒÔͨ¹ýInterface BuilderÉèÖÃUIAElementµÄnameÊôÐÔ£¬

»òÕßͨ¹ý±àд´úÂëµÄ·½Ê½£º
myTextField.accessibilityEnabled = YES;
myTextField.accessibilityLabel = @"User Text";
|
ÄãÏÖÔÚ¿ÉÒÔ¿´µ½£¬Í¨¹ýaccessibilityÊôÐÔ¿ÉÒÔ±»UIAutomationÓÃÀ´ÕÒµ½²»Í¬µÄ¿Ø¼þ¡£Õâ·Ç³£µÄÇåÎú£¬ÒòΪ£¬µÚÒ»£¬ÄãֻҪѧϰһ¸ö²âÊÔ¿ò¼Ü£»µÚ¶þ£¬Í¨¹ý±àд×Ô¶¯»¯²âÊÔ´úÂ룬Äãͬʱ»¹¿ÉÒÔ±£Ö¤ÄãµÄ³ÌÐòÊÇ¿ÉÒÔ±»·ÃÎʵġ£Òò´Ë£¬Ã¿Ò»¸öUIAElement¶ÔÏóµÄ×ӿؼþ¿ÉÒÔͨ¹ýÏÂÃæµÄ·½·¨½øÐзÃÎÊ£º
buttons(), images(), scrollViews(),textFields(), webViews(),
segmentedControls(), sliders(), staticTexts(), switches(),
tabBar(),tableViews(), textViews(), toolbar(), toolbars()
µÈµÈ¡¡
Äã¿ÉÒÔͨ¹ýÈçÏ´úÂëÔÚtabbarÉÏ·ÃÎʵÚÒ»¸ötab£º
var tabBar = UIATarget.localTarget().frontMostApp().tabBar();
var tabButton = tabBar.buttons()["First"];
|
UIAElement½á¹¹²ã´Î·Ç³£µÄÖØÒª£¬ÄãÒÔºó»á³£³£Óõ½Ëü¡£¶øÇÒÄ㻹Ҫ¼Çס£¬Äã¿ÉÒÔÔÚËæÊ±Í¨¹ýµ÷ÓÃUIAAplicationµÄlogElementTreeÀ´»ñµÃËüµÄ½á¹¹¡£
UIATarget.localTarget().frontMostApp().logElementTree(); |
ÔÚÄ£ÄâÆ÷ÉÏ£¬Ä㻹¿ÉÒÔ¼¤»îAccessibility µÄ¼ì²âÆ÷¡£Æô¶¯Ä£ÄâÆ÷£¬ÕÒµ½¡°Settings >
General > Accessibility > Accessibility Inspector¡±£¬È»ºó½«ËüÉèΪ¡°´ò¿ª¡±×´Ì¬¡£

Õâ¸ö²ÊÉ«µÄС¿ò¿ò¾ÍÊÇAccessibility ¼ì²âÆ÷ÁË¡£µ±ËüÊÕÆðÀ´µÄʱºò£¬Accessibility¾Í±»¹Ø±ÕÁË£¬µ±ËüÕ¹¿ªµÄʱºò£¬Accessibility¾ÍÊÇ´ò¿ªµÄ¡£ÄãÖ»Òªµã»÷ÉÏÃæµÄ¼ýÍ·°´Å¥¾Í¿ÉÒÔ¼¤»î»òÕ߯Á±ÎAccessibility¡£ÏÖÔÚ£¬´ò¿ªÎÒÃǵÄʾÀý³ÌÐò£¬¼¤»î¼ì²âÆ÷¡£

È»ºó£¬µã»÷Îı¾¿ò£¬¼ì²éUIAElementµÄnameºÍvalueÊôÐÔ£¨Æäʵ¾ÍÊÇaccessibilityLabelºÍaccessibilityValue¶ÔÓ¦µÄNSObjectÀàÐ͵ÄÖµ£©¡£Õâ¸ö¼ì²âÆ÷¿ÉÒÔ°ïÖúÄãµ÷ÊԺͱàдÄãµÄ²âÊÔ´úÂë¡£
Ä£ÄâÓû§²Ù×÷
ÈÃÎÒÃǸü½øÒ»²½£¬Ä£ÄâһЩÓû§µÄ½»»¥²Ù×÷¡£Äã¿ÉÒÔ¼òµ¥µØµ÷Óð´Å¥µÄtap()À´×÷Ò»¸öµã»÷²Ù×÷£º
var tabBar = UIATarget.localTarget().frontMostApp().tabBar();
var tabButton = tabBar.buttons()["First"];
// Tap the tab bar !
tabButton.tap();
|
Ä㻹¿ÉÒÔµ÷ÓÃUIAButtonsµÄdoubleTap(), twoFingerTap()¡£Èç¹ûÄã²»Ïë²Ù×÷¾ßÌåµÄij¸öÔªËØ£¬ÄãÒ²¿ÉÒÔÖ±½Ó¸ù¾ÝÆÁÄ»ÉÏÖ¸¶¨µÄ×ø±êµã½øÐвÙ×÷£¬Äã¿ÉÒÔÕâôÓãº
µã»÷:
UIATarget.localTarget().tap({x:100, y:200});
UIATarget.localTarget().doubleTap({x:100, y:200});
UIATarget.localTarget().twoFingerTap({x:100, y:200});
|
Ëõ·Å:
UIATarget.localTarget().pinchOpenFromToForDuration({x:20, y:200},{x:300, y:200},2);
UIATarget.localTarget().pinchCloseFromToForDuration({x:20, y:200}, {x:300, y:200},2);
|
ÍÏ×§Óë»®¶¯:
UIATarget.localTarget().dragFromToForDuration({x:160, y:200},{x:160,y:400},1);
UIATarget.localTarget().flickFromTo({x:160, y:200},{x:160, y:400});
|
×¢Ò⣬µ±ÄãÖ¸¶¨²Ù×÷µÄʱ¼ä¼ä¸ôµÄʱºò£¬ËüÊÇÓÐÌØ¶¨µÄ·¶Î§µÄ£¬¼´£ºÍÏ×§²Ù×÷µÄʱ¼ä¼ä¸ô±ØÐë´óÓÚ»òÕßµÈÓÚ0.5Ã룬СÓÚ60Ãë¡£
ÏÖÔÚ£¬ÈÃÎÒÃÇÀ´Á·Ï°Ò»Ï£º
1.Í£Ö¹Instruments (?R)
2.ÔÚScripts´°¿ÚÀï, ÒÆ³ýµ±Ç°µÄ½Å±¾
3.µã»÷¡°Add > Import¡±È»ºóÑ¡ÔñTestAutomation/TestUI/Test-1.js£¨½«ÏÂÃæµÄ´úÂë±£´æµ½Õâ¸ö·¾¶£©
4.µã»÷Â¼ÖÆ°´Å¥ (?R) È»ºó¿´¿´½«»á·¢Éúʲô¡
|
ÏÂÃæÊÇTest-1.js´úÂ룺
var testName = "Test 1";
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
UIALogger.logStart( testName );
app.logElementTree();
//-- select the elements
UIALogger.logMessage( "Select the first tab" );
var tabBar = app.tabBar();
var selectedTabName = tabBar.selectedButton().name();
if (selectedTabName != "First") {
tabBar.buttons()["First"].tap();
}
//-- tap on the text fiels
UIALogger.logMessage( "Tap on the text field now" );
var recipeName = "Unusually Long Name for a Recipe";
window.textFields()[0].setValue(recipeName);
target.delay( 2 );
//-- tap on the text fiels
UIALogger.logMessage( "Dismiss the keyboard" );
app.logElementTree();
app.keyboard().buttons()["return"].tap();
var textValue = window.staticTexts()["RecipeName"].value();
if (textValue === recipeName){
UIALogger.logPass( testName );
}
else{
UIALogger.logFail( testName );
}
|
Õâ¶Î½Å±¾ÏÈÆô¶¯´ý²â³ÌÐò£¬È»ºó£¬Èç¹ûµÚÒ»¸ötabûÓб»Ñ¡µÄ»°¾ÍÇл»µ½µÚÒ»¸ötab£¬²¢½«ÉÏÃæµÄÎı¾¿òµÄÖµÉè³É¡°Unusually
Long Name for a Recipe¡±£¬½Ó×ÅÊÕÆðÐéÄâ¼üÅÌ¡£ÕâÀïÓÐһЩÐµķ½·¨ÖµµÃ×¢ÒâµÄ£ºUIATargetµÄdelay(Number
timeInterval) ·½·¨ÔÊÐíÄãÔÚÁ½¸ö²Ù×÷Ö®¼ä×öһЩµÈ´ý£¬UIALoggerµÄlogMessage(
String message) ·½·¨ÓÃÀ´½«ÄãÏë´òÓ¡µÄÐÅÏ¢Êä³öµ½ÈÕÖ¾ÉÏÈ¥£¬UIALoggerµÄlogPass(String
message)·½·¨Ö¸Ã÷ÄãµÄ²âÊԽű¾ÒѾ³É¹¦µÄÍê³É²âÊÔÁË¡£
Ä㻹֪µÀÁËÈçºÎ·ÃÎʼüÅÌÉϵİ´Å¥£¬È»ºó×÷µã»÷²Ù×÷£º
app.keyboard().buttons()["return"].tap(); |
ÓÉÓÚʱ¼äÓÐÏÞÇÒÔÎÄÌ«³¤£¬ÏÈÖ»ÄÜ·Òëµ½ÕâÀÎһᾡ¿ìµÄ½«Ê£ÏµIJ¿·Ö·Òë²¹ÉÏ¡£ÁíÍ⣬ʱ¼ä²Ö´Ù£¬ÈçÓзÒëµÃ²»×¼È·µÄµØ·½£¬Ò²¾´Çëµ£´ý¡£Ð»Ð»¡£
3. ¾Ñé·ÖÏí£¨ÈÃÄãÉú»î±äµÃ¸ü¼òµ¥£©
Àà¿âTune-up½éÉÜ
ÏÖÔÚÄãÓ¦¸Ã»ù±¾ÉÏÖªµÀÈçºÎ±àд²âÊÔ´úÂëÁË¡£µ«ÄãÂýÂýµØ»á·¢ÏÖ£¬Äã»á¾³£Ð´µ½Ò»Ð©Öظ´µÄ£¬ÈßÓàµÄ£¬ð¤ºýºýµÄ´úÂ룬ÏñÏÂÃæÒ»Ñù£º
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
|
ÕâÒ²ÊÇΪʲôÎÒÃÇ»áÓõ½Ò»¸öСµÄJavascriptÀà¿âÀ´¼ò»¯ÎÒÃÇдµÄUIAutomation²âÊÔµÄÔÒò¡£Äã¿ÉÒÔÈ¥
https://github.com/alexvollmer/tuneup_js»ñÈ¡Õâ¸öÀà¿â£¬È»ºó½«Ëü¸´ÖƵ½ÄãµÄ²âÊÔĿ¼ÏÂÃæ¡£ÏÖÔÚÈÃÎÒÃÇʹÓÃTune-UpÀà¿âÀ´ÖØÐ±àдÎÒÃǵÄTest1.js£º
#import "tuneup/tuneup.js"
test("Test 1", function(target, app) {
var window = app.mainWindow();
app.logElementTree();
//-- select the elements
UIALogger.logMessage( "Select the first tab" );
var tabBar = app.tabBar();
var selectedTabName = tabBar.selectedButton().name();
if (selectedTabName != "First") {
tabBar.buttons()["First"].tap();
}
//-- tap on the text fiels
UIALogger.logMessage( "Tap on the text field now" );
var recipeName = "Unusually Long Name for a Recipe";
window.textFields()[0].setValue(recipeName);
target.delay( 2 );
//-- tap on the text fiels
UIALogger.logMessage( "Dismiss the keyboard" );
app.logElementTree();
app.keyboard().buttons()["return"].tap();
var textValue = window.staticTexts()["RecipeName"].value();
assertEquals(recipeName, textValue);
});
Tune-Up¿ÉÒÔ±ÜÃâÄã±àÐ´ÖØ¸´µÄ´úÂ룬ͬʱ»¹¸øÄãÌṩÁ˸÷ÖÖºÃÓõĶÏÑÔ·½·¨£º
ssertTrue(expression, message),
assertMatch(regExp, expression, message),
assertEquals(expected, received, message),
assertFalse(expression, message),
assertNull(thingie, message),
assertNotNull(thingie, message),
assertNull(thingie, message),
assertNotNull(thingie, message) |
µÈµÈ
ÄãÒ²¿ÉÒÔºÜÈÝÒ×µÄÀ©Õ¹Õâ¸öÀà¿â£ºÀýÈ磬Äã¿ÉÒÔͨ¹ý½«·½·¨¼ÓÈëµ½uiautomation-ext.js:ÀïÃæÀ´ÎªUIATargetÀà¼ÓÒ»¸ölogDevice·½·¨£º
extend(UIATarget.prototype, {
logDevice: function(){
UIALogger.logMessage("Dump Device:");
UIALogger.logMessage(" model: " + UIATarget.localTarget().model());
UIALogger.logMessage(" rect: " + JSON.stringify(UIATarget.localTarget().rect()));
UIALogger.logMessage(" name: "+ UIATarget.localTarget().name());
UIALogger.logMessage(" systemName: "+ UIATarget.localTarget().systemName());
UIALogger.logMessage(" systemVersion: "+ UIATarget.localTarget().systemVersion());
}
});
|
È»ºóµ±Äãµ÷ÓÃtarget.logDevice()¾Í¿ÉÒÔ¿´µ½£º
Dump Device:
model: iPhone Simulator
rect: {"origin":{"x":0,"y":0},"size":{"width":320,"height":480}}
name: iPhone Simulator
|
µ¼ÈëÍⲿ½Å±¾
ÄãÒ²¿ÉÒÔ¿´µ½ÈçºÎÔÚÒ»¸ö½Å±¾ÎļþÀïÒýÓÃÁíÒ»¸ö½Å±¾£¬¼´Í¨¹ý#importÖ¸Áî¡£Òò´Ë£¬Äã¿ÉÒÔ´´½¨¶à¸ö²âÊÔÎļþ£¬È»ºó½«ËüÃÇͨ¹ýµ¼Èëµ½µ¥¸öÎļþµÄ·½Ê½À´Á´½Ó²¢µ÷ÓÃËüÃÇ£º
#import "Test1.js"
#import "Test2.js"
#import "Test3.js"
#import "Test4.js"
#import "Test5.js"
|
ʹÓÃÇ¿´óµÄÃüÁîÐÐ
Èç¹ûÄãÏëÈÃÄãµÄ²âÊÔ´úÂë×Ô¶¯µÄÔËÐÐÆðÀ´£¬Ä㻹¿ÉÒÔͨ¹ýÃüÁîÐÐÀ´Æô¶¯²âÊÔ¡£Æäʵ£¬ÎұȽÏÍÆ¼öÕâÖÖ·½Ê½£¬¶ø²»ÊÇʹÓÃInstrumentsµÄͼÐνçÃæ³ÌÐò¡£ÒòΪ£¬InstrumentsµÄͼÐνçÃæ³ÌÐò±È½ÏÂý£¬¶øÇÒ¼´Ê¹ÄãµÄ²âÊÔ´úÂëÅÜÍêÁËËüÒ²»¹ÊÇ»áÒ»Ö±ÔËÐÐ×Å¡£¶øÍ¨¹ýÃüÁîÐÐÀ´Æô¶¯ºÍÔËÐвâÊÔ´úÂë¸ü¿ì£¬Ëü»áÔÚÅÜÍê²âÊÔºó×Ô¶¯µÄÍ£Ö¹¡£
ΪÁË¿ÉÒÔÔÚÃüÁîÐÐÖÕ¶ËÔËÐÐÄãµÄ½Å±¾£¬ÄãÐèÒªÖªµÀÄãÉ豸µÄUDIDºÍÀàÐÍ£º
instruments -w your_ios_udid -t
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/
Library/Instruments/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate
name_of_your_app -e UIASCRIPT absolute_path_to_the_test_file
|
ÀýÈ磬ʹÓÃÎÒ×Ô¼ºµÄ»ú×Ó£¬¾ÍÕâôдµÄ£º
instruments -w a2de620d4fc33e91f1f2f8a8cb0841d2xxxxxxxx -t
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/
Developer/Library/Instruments/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate
TestAutomation -e UIASCRIPT
/Users/jc/Documents/Dev/TestAutomation/TestAutomation/TestUI/Test-2.js
|

Èç¹ûÄãʹÓõÄXcode°æ±¾µÍÓÚ4.3µÄ»°£¬ÄãÐèÒªÕâÑùд£º
instruments -w your_ios_device_udid -t /Developer/Platforms/iPhoneOS.platform/
Developer/Library/Instruments/PlugIns/AutomationInstrument.bundle/Contents/Resources/
Automation.tracetemplate TestAutomation -e UIASCRIPT /
Users/jc/Documents/Dev/TestAutomation/TestAutomation/TestUI/Test-2.js
|
Ò»¸öСÌáʾ£¬²»ÒªÍüÁ˹رÕÄãÉ豸µÄÃÜÂëÑéÖ¤£¬·ñÔòÄã»á¿´µ½ÕâÑùµÄÈÕÖ¾ÐÅÏ¢µÄ£ºremote exception
encountered : ¡¯device locked : Failed to launch process
with bundle identifier ¡¯com.manbolo.testautomation¡¯.
µÄÈ·£¬ÒòΪUIAutomation¸ù±¾²»ÖªµÀÄãµÄÃÜÂë°¡¡£
ÃüÁîÐÐÖÕ¶ËͬÑù¿ÉÒÔÔÚÄ£ÄâÆ÷ÉÏʹÓ㬵«ÄãÐèÒªÖªµÀ´ý²âÓ¦ÓóÌÐòÔÚÎļþϵͳÖеľø¶Ô·¾¶¡£Ä£ÄâÆ÷½«Ä¿Â¼~/Library/Application
Support/iPhone Simulator/5.1/ ¡°Ä£Ä⡱³ÉÁËÉ豸µÄÎļþϵͳ¡£ÔÚÕâ¸öĿ¼Ï£¬Äã¿ÉÒÔÕÒµ½Ò»¸ö°üº¬×°ÔÚÄ£ÄâÆ÷ÉϵÄËùÓÐÓ¦ÓóÌÐòµÄɳºÐµÄApplicationsÎļþ¼Ð¡£¶¨Î»µ½TestAutomation³ÌÐòµÄĿ¼£¬È»ºó£º
instruments -t /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Instruments/
PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate "/Users/jc/Library/
Application Support/iPhone Simulator/5.1/Applications/C28DDC1B-810E-43BD-A0E7-C16A680D8E15/
TestAutomation.app" -e UIASCRIPT /Users/jc/Documents/Dev/TestAutomation/TestAutomation/TestUI/Test-2.js |
×îºó£¬Èç¹ûÄãûÓÐÖ¸¶¨ÈÕÖ¾ÊäÈëµ½ÄÄÀïµÄ»°£¬ÄãµÄ²âÊÔ½á¹û»á±»·Åµ½ÄãÃüÁîÐе±Ç°Ö¸¶¨£¨¹¤×÷£©µÄĿ¼Ï¡£Äã¿ÉÒÔͨ¹ý¼ÓÈë
-e UIARESULTSPATH results_path ²ÎÊýÀ´Ö¸¶¨ÈÕÖ¾ÊäÈëĿ¼¡£
ÎÒûÓгɹ¦µÄ½«¶à¸ö²âÊԽű¾²¢ÐÐ×ÅÔÚÃüÁîÐÐÖÐÔËÐÐÆðÀ´¡£µ«ÊÇÄã¿ÉÒÔ½«ÄãµÄ²âÊԽű¾´®Á¬½øÀ´£¬ÓÐÒ»ÕûÍíÈ¥ÅÜËü£¬ÕâÑù¾ÍÕæÕýµÄʵÏÖÁË¡°ÔÚÄã˯×ŵÄʱºò¡±£¬¾ÍÍê³ÉÁ˶ÔÓ¦ÓóÌÐòµÄ²âÊÔ¡£
ʹÓÃÂ¼ÖÆ½»»¥¹¦ÄÜ
³ýÁËÊÖ¶¯µÄ±àд½Å±¾£¬Ä㻹¿ÉÒÔÖ±½ÓÔÚÉ豸ÉÏ»òÕßÄ£ÄâÆ÷ÉÏÂ¼ÖÆ½Å±¾£¬È»ºóÌæ»»µôÔÀ´µÄ¡£ÏÂÃæÊDz½Ö裺
1. Æô¶¯Instruments
2. ´´½¨Ò»¸öеĽű¾
3. Ñ¡Ôñ½Å±¾±à¼Æ÷

4. Ôڽű¾±à¼Æ÷µÄµ×¶Ë£¬ÄãÊÇ·ñ¿´µ½ÁËÒ»¸öºìÉ«µÄ°´Å¥£¿µã»÷Ëü£¡

5. ÏÖÔÚ£¬Äã¿ÉÒÔ²Ù×÷ÄãµÄÓ¦ÓóÌÐò£»Ä㽫¿´µ½Â¼ÖƵĽ»»¥²Ù×÷³öÏÖÔڽű¾´°¿Ú£¨ÉõÖÁÐýתʼþ£©¡£µã»÷·½Ðΰ´Å¥À´Í£Ö¹Â¼ÖÆ¡£

µ±Óöµ½ÎÊÌâʱ£¬¼ÓÉÏ¡°UIATarget.delay(1);¡±
µ±ÄãÔÚ±àд½Å±¾µÄʱºò£¬Äã×ÜÊÇÔÚÓëʱ¼ä£¬¶¯»´ò½»µÀ¡£UIAutomationÓкܶ෽ʽȥ»ñÈ¡¿Ø¼þÔªËØ£¬È»ºóµÈ´ýËüÃDZäΪ¿ÉÓÃ״̬£¬¼´Ê¹ÓÐʱºòËüÃÇ»¹Ã»ÓÐÏÔʾ³öÀ´£¬µ«¸ù¾ÝÕâÆªÎĵµÀïÌáµ½µÄ£¬×îºÃµÄ½¨ÒéÊÇ£º
µ±Óöµ½ÎÊÌâʱ£¬¼ÓÉÏUIATarget.delay(1);!
4. ¸ß¼¶½»»¥
´¦Àí·ÇÔ¤ÆÚºÍÔ¤ÆÚµÄÌáʾ¿ò£¨alerts£©
ÔÚд×Ô¶¯»¯²âÊÔ¹ý³ÌÖУ¬´¦ÀíÌáʾ¿òÊǺÜÄѵÄÒ»¼þÊÂÇ飺ÄãÒѾºÜÈÏÕæµÄдºÃÁËÄãµÄ²âÊÔÓÃÀý£¬È»ºóÔÚÄã×¼±¸Ë¯¾õ֮ǰ½«ËüÅÜÆðÀ´£¬È»ºó£¬µ½µÚ¶þÌìÔçÉÏ£¬Äã·¢ÏÖÄãµÄ²âÊÔÓÃÀý±»Ò»¸öδ֪ÏûÏ¢Ìáʾ¿ò¸ø»ÙÁË¡£È»¶ø£¬UIAutomation°ïÖúÄã´¦ÀíÁËÕâÖÖÇé¿ö¡£
ͨ¹ýÏÂÃæ´úÂëÀ´ÊµÏÖ£º
UIATarget.onAlert = function onAlert(alert){
var title = alert.name();
UIALogger.logWarning("Alert with title ¡¯" + title + "¡¯ encountered!");
return false; // use default handler
} |
Ëü·µ»ØÒ»¸öfalse£¬UIAutomation»á×Ô¶¯µÄ°ïÄãÏú»ÙUIAlertView´°¿Ú£¬Òò´ËÌáʾ¿ò¾Í²»»áÔÙÓ°ÏìÄãµÄ²âÊÔÁË¡£ÄãµÄ²âÊԽű¾¾ÍÓÀÔ¶²»»áÓÐÌáʾ¿òµ¯³öÁË¡£µ«ÊÇÌáʾ¿ò¿ÉÄÜÊÇÄãÓ¦ÓóÌÐòµÄÒ»²¿·Ö£¬Éæ¼°µ½Äã²âÊÔµÄÁ÷³Ì£¬ËùÒÔ£¬ÓÐʱºò£¬Ä㲻ϣÍûËü±»×Ô¶¯µÄ´¦Àíµô¡£Õâʱ£¬Äã¿ÉÒÔ¸ù¾ÝÌáʾ¿òµÄ±êÌâÀ´¾ö¶¨£¬µã»÷ij¸ö°´Å¥£¬È»ºó·µ»Øtrue¡£Í¨¹ý·µ»Øtrue£¬ÄãÏòUIAutomationÖ¸¶¨Õâ¸öÌáʾ¿ò±ØÐë×÷Ϊ²âÊÔµÄÒ»²¿·ÖÀ´¿¼ÂÇ¡£
ÀýÈ磬Èç¹ûÄãÏëµ±Ìáʾ¿òµÄ±êÌâΪ¡°Add Something¡±Ê±£¬µã»÷¡°Add¡±°´Å¥£¬Äã¿ÉÒÔÕâôд£º
UIATarget.onAlert = function onAlert(alert) {
var title = alert.name();
UIALogger.logWarning("Alert with title ¡¯" + title + "¡¯ encountered!");
if (title == "Add Something") {
alert.buttons()["Add"].tap();
return true; // bypass default handler
}
return false; // use default handler
}
|
ÈÝÒ×°É£¿
¶àÈÎÎñ
²âÊÔÄãµÄÓ¦ÓóÌÐòµÄ¶àÈÎÎñÊǷdz£ÈÝÒ×µÄÊ£º¼ÙÉèÄãÏë²âÊÔÿ´ÎÆô¶¯Ò»¸ö·è¿ñµÄºǫ́½ø³Ì£¬½«³ÌÐò·Åµ½ºǫִ́ÐÐ,²¢½øÈë(void)applicationWillEnterForeground:(UIApplication
*)applicationÑ¡ÔñÆ÷´úÂë¶Î£¬Äã¿ÉÒÔͨ¹ýÏÂÃæµÄ´úÂëÀ´½«ËüÍÆÖÁºǫ́£¬È»ºóµÈ´ý10Ãëºó×Ô¶¯·µ»Ø»î¶¯×´Ì¬¡£.
UIATarget.localTarget().deactivateAppForDuration(10);
deactivateAppForDuration(duration) ·½·¨»áÔÝÍ£²âÊԽű¾µÄÖ´ÐУ¬Ä£ÄâÓû§µã»÷Home°´Å¥£¬£¨¼´½«³ÌÐò·Åµ½ºǫ́£©£¬µÈ´ý£¬È»ºóΪÄãÖØÐ¼¤»î³ÌÐòºÍ²âÊԽű¾£¬¾ÍÕâôһÐдúÂë¶øÒÑ£¡
ÆÁÄ»·½Ïò
×îºó£¬Äã¿ÉÒÔÄ£ÄâÄãµÄiPhoneµÄÐýת·½Ïò¡£Ò²ÊǺÜÖ±¹ÛºÜ¼òµ¥£º
var target = UIATarget.localTarget();
var app = target.frontMostApp();
// set landscape left
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPELEFT);
UIALogger.logMessage("Current orientation is " + app.interfaceOrientation());
// portrait
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_PORTRAIT);
UIALogger.logMessage("Current orientation is " + app.interfaceOrientation());
|
5. ×ܽá
ÕâÆªÎÄÕÂÓеã¶ù³¤£¬µ«ÎÒÏ£ÍûÄãÃÇÄܼûʶµ½UIAutomationÊǺÜÇ¿´óµÄ£¬ÇÒÄãµÄÓ¦ÓóÌÐòÊÇ¿ÉÒԵõ½ÖÊÁ¿µÄ±£Õϵġ£
|