1 2<!DOCTYPE html> 3<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]--> 4<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]--> 5<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]--> 6<head> 7 <meta charset="utf-8"> 8 <title>åè¸ç®è¯´æµè¯</title> 9 <meta name="author" content="mijun(åè¸ç®)"> 10 11 12 <meta name="description" content="Calabash Android ççä¸é Androidèªå¨åæµè¯æçè«è«å¤çèªå¨åæµè¯æ¡æ¶ï¼ç±äºæ¬äººæ¯Rubyçfansãæä»¥å¯¹Rubyå°è£ çä¸äºå·¥å ·æ æç¬éãè½ç¶æ¯Rubyçfansï¼ä½æ¯å¯¹BDDä¸ç´ä¸å¤ªè½æ¥åãæè¿æ£å¥½æä¸ä¸ªæºä¼ï¼å¼å§å°è¯ç使ç¨Calabash …"> 13 14 15 <!-- http://t.co/dKP3o1e --> 16 <meta name="HandheldFriendly" content="True"> 17 <meta name="MobileOptimized" content="320"> 18 <meta name="viewport" content="width=device-width, initial-scale=1"> 19 20 21 <link rel="canonical" href="http://houlianpi.github.com/index.html"> 22 <link href="/favicon.png" rel="icon"> 23 <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css"> 24
24<script src="/javascripts/modernizr-2.0.js"></script>
24 25
25<script src="/javascripts/ender.js"></script>
25 26
26<script src="/javascripts/octopress.js" type="text/javascript"></script>
26 27 <link href="/atom.xml" rel="alternate" title="åè¸ç®è¯´æµè¯" type="application/atom+xml"> 28 <!--Fonts from Google"s Web font directory at http://google.com/webfonts --> 29<link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css"> 30<link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css"> 31 32 33
33<script type="text/javascript"> 34 var _gaq = _gaq || []; 35 _gaq.push(['_setAccount', 'UA-47053050-1']); 36 _gaq.push(['_trackPageview']); 37 38 (function() { 39 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 40 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 41 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 42 })(); 43 </script>
43 44 45 46</head> 47 48<body > 49 <header role="banner"><hgroup> 50 <h1><a href="/">åè¸ç®è¯´æµè¯</a></h1> 51 52 <h2>å¨è¿éæä»¬åªè¯´æµè¯</h2> 53 54</hgroup> 55 56</header> 57 <nav role="navigation"><ul class="subscription" data-subscription="rss"> 58 <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li> 59 60</ul> 61 62<form action="http://google.com/search" method="get"> 63 <fieldset role="search"> 64 <input type="hidden" name="q" value="site:houlianpi.github.com" /> 65 <input class="search" type="text" name="q" results="0" placeholder="Search"/> 66 </fieldset> 67</form> 68 69<ul class="main-navigation"> 70 <li><a href="/">Blog</a></li> 71 <li><a href="/blog/archives">Archives</a></li> 72 <li><a href="/about-me">About me</a></li> 73</ul> 74 75</nav> 76 <div id="main"> 77 <div id="content"> 78 <div class="blog-index"> 79 80 81 82 <article> 83 84 <header> 85 86 <h1 class="entry-title"><a href="/blog/calabash-setup-and-simple-use.html">Calabash Android åå§ååä¸äºä½¿ç¨æå·§</a></h1> 87 88 89 <p class="meta"> 90 91 92 93 94 95 96 97 98 99 100 101 102<time datetime="2015-06-19T08:32:00+08:00" pubdate data-updated="true">Jun 19<span>th</span>, 2015</time> 103 104 </p> 105 106 </header> 107 108 109 <div class="entry-content"><h2>Calabash Android ççä¸é</h2> 110 111<p> Androidèªå¨åæµè¯æçè«è«å¤çèªå¨åæµè¯æ¡æ¶ï¼ç±äºæ¬äººæ¯Rubyçfansãæä»¥å¯¹Rubyå°è£ çä¸äºå·¥å ·æ æç¬éãè½ç¶æ¯Rubyçfansï¼ä½æ¯å¯¹BDDä¸ç´ä¸å¤ªè½æ¥åãæè¿æ£å¥½æä¸ä¸ªæºä¼ï¼å¼å§å°è¯ç使ç¨Calabash Androidèªå¨åæµè¯åä¸äºä¸è¥¿ã</p> 112 113<p> é¦å ï¼è¿æ¯å åºè¯å å¥å§ãAndroidçèªå¨åæµè¯çæ¬å¤ªå¤ï¼ä¸è½å¨è¿éä¸ä¸ä»ç»ã使¯ï¼ç°å¨å½å 使ç¨çæ¡æ¶åºæ¬ä¸å¯ä»¥å为两大类ï¼Android JUnitç³»ååUiAutomatorç³»åã</p> 114 115<p> Android Junitç³»åå°±å æ¬å¤§åé¼é¼ç<a href="https://code.google.com/p/robotium/">Robotium</a>åä»å¤©è¦è¯´ç<a href="https://github.com/calabash/calabash-android">Calabash Android</a>ãè¿ä¸ªç³»åé¤äºæç¾åéå¶ä¸è½å¤¸åºç¨ä»¥å¤ï¼é½é常å¥å£®å稳å®ã</p> 116 117<p> UiAutomatorç³»åæèåçå½ç¶è¦è¯´æ¯<a href="http://appium.io/">Appium</a>ãUiAutomatorå¯ä»¥è·¨åºç¨æä½ï¼æ´ä½æä½å®å ¨æ¯åºäºUIçæä½ã使¯Android宿¹å¯¹UiAutomatorçæ¯æå¹¶ä¸æ¯éå¸¸å¥½ï¼æ¯å¦è¾å ¥æ³çã使å¾UiAutomatorçè¿è¡ç¨³å®æ§ç¸å¯¹äºAndroid JUnitå·®å¾å¤ãåå ä¸Androidæ¬èº«ççæ¬åè£ï¼UiAutomatoré£å°±æ´ä¼è®©å¼åè è§å¾å¤´å¤§ãæä»¥ï¼å¦ææ²¡æè·¨åºç¨çæä½ï¼è¯·å°½éä¸è¦éæ©UiAutomatorç³»åçå·¥å ·ï¼è³å°ç°å¨ä¸è¦ã</p> 118 119<p> å¨Android JUnitè¿ä¸ªç³»åä¸éæ©ä¸æ¬¾å·¥å ·åèªå¨åæµè¯çè¯ï¼ä¸ªäººæ´å¾åäºéæ©Calabash Android](https://github.com/calabash/calabash-android)æè <a href="http://selendroid.io/">Selendroid</a>ãç¬ç«çQAå¢éæ´éè¦æ æºç æ¹å¼çèªå¨åæµè¯æ¡æ¶ãå ¶æ¬¡ï¼ç®åé«æç¨³å®æ¯ä»»ä½èªå¨åæµè¯æ¡æ¶çåºç¡ãä»è¿ä¸¤ç¹åºåï¼éæ©äºä»¥ä¸ä¸¤æ¬¾å·¥å ·ã<a href="http://selendroid.io/">Selendroid</a>æ¯ä½¿ç¨Javaå¼åçï¼ä¸è¬æ åµä¸éè¦ä½¿ç¨Javaæ¥ç¼åèªå¨åæµè¯ç¨ä¾ãä½ä¸ºRubyçfansæ´åºè¯¥å°è¯ä¸ä¸Calabash Android](https://github.com/calabash/calabash-android)ã</p> 120 121<h2>Calabashçç¯å¢é ç½®</h2> 122 123<p> Calabashçæ¬èº«çå®è£ ç¸å¯¹ç®åï¼å¹¶ä¸æ<a href="https://github.com/calabash/calabash-android/blob/master/documentation/installation.md">宿¹ææ¡£</a>ãç°å¨å®è£ çCalabash齿¯0.5çæ¬çã</p> 124 125<p> å®è£ 宿ä¹åï¼è¿è¡ç®åçé ç½®æå¯ä»¥ä½¿ç¨Calabashã</p> 126 127<h4>1ãé ç½®ç¯å¢åé</h4> 128 129<p>é ç½®ç¯å¢åéæå ³é®ç¹</p> 130 131<pre><code>export ANDROID_HOME=/Users/<user>/adt-bundle-mac-x86_64-20140702/sdk 132export PATH=$PATH:$ANDROID_HOME/tools 133</code></pre> 134 135<h4>2ãçæç¾åï¼å¹¶ä¸ç¥éèªå·±ç¾åçpasswordåalias</h4> 136 137<p>çæç¾åå¯ä»¥ä½¿ç¨ä¸ä¸Shellæ¥çæã</p> 138 139<pre><code>keytool -genkey -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=Android Debug,O=Android,C=US" 140</code></pre> 141 142<p>çæä¹åç¾åçä½ç½®å¨</p> 143 144<pre><code>~/.android/debug.keystore 145</code></pre> 146 147<p>passwordæ¯ï¼</p> 148 149<pre><code>android 150</code></pre> 151 152<p>aliasæ¯ï¼</p> 153 154<pre><code>androiddebugkey 155</code></pre> 156 157<p>以ä¸è¿äºå ³é®å ç´ å¨é ç½®Calabashçæ¶åé½å¾éè¦ã</p> 158 159<h4>3ãé ç½®Calabash</h4> 160 161<p>Calabashçé ç½®ä¸è¬æ åµå åªéè¦é ç½®ç¾åç¸å ³ä¿¡æ¯å°±å¥½ãè¿è¡å½ä»¤è¡ï¼</p> 162 163<pre><code>calabash-android setup 520c4f587081a6b530a03c3e86c8bfc4.apk -v 164</code></pre> 165 166<p>ç¶åæç §æç¤ºåå«è¾å ¥ï¼ç¾åè¯ä¹¦çä½ç½®ï¼å¯ç åaliasãæåä¹åä¼çå°è¿æ ·ä¸å¥æç¤ºï¼</p> 167 168<pre><code>Saved your settings to .calabash_settings. You can edit the settings manually or run this setup script again 169</code></pre> 170 171<p>å½ç¶ï¼ä½ ä¹å¯ä»¥æå¨çé ç½®æä»¶å®æè®¾ç½®ãé ç½®æä»¶çå°å为ï¼</p> 172 173<pre><code>~/.calabash_settings 174</code></pre> 175 176<h4>4ãCalabash Console</h4> 177 178<p>Calabash Console对äºä¼å代ç ç人æ¥è¯´ï¼ä¸ç§é常æ¹ä¾¿è°è¯çå·¥å ·ã使ç¨å½ä»¤ï¼</p> 179 180<pre><code>calabash-android console 520c4f587081a6b530a03c3e86c8bfc4.apk 181</code></pre> 182 183<p>å½ç¶ææ¶å°±ä¼æ¥éãæ¥éæä¸¤ç§ï¼ä¸ç§æ¯éè¦æç §æ¬æä¹åçå 容è¿è¡Calabashé ç½®ãè¿æä¸ç§æ 嵿¯éè¦å¯¹è¢«æµè¯åºç¨è¿è¡éæ°ç¾åãéæ°ç¾åçå½ä»¤ï¼</p> 184 185<pre><code>calabash-android resign 520c4f587081a6b530a03c3e86c8bfc4.apk -v 186</code></pre> 187 188<p>æåè¿å ¥Calabash Consoleä¹åï¼è¿éè¦è¿è¡ä¸¤ä¸ªå½ä»¤è¡ï¼æè½å¼å§ä¼ ç»æä¹ä¸çèªå¨åæµè¯çè°è¯ï¼</p> 189 190<pre><code>reinstall_apps 191start_test_server_in_background 192</code></pre> 193 194<p>ç»è¿ä»¥ä¸ä¸¤æ¡å½ä»¤ï¼è¢«æµè¯ç¨åºä¼å¯å¨ï¼è¿æ¯å¯ä»¥éè¿ä¸äºCalabashçå½ä»¤è¿è¡èªå¨åæµè¯äºã</p> 195 196<p>å½ç¶ï¼ä¹ä¼æä¸äºå¼å¸¸æ åµï¼ä¾å¦ï¼å¦ææ¿äºç½ææ°é»çAndroid客æ·ç«¯åè¿ä¸ªå®éªï¼å°±ä¼åç°ä¸ä¼æåãå ä¸ºç½ææ°é»åäºç¾åéªè¯ï¼å½ç¨åºçç¾åè¢«æ¿æ¢æä»¥åï¼ç¨åºæ æ³æ£å¸¸å¯å¨ã</p> 197</div> 198 199 200 201 202 </article> 203 204
205 <article> 206 207 <header> 208 209 <h1 class="entry-title"><a href="/blog/appium-chinese-input.html">Appium䏿è¾å ¥é®é¢çä¸äºæ¢ç´¢</a></h1> 210 211 212 <p class="meta"> 213 214 215 216 217 218 219 220 221 222 223 224 225<time datetime="2014-06-17T12:08:00+08:00" pubdate data-updated="true">Jun 17<span>th</span>, 2014</time> 226 227 </p> 228 229 </header> 230 231 232 <div class="entry-content"><h2>Appiumè¾å ¥ä¸æçé®é¢</h2> 233 234<p>å¨ä½¿ç¨Appiumåææºç«¯çèªå¨åæµè¯æ¶ï¼ä½ å¯ä»¥ä¼éå°è¾å ¥ä¸æçé®é¢ã使¯ç±äºAppiumæ¯ä¸ä¸ªèªå¨åæµè¯å·¥å ·çéåï¼æä»¥éå°ç䏿é®é¢ä¹å¯è½ä¼æ¯è¾é¾è¯´æ¸ æ¥ãAppiumæ¯æiOSãAndroidåFireFoxOSä¸ç§æä½ç³»ç»ã使¯FireFoxOSä¸è¬äººé½ä¸ç¨ï¼æä»¥ï¼æç« ä¸å®æ¯æå䏿¬¡é²é¢äºã</p> 235 236<p>Appiumå¨iOS端èªå¨åæµè¯åºå±ä½¿ç¨çæ¯å®æ¹ç<a href="https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html" title="Title">UI Autoamtion</a>ãå¨Android端ï¼4.2以ä¸ä½¿ç¨ç宿¹ç<a href="http://developer.android.com/tools/help/uiautomator/index.html" title="Title">Uiautomator</a>ï¼4.1以ä¸ä½¿ç¨çæ¶eBayç<a href="http://selendroid.io/" title="Title">selendroid</a>ãæä»¥å¨è¾å ¥ä¸æçé®é¢ä¸ï¼ä¸ä¸ªå¹³å°ç论ä¸é½æå¯è½éå°é®é¢ãæ¬æä¹åå°éç¹è°ç Uiautomatorçè¾å ¥ä¸æçé®é¢ã</p> 237 238<p>å ³äºä¸æè¾å ¥ççç»è®ºï¼</p> 239 240<ul> 241<li>Appium iOS å®å ¨æ¯æ</li> 242<li>Appium Android selendroid åºè¯¥æ¯æï¼éè¦å®è·µç¡®è®¤ï¼ç®å没æè¯è¿ï¼åªæ¯çæµï¼</li> 243<li>Appium Android Uiautomator 䏿¯æï¼åºè¯¥æ¯ç¡¬ä¼¤ï¼ç®åæ è§£</li> 244</ul> 245 246 247<p>selendroidçè°ç ä¹åè¡¥å ã</p> 248 249<h2>Appium iOS䏿è¾å ¥è°ç </h2> 250 251<p>é¦å å æ¥è¯´ä¸ä¸UI Automationãè¹æå®æ¹çUI Automationå¨è¾å ¥æ¶æä¸¤ç§æ¹æ³ï¼</p> 252 253<ul> 254<li>ï¼1ï¼ç´æ¥ä½¿ç¨ElementçsetValueæ¹æ³ã</li> 255<li>ï¼2ï¼UI Automationä¸ç UIAKeyboard对象æä¸ä¸ªtypeStringæ¹æ³ã</li> 256</ul> 257 258 259<p>以ä¸ä¸¤ä¸ªæ¹æ³å¨æ¨¡æå¨ä¸é½æ¯å®ç¾æ¯æä¸æçãæä»¥ä¸ç®¡å¨iOSä¸é¢æä¹ç©ï¼é½æ¯æ¯æä¸æçãå½ç¶ä¸¤ä¸ªæ¹å¼æ¯æåºå«çãæ¹æ³ï¼1ï¼ç®åç´æ¥ï¼åºæ¬ä¸å°±æ¯ä¸ä¸ªç®åçsetæ¹æ³ãè¾å ¥æ¶ä¸ä¼è§¦åä»ä¹ç±»ä¼¼textChangedäºä»¶ãæ¹æ³ï¼2ï¼éè¦å¾å¤æ¯æï¼æ¹æ³äºæ¯å®å ¨æ¨¡æäººæå·¥è¾å ¥è¿ç¨ãè¹æå¯¹è±æä»¥å¤çè¾å ¥é½åäºå¾å¥½å°å ¼å®¹ã</p> 260 261<p>Appium iOSçæ¬ç sendkeysæ¹æ³ï¼ç´æ¥å¯¹åº UIAKeyboardçtypeStringæ¹æ³ãç±äºtypeStringæ¹æ³å®ç¾æ¯æä¸æãæä»¥Appium iOSçæ¬ä¹å°±æ¯æä¸æäºãå½ç¶ï¼typeStringæ¹æ³ä¹æç¼ºç¹ãå½ä¸ä¸ªè¾å ¥æ¡å æå å®¹çæ¶åï¼typeStringçè¾å ¥æ¹æ³æ¯æ·»å ï¼æä»¥ï¼å¦æä¹åçå 容ä¸éè¦çæ¶åï¼è¿éè¦å æ¸ é¤æï¼å¨è¿è¡typeStringã卿²¡æç¹æ®è¦æ±çæ åµä¸ï¼ææ¯è¾å欢setValueè¿ä¸ªæ¹æ³ï¼ä½æ¯éæ¾çæ¶Appium䏿¯æç´æ¥setValueã</p> 262 263<h2>Appium Android Uiautomator䏿è¾å ¥è°ç </h2> 264 265<p>ä¹æä»¥è½æè¿ç¯æç« ï¼ä¸»è¦æ¯å 为æè¿æ³ä½¿ç¨Appiumåä¸äºAppä¹é´ç¸äºè·³è½¬çèªå¨å确认æµè¯ãä¸ä¸ªä¸æçAppï¼å¦æä¸è½è¾å ¥ä¸æåºæ¬ä¸å°±æ¯æèãå¨ä½¿ç¨å¦ä¹ å·¥å ·çæ¶ååç°äºå¾å¤åï¼ä¸è½è¾å ¥ä¸æçè¿ä¸ªåæå¤§ï¼æéé·ãæä»¥ï¼æèªå·±çè°ç æ¹æ³ååºæ¥ï¼ä¾å¤§å®¶åèã</p> 266 267<p>é¦å å¨ä¸åæªç¥çæ åµä¸ï¼ä½¿ç¨äºè¿ä¸ªæ¹æ³è¿è¡è¾å ¥ï¼</p> 268 269<pre><code>input.sendKeys("èå°ä¸çä¸å½"); 270</code></pre> 271 272<p>åç°ç»æä¸å¯¹ï¼ç¶åå°è¯äºä¸è¾å ¥ä¸æï¼</p> 273 274<pre><code>input.sendKeys("ssssssss"); 275</code></pre> 276 277<p>ç»æä¹ä¸å¯¹ï¼åç°ææºä¸ä½¿ç¨çè¾å ¥æ³æ¯Google䏿è¾å ¥æ³ãæè¾å ¥æ³åæ¢å°è±æè¾å ¥æ³ï¼ä»¥åï¼è±æçæ£ç¡®çäºï¼ä¸æçè¿æ¯æé®é¢ãäºæ¯Googleäºä¸ä¸ï¼æ¾å°äºä¸ä¸ª<a href="http://testerhome.com/topics/242" title="Title">å¸å</a>ãä¸é¢ä¿¡æ¯éå¾å¤§ï¼çèµ·æ¥æ¯è¾é è°±çæ¯æä¸ä¸ªæ¹æ³ï¼å©ç¨JSè¿è¡å¨æ¥ç´æ¥è¾å ¥æ¹æ³ï¼ç¿»è¯ä¸ºJavaçæ¬ä»¥åï¼ä»£ç å¦ä¸ï¼</p> 278 279<figure class='code'><figcaption><span>Java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 280<span class='line-number'>2</span> 281<span class='line-number'>3</span> 282</pre></td><td class='code'><pre><code class='java'><span class='line'> <span class="n">inputDir</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"element"</span><span class="o">,((</span><span class="n">RemoteWebElement</span><span class="o">)</span><span class="n">input</span><span class="o">).</span><span class="na">getId</span><span class="o">());</span> 283</span><span class='line'> <span class="n">inputDir</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"text"</span><span class="o">,</span><span class="s">"èå°ä¸çä¸å½"</span><span class="o">);</span> 284</span><span class='line'> <span class="n">driver</span><span class="o">.</span><span class="na">executeScript</span><span class="o">(</span><span class="s">"element:setText"</span><span class="o">,</span> <span class="n">inputDir</span><span class="o">);</span> 285</span></code></pre></td></tr></table></div></figure> 286 287 288<p>è¿ä¸ªæ¹æ³ä¼åºç°ä¸ä¸ªæ²¡æå®ç°çå¼å¸¸ã</p> 289 290<p>好å§ï¼çæºç ã</p> 291 292<p>å¨ä½¿ç¨Appium çsendkeysæ¹æ³æ¯ï¼Clientä¼åéä¸ä¸ªhttp请æ±å°Ap
292piumçserverãå¨AppiumServerç«¯çæºç ä¸ æä¸ä¸ª rounting çæä»¶ï¼è¾å ¥æ¹æ³ä¼åéè¿æ ·çè·¯ç±ï¼ rest.post(‘/wd/hub/session/:sessionId?/element/:elementId?/value’, controller.setValue); ç¶åæ è¤æ¸çï¼æ¾å°controllerçsetValueæ¹æ³ãç¶å䏿¥ä¸æ¥çæ¥æ¾ï¼æç»ä¼æ¾å°bootstrap项ç®ä¸çAndroidElement.javaæä»¶ï¼å ¶ä¸æsetTextæ¹æ³ã代ç å¦ä¸ï¼</p> 293 294<figure class='code'><figcaption><span>Java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 295<span class='line-number'>2</span> 296<span class='line-number'>3</span> 297<span class='line-number'>4</span> 298<span class='line-number'>5</span> 299<span class='line-number'>6</span> 300<span class='line-number'>7</span> 301<span class='line-number'>8</span> 302<span class='line-number'>9</span> 303<span class='line-number'>10</span> 304</pre></td><td class='code'><pre><code class='java'><span class='line'> <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">setText</span><span class="o">(</span><span class="kd">final</span> <span class="n">String</span> <span class="n">text</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">UiObjectNotFoundException</span> <span class="o">{</span> 305</span><span class='line'> <span class="k">if</span> <span class="o">(</span><span class="n">UnicodeEncoder</span><span class="o">.</span><span class="na">needsEncoding</span><span class="o">(</span><span class="n">text</span><span class="o">))</span> <span class="o">{</span> 306</span><span class='line'> <span class="n">Logger</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"Sending Unicode text to element: "</span> <span class="o">+</span> <span class="n">text</span><span class="o">);</span> 307</span><span class='line'> <span class="n">String</span> <span class="n">encodedText</span> <span class="o">=</span> <span class="n">UnicodeEncoder</span><span class="o">.</span><span class="na">encode</span><span class="o">(</span><span class="n">text</span><span class="o">);</span> 308</span><span class='line'> <span class="k">return</span> <span class="n">el</span><span class="o">.</span><span class="na">setText</span><span class="o">(</span><span class="n">encodedText</span><span class="o">);</span> 309</span><span class='line'> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> 310</span><span class='line'> <span class="n">Logger</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"Sending plain text to element: "</span> <span class="o">+</span> <span class="n">text</span><span class="o">);</span> 311</span><span class='line'> <span class="k">return</span> <span class="n">el</span><span class="o">.</span><span class="na">setText</span><span class="o">(</span><span class="n">text</span><span class="o">);</span> 312</span><span class='line'> <span class="o">}</span> 313</span><span class='line'> <span class="o">}</span> 314</span></code></pre></td></tr></table></div></figure> 315 316 317<p>å¨Appium Android Uiautomatorä¸ï¼è¾å ¥æ¹æ³å°±æ¯è¿ä¸æ®µä»£ç ãä»è¿ä¸æ®µä»£ç ä¸ä¼åç°Appiumåºæ¬æ²¡æåä»ä¹äºæ ï¼æç»è°ç¨äºUiautomatoræ¬èº«çsetTextæ¹æ³ãæä»¥ï¼æ¥ä¸æ¥éè¦ç¡®è®¤åççUiautomatoræ¯å¦å¯ä»¥æ¯æä¸æè¾å ¥ã 318ç»è¿ç®åçæµè¯åç°ï¼Uiautomator䏿¯æä¸æè¾å ¥ï¼ç¶åç»§ç»Googleè§£å³æ¹æ¡ãåç°äºä¸ä¸ª<a href="https://github.com/sumio/uiautomator-unicode-input-helper" title="Title">uiautomator-unicode-input-helper</a>弿ºé¡¹ç®ãç´æ¥æ¿æ¥å°è¯äºä¸æï¼ä¹åç°ä¸å¯¹ãæç §ä½è çè¯´æ³æ¯å¯ä»¥æ¯ææ¥è¯ï¼ä½æ¯è²ä¼¼æ³æ¯æä¸æçè¯ï¼è¿è¦è¿è¡ä¸å®éçå¼åã</p> 319 320<p>ç»§ç»ççUiautomator为ä»ä¹ä¸æ¯æä¸æãç¶åç»§ç»æ¾Androidçæºç ï¼åç°Uiautomatorçææçåè½é½æ¯éè¿UiAutomatorBridgeæ¥å®æçãå¨UiAutomatorBridgeç±»ä¸æä¸ä¸ªæååéç±»åæ¯InteractionControllerãè¾å ¥æ¯éè¿InteractionControlleræ¥å®ç°çãå ·ä½çsetTextæ¹æ³ä
320»£ç å¦ä¸ï¼</p> 321 322<figure class='code'><figcaption><span>Java</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 323<span class='line-number'>2</span> 324<span class='line-number'>3</span> 325<span class='line-number'>4</span> 326<span class='line-number'>5</span> 327<span class='line-number'>6</span> 328<span class='line-number'>7</span> 329<span class='line-number'>8</span> 330<span class='line-number'>9</span> 331<span class='line-number'>10</span> 332<span class='line-number'>11</span> 333<span class='line-number'>12</span> 334<span class='line-number'>13</span> 335<span class='line-number'>14</span> 336<span class='line-number'>15</span> 337<span class='line-number'>16</span> 338<span class='line-number'>17</span> 339<span class='line-number'>18</span> 340<span class='line-number'>19</span> 341<span class='line-number'>20</span> 342<span class='line-number'>21</span> 343<span class='line-number'>22</span> 344</pre></td><td class='code'><pre><code class='java'><span class='line'> <span class="kd">public</span> <span class="kt">boolean</span> <span class="n">More</span> <span class="o">...</span><span class="na">sendText</span><span class="o">(</span><span class="n">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span> 345</span><span class='line'> <span class="k">if</span> <span class="o">(</span><span class="n">DEBUG</span><span class="o">)</span> <span class="o">{</span> 346</span><span class='line'> <span class="n">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="n">LOG_TAG</span><span class="o">,</span> <span class="s">"sendText ("</span> <span class="o">+</span> <span class="n">text</span> <span class="o">+</span> <span class="s">")"</span><span class="o">);</span> 347</span><span class='line'> <span class="o">}</span> 348</span><span class='line'> <span class="n">mUiAutomatorBridge</span><span class="o">.</span><span class="na">setOperationTime</span><span class="o">();</span> 349</span><span class='line'> <span class="n">KeyEvent</span><span class="o">[]</span> <span class="n">events</span> <span class="o">=</span> <span class="n">mKeyCharacterMap</span><span class="o">.</span><span class="na">getEvents</span><span class="o">(</span><span class="n">text</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">());</span> 350</span><span class='line'> <span class="k">if</span> <span class="o">(</span><span class="n">events</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> 351</span><span class='line'> <span class="k">for</span> <span class="o">(</span><span class="n">KeyEvent</span> <span class="n">event2</span> <span class="o">:</span> <span class="n">events</span><span class="o">)</span> <span class="o">{</span> 352</span><span class='line'> <span class="c1">// We have to change the time of an event before injecting it because</span> 353</span><span class='line'> <span class="c1">// all KeyEvents returned by KeyCharacterMap.getEvents() have the same</span> 354</span><span class='line'> <span class="c1">// time stamp and the system rejects too old events. Hence, it is</span> 355</span><span class='line'> <span class="c1">// possible for an event to become stale before it is injected if it</span> 356</span><span class='line'> <span class="c1">// takes too long to inject the preceding ones.</span> 357</span><span class='line'> <span class="n">KeyEvent</span> <span class="n">event</span> <span class="o">=</span> <span class="n">KeyEvent</span><span class="o">.</span><span class="na">changeTimeRepeat</span><span class="o">(</span><span class="n">event2</span><span class="o">,</span> 358</span><span class='line'> <span class="n">SystemClock</span><span class="o">.</span><span class="na">uptimeMillis</span><span class="o">(),</span> <span class="mi">0</span><span class="o">);</span> 359</span><span class='line'>
359 <span class="k">if</span> <span class="o">(!</span><span class="n">injectEventSync</span><span class="o">(</span><span class="n">event</span><span class="o">))</span> <span class="o">{</span> 360</span><span class='line'> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span> 361</span><span class='line'> <span class="o">}</span> 362</span><span class='line'> <span class="o">}</span> 363</span><span class='line'> <span class="o">}</span> 364</span><span class='line'> <span class="k">return</span> <span class="kc">true</span><span class="o">;</span> 365</span><span class='line'> <span class="o">}</span> 366</span></code></pre></td></tr></table></div></figure> 367 368 369<p>éè¿è¿æ®µä»£ç ï¼åºæ¬ä¸å°±æç½äºï¼AndroidçUiautomatorå®å ¨æ²¡æå ¼å®¹è±æä»¥å¤çè¾å ¥æ³çææãå¹¶ä¸ä¹æ²¡ææä¾ç´æ¥è®¾ç½®å±æ§çæ¹æ³ã</p> 370 371<p>Appium Android Uiautomator è¦æ¯æè¾å ¥ä¸æè¿æå¾é¿ç䏿®µè·¯éè¦èµ°ã伤å¿äºã</p> 372</div> 373 374 375 376 377 </article> 378 379 380 <article> 381 382 <header> 383 384 <h1 class="entry-title"><a href="/blog/kan-wu.html">ãiOSæµè¯æåãå误ä¸</a></h1> 385 386 387 <p class="meta"> 388 389 390 391 392 393 394 395 396 397 398 399 400<time datetime="2014-06-01T21:00:00+08:00" pubdate data-updated="true">Jun 1<span>st</span>, 2014</time> 401 402 </p> 403 404 </header> 405 406 407 <div class="entry-content"><p>ãiOSæµè¯æåãåºçå¹¶ä¸ä¸å¸å·²ç»æä¸ä¸ªæçæ¶é´äºãéç该书éç»çä¸è¯»è è§é¢ï¼ä¸äºéèççå°éè¯¯ä¹æ ¢æ ¢æµ®åºæ°´é¢ãå¨è¿éå ç®åç说æä¸ä¸ï¼æªæ¢å°ç°å¨ç¬è æç¥çä¸äºä¹¦å çé误ã</p> 408 409<h3>Byte å bitçåºå«</h3> 410 411<p>Byteåbitæ¯æåºå«ï¼8个bitæ¯ä¸ä¸ªByteãä¸è¬è¯´æä»¶å¤§å°çæ¶åï¼å使¯Byteã说ç½ç»å¸¦å®½æ¶ä¸è¬ä½¿ç¨bitãå¨ãiOSæµè¯æåãç125页ä¸ï¼å¨æè¿°å ç§ææºä¸ç½å¸¦å®½æ¶ï¼åéäºï¼ç½ç»å¸¦å®½çå°åã</p> 412 413<p>书ä¸åå§å¦å¾æç¤ºï¼è¿éåºè¯¥ä½¿ç¨ kbï¼æ¥è¡¨ç¤ºç½ç»å¸¦å®½ï¼å¹¶ä¸æ¯ä½¿ç¨KBã 414<img src="http://ww3.sinaimg.cn/mw690/9d98efcctw1egywk2uikxj21cq0hagpm.jpg" title="125页ä¸é误æªå¾" alt="alt text" /></p> 415 416<p>éå¸¸æ±æï¼ä¸ä¸ªç®åçç忽就让ç½ç»å¸¦å®½åå°æé«äº8åï¼çå¯è°å·®ä¹æ¯«åï¼å¤±ä¹åéã</p> 417 418<h3>åä¸ä¸è¦å»Copy代ç </h3> 419 420<p>æå¨åãiOSæµè¯æåãçè¿ç¨ä¸ï¼ä¹¦ç¨¿ç»è¿äºå¥½å 次修æ¹ï¼ä½æ¯ä¾ç¶è¿æ¯è½åç°ä¸äºéå«åãæåååºå·²ç»æ²¡æåæ³æ½åäºï¼åªè½è®¤ççæå®ä¾ä»£ç å好äºãæä»¥ï¼æé½å¾è®¤ççåç示ä¾ä»£ç ãä¿è¯ææç代ç 齿¯è¿è¡è¿ï¼å¹¶ä¸æ²¡æé®é¢çæåè¿å°ä¹¦ä¸ãâ代ç è¿è¡è¿ï¼ä¸ä»£è¡¨æ²¡æé®é¢ãâè¿æ¯æµè¯å·¥ç¨å¸ç»å¸¸æ¿æ¥æè²å¼åå·¥ç¨å¸çè¯ï¼èªå·±ä¹ç¯é误äºã</p> 421 422<p>å¨ä¹¦ä¸ç第43é¡µï¼æä¸æ®µä»£ç ä¸ç注éæé®é¢ã</p> 423 424<p><img src="http://ww1.sinaimg.cn/mw690/9d98efcctw1egywk3rum6j21k00umn85.jpg" title="43页ä¸é误æªå¾" alt="alt text" /></p> 425 426<p>注éåéäºï¼å¾ææ¾è¿ä¸æ¯ä¸ä¸ªç¬è¯¯ãè¿æ¯ä¸ä¸ªå¤å¶ä¹å没æä¿®æ¹å®å ¨çé误ãå¨ç¼å代ç çè¿ç¨ä¸åä¸ä¸è¦å»Copy代ç ãæ²¡æCopy就没æä½çº§é误ã</p> 427 428<h3>iOS 7çæ¹å¨å¸¦æ¥çé®é¢</h3> 429 430<p>卿¬ä¹¦ä¸ä½¿ç¨äºå¾å¤æ¬¡Recipseç¨åºï¼Recipseç¨åºæ¯å®æ¹ææ¡£ä¸ç¨æ¥ä»ç»UI Automationç示ä¾ç¨åºãæ¬ä¹¦çç¬¬å «ç« ä»ç»KIFæ¶ï¼ä¹æ¯ä½¿ç¨äºRecipseç¨åºæ¥å®æä¸äºåè½æµè¯ãå½éè¦å é¤Recipseç¨åºä¸çèåæ¶ï¼ç³»ç»æä¾çTableViewCell伿å é¤ç¡®è®¤ã使¯é£ä¸ªç¡®è®¤çæé®çä¸äºå±æ§æäºååãå¦å¾æç¤ºã</p> 431 432<p><img src="http://ww3.sinaimg.cn/mw690/9d98efcctw1egyy44qotaj21z41721kx.jpg" title="å é¤ç¡®è®¤æªå¾" alt="alt text" /></p> 433 434<p>å¾ä¸çº¢æ¡å ç屿§åiOS 6ä¸ç屿§å·²ç»ææååã</p> 435 436<p>å¨ iOS 7.0以ä¸ççæ¬ï¼å é¤ç¡®è®¤æé®ç屿§æ¯ Deleteã使¯å¨iOS 6æè 5ä¸ï¼å é¤ç¡®è®¤æé®ç屿§æ¯ Confirm Deletion for xxxï¼xxx æ¯ TableCellçname屿§ï¼</p> 437 438<p>æä»¥ä¸ºäºæµè¯è½å¨iOSææçç³»ç»ä¸é½è½å®ç¾çè¿è¡ï¼ä»£ç å¯ä»¥è¿æ ·ä¿®æ¹ï¼</p> 439 440<figure class='code'><figcaption><span>Objective-C</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 441<span class='line-number'>2</span> 442<span class='line-number'>3</span> 443<span class='line-number'>4</span> 444<span class='line-number'>5</span> 445<span class='line-number'>6</span> 446<span class='line-number'>7</span> 447<span class='line-number'>8</span> 448</pre></td><td class='code'><pre><code class='objectivec'><span class='line'><span class="c1">//ç¹å»å é¤ç¡®è®¤æé®</span> 449</span><span class='line'><span class="k">if</span> <span class="p">([[[</span><span class="n">UIDevice</span> <span class="n">currentDevice</span><span class="p">]</span> <span class="n">systemVersion</span><span class="p">]</span> <span class="n">floatValue</span><span class="p">]</span> <span class="o"><</span> <span class="mf">7.0</span><span class="p">)</span> <span class="p">{</span> 450</span><span class='line'> <span class="p">[</span><span class="n">tester</span> <span class="nl">tapViewWithAccessibilityLabel:</span><span class="s">@"Confirm Deletion for aaa"</span> 451</span><span class='line'>
451 <span class="nl">traits:</span><span class="n">UIAccessibilityTraitButton</span><span class="p">];</span> 452</span><span class='line'><span class="p">}</span> <span class="k">else</span> <span class="p">{</span> 453</span><span class='line'> <span class="p">[</span><span class="n">tester</span> <span class="nl">tapViewWithAccessibilityLabel:</span><span class="s">@"Delete"</span> 454</span><span class='line'> <span class="nl">traits:</span><span class="n">UIAccessibilityTraitButton</span><span class="p">];</span> 455</span><span class='line'><span class="p">}</span> 456</span></code></pre></td></tr></table></div></figure> 457 458 459<p>å½ç¶ï¼å ä¸ºå±æ§æ¯å¾å¤èªå¨åæµè¯å·¥å ·é½è¦ç¨å°çï¼æä»¥ï¼å¤§å®¶å¨iOS6å级å°iOS7æ¶é½ä¼æè¿ä¸ªé®é¢ãå½ä½ 使ç¨çUI Automationçæ¶åï¼ä¹ä¼éå°è¿ä¸ªé®é¢ãå½ç¶ï¼å¨UI Automationçæ¶åï¼è¿ææ´å¤§çä¸ä¸ªé®é¢ãå¨iOS 7ç³»ç»ä¸ï¼ç±äºAppleå ¬å¸çé®é¢ï¼å¯¼è´UI Automationçæææ»å¨æä½æ æã</p> 460 461<p>ç±äºiOS7䏿»å¨æä½æ æï¼æä»¥ï¼åªè½ä½¿ç¨å«çæä½è·¯å¾æ¥è¿è¡å é¤ã</p> 462 463<p>宿´ç代ç å¦ä¸ï¼</p> 464 465<figure class='code'><figcaption><span>JavaScript</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 466<span class='line-number'>2</span> 467<span class='line-number'>3</span> 468<span class='line-number'>4</span> 469<span class='line-number'>5</span> 470<span class='line-number'>6</span> 471<span class='line-number'>7</span> 472<span class='line-number'>8</span> 473<span class='line-number'>9</span> 474</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">test</span><span class="p">(</span><span class="s2">"å é¤åææ·»å ç饺åèåï¼éè¿å¤ææ»èåæ°éçå忥夿æµè¯æ¯å¦æå"</span><span class="p">,</span> 475</span><span class='line'> <span class="kd">function</span><span class="p">(){</span> 476</span><span class='line'> <span class="nx">oldCellsLength</span> <span class="o">=</span> <span class="nx">Finder</span><span class="p">.</span><span class="nx">findElementByName</span><span class="p">(</span><span class="s2">"Empty list"</span><span class="p">).</span><span class="nx">cells</span><span class="p">().</span><span class="nx">length</span> 477</span><span class='line'> <span class="nx">Finder</span><span class="p">.</span><span class="nx">findElementByName</span><span class="p">(</span><span class="s2">"Edit"</span><span class="p">).</span><span class="nx">tap</span><span class="p">();</span> 478</span><span class='line'> <span class="nx">Finder</span><span class="p">.</span><span class="nx">findElementByName</span><span class="p">(</span><span class="s2">"Delete 饺å"</span><span class="p">).</span><span class="nx">tap</span><span class="p">();</span> 479</span><span class='line'> <span class="nx">Finder</span><span class="p">.</span><span class="nx">findElementByName</span><span class="p">(</span><span class="s2">"饺å"</span><span class="p">).</span><span class="nx">buttons</span><span class="p">()[</span><span class="mi">0</span><span class="p">].</span><span class="nx">tap</span><span class="p">();</span> 480</span><span class='line'> <span class="nx">newCellsLength</span> <span class="o">=</span> <span class="nx">Finder</span><span class="p">.</span><span class="nx">findElementsByClassType</span><span class="p">(</span><span class="s2">"TableCell"</span><span class="p">).</span><span class="nx">length</span> 481</span><span class='line'> <span class="nx">assertEquals</span><span class="p">(</span><span class="nx">newCellsLength</span><span class="p">,</span><span class="nx">oldCellsLength</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> 482</span><span class='line'> <span class="p">}</span> 483</span></code></pre></td></tr></table></div></figure> 484 485 486<p>以ä¸ä¸¤å¤éè¦è¿è¡ä»£ç æ´æ¹çå°æ¹ï¼é½æ¯Appleå级iOS7以åï¼éè¦é对iOS7è¿è¡çä¸äºå®¹éå¤çãéè¦å®¹éç主è¦ç±2å¤ï¼</p> 487 488<ol> 489<li><p>iOS 7 ä¸ TableCellsä¸èªå¸¦çå 餿é®çAccessbility屿§åçäºååãæåæ¥ç âConfirm Deletion for xxxï¼xxx æ¯ TableCellçname屿§ï¼â åå为 âDeleteâã</p></li> 490<li><p>UI Autoamtionçæææ»å¨ç¸å ³çæå¿æ æã</p></li> 491</ol> 492 493 494<p>é对以ä¸çå 容éè¦è¿è¡iOS7ç¸å ³çéé ãéé æ¹æ³è¯·ä»ç»é 读代ç ããiOSæµè¯æåãåºççæ¶åï¼iOS7å·²ç»åäºï¼ä½æ¯æªè½å¯¹iOS7ä¸çå 容è¿è¡å ¨é¢çå ¼å®¹ï¼å¨æ¤è¡¨ç¤ºæ·±æ·±çææã</p> 495</div> 496 497 498 499 500 </article> 501 502
503 <article> 504 505 <header> 506 507 <h1 class="entry-title"><a href="/blog/ios-testframework.html">è¿äºå¹´ç¨è¿çiOSæµè¯æ¡æ¶</a></h1> 508 509 510 <p class="meta"> 511 512 513 514 515 516 517 518 519 520 521 522 523<time datetime="2014-01-16T00:37:00+08:00" pubdate data-updated="true">Jan 16<span>th</span>, 2014</time> 524 525 </p> 526 527 </header> 528 529 530 <div class="entry-content"><p> iOSèªå¨åæµè¯ä¸ç´å¾ç¥ç§ï¼å¾å¤äººé½å¨æ¢ç´¢åæ¾å¯»æå¼ºå¤§çé£ä¸æ¬¾èªå¨åæµè¯å·¥å ·ã个人è§ç¹ï¼æ²¡ææå¼ºå¤§åªææéåï¼éå以å使ç¨çç»äºèªç¶åè½å¼ºå¤§äºã</p> 531 532<p> å卿£æä¹åçå å¥åºè¯ã说å°åè½èªå¨åæµè¯ä¸è¬ç¹æåºäºUIå±é¢çèªå¨åï¼æ¬æä¸ä»ç»çèªå¨åæµè¯æ¡æ¶é½æ¯UIèªå¨åæµè¯æ¡æ¶ãæ´å¤§æ¦å¿µçèªå¨åæµè¯ä»¥åææ¶é´å详ç»ä»ç»å§ã说å°UIèªå¨åæµè¯ï¼å°±ä¼æä¸åçä¸äºå£°é³ã说ä»ä¹UIèªå¨åæµè¯æå ¥äº§åºæ¯ä½ï¼UIååå¿«èæ¬ç»´æ¤ææ¬é«çãå ¶å®ï¼è¿æ¯ä¸ä¸ªæä¹çå¾ UIèªå¨åæµè¯é®é¢ã个人认为ééçUIèªå¨åæµè¯æå ¥äº§åºæ¯è¿æ¯å¾é«çï¼å ·ä½âééâæä¹çè§£éè¦çå ·ä½çåºæ¯ãå¦æä½ è§å¾UIèªå¨å䏿 æ¯å¤ï¼é£ä¹çå°è¿éå°±å¯ä»¥åä¸å«å¾ä¸çäºã</p> 533 534<p> iOSå°åºæå¤å°æµè¯æ¡æ¶ï¼å¤§å®¶ä¸ç´å¨æ»ç»ï¼ä¹åstackoverflow䏿ä¸ç¯ç¥å¸æ»ç»è¿ä¸ä¸20ç§ï¼å½ç¶ä¸åªæ¯UIèªå¨åæµè¯æ¡æ¶ï¼è¿å æ¬åå æµè¯æ¡æ¶ä»ä¹çãï¼é¾æ¥æ¾ä¸å°äºï¼ç±äºæ¶é´æ¯è¾èäºå¾å¤å·¥å ·å·²ç»ä¸ç»´æ¤æè å¾å°äººä½¿ç¨ï¼ä¸çä¹ç½¢ï¼</p> 535 536<p> æè¿åç°äºä¸ç¯Blog <a href="http://watirmelon.com/2013/11/04/the-current-state-of-ios-automated-functional-testing/" title="Title">The current state of iOS automated functional testing</a>æ»ç»äºä¸äºUIèªå¨åæ¡æ¶ï¼æ»ç»çæ¯è¾å°ä½æ¨èç»å¤§å®¶ãç»åèªå·±ç使ç¨ç»éªï¼å¯¹è¯¥Blogè¿è¡ä¸äºè¡¥å ï¼å¸ææ¨å欢ã</p> 537 538<p>æç §iOSèªå¨åæµè¯æ¡æ¶çå®ç°åçæ¥ååï¼iOSèªå¨åæµè¯æ¡æ¶å¤§è´å¯ä»¥å为两个大类4ç§ç±»åï¼</p> 539 540<ul> 541<li>UI Automationç³» 542 543<ul> 544<li>æ©å±åUI Automation</li> 545<li>驱å¨åUI Automation</li> 546</ul> 547</li> 548<li>é UI Automationç³» 549 550<ul> 551<li>ç§æAPIå</li> 552<li>æ³¨å ¥ç¼è¯å</li> 553</ul> 554</li> 555</ul> 556 557 558<h2>UI Automation</h2> 559 560<p>UI Automationæ¯Apple宿¹æä¾çUIèªå¨åæµè¯çè§£å³æ¹æ³ï¼è½ç¶ç´æ¥ä½¿ç¨é常ä¸ç½ï¼ä½æ¯è¿ä¸å¾ä¸è¯´ãè½ç¶ä¸å¥½ç¨ï¼ä½æ¯ä½ä¸ºä¸äºå·¥å ·çåºå±å®ç°è¿æ¯éè¦äºè§£çã<a href="https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/_index.html" title="Title">宿¹æç¨</a> å <a href="https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html" title="Title">ç¸å ³APIææ¡£</a> å¯ä»¥æ¹ä¾¿æ¥é </p> 561 562<h3>æ©å±åUI Automation</h3> 563 564<p><a href="https://github.com/alexvollmer/tuneup_js" title="title">TuneupJs</a>æ¯ææ©çiOSèªå¨åæµè¯å·¥å ·ï¼ä»¥JavaScriptæ©å±åºæ¹æ³æä¾äºå¾å¤å¥½ç¨jså·¥å ·ï¼æéè¦çæ¯æä¾äºè¶ ç®æ´çåå æµè¯æ¡æ¶åæç»ç»§æ¿è§£å³æ¹æ¡ã</p> 565 566<p><a href="https://github.com/douban/ynm3k" title="title">ynm3k</a>æ¯ç¬è ç»´æ¤çiOSèªå¨åæµè¯æ¡æ¶ï¼åé´æè 说æè¢äºå¾å¤TuneUpJsçæ³æ³ï¼å¨å ¶åºç¡ä¸å å ¥äºUIæ§ä»¶å®ä½çå¾å¤æ¹æ³ï¼è®©æµè¯èæ¬æ´å ç®å便æ·ãå½ç¶ä¹åè¿æåç»çç»´æ¤è®¡åï¼è¿äºåæç996以åä¼å¼å§å®æ½ã</p> 567 568<p>å¦æä½ åç±è¿ç§ç±»åçæµè¯æ¡æ¶ï¼æçå¿çæ¨èynm3kãå 为TuneUpJSå·²ç»ä¸ç»´æ¤äºï¼ynm3kè¿ä¼åä¸äºå¥½ç©çåè½ãæå ³é®çæ¯æè§å¾ynm3kçUIæ§ä»¶å®ä½è¯å«åè½çç徿£ãï¼èçåçäºè¿ä¹é¿æ¶é´è¿è¯·å¤§å®¶è§è° ï¼</p> 569 570<h3>驱å¨åUI Automation</h3> 571 572<p>驱å¨åUI Automation å¨èªå¨åæµè¯åºå±ä½¿ç¨äºUI Automationåºï¼éè¿TCPéä¿¡çæ¹å¼é©±å¨UI Automationæ¥å®æèªå¨åæµè¯ãéè¿è¿ç§æ¹å¼ï¼ç¼è¾èæ¬çè¯è¨ä¸å¨å±éäºJavaScriptï¼ç论ä¸è®²å¯ä»¥æ¯ä»»ä½ä¸ç§è¯è¨ãæä»¥æäº<a href="http://ios-driver.github.io/ios-driver/index.html">iOSDriver</a>å<a href="http://appium.io/">Appium</a>.</p> 573 574<p>iOSDriveråAppiumè¿å ¼å®¹äºWebDriverçJson Wire Protocolåè®®ï¼æå³çä½ å¯ä»¥åWebDriverèæ¬æ¥å®æiOSèªå¨åæµè¯ãå½ç¶å¨ææºç«¯çä¸äºæä½åWeb端æ¯ä¸åçï¼iOSDriveråAppium齿©å±äºç¸å ³çåè½ãiOSDriveréæ©äºå¤å å ¥Javaè¯è¨Jarå çæ¹å¼æ¯æï¼èAppiumåéæ©äºéè¿WebDriveræ³¨å ¥JavaScriptçæ¹å¼æ¯æãiOSDriverçå®ç°æ¹å¼å³å®äºåªè½ä½¿ç¨Javaè¯è¨ç¼è¾èæ¬ï¼èAppiumåæ¯ææ´å¤çè¯è¨ã</p> 575 576<p>å½ç¶è®©æçæ£éæ©Appiumçåå æ¯å 为Appiumæ´å 轻便æç¨ä¸äºãå¦æä½ ä¸ç»å¸¸ç©Javaï¼ä½¿ç¨iOSDriverçæ¶åä¸å®ä¼å¨ç¯å¢è®¾ç½®æ¹é¢å¡å¾é
576¿çæ¶é´ã</p> 577 578<h3>ç§æAPIå</h3> 579 580<p>ç´æ¥ä½¿ç¨ç§æAPI对UIçé¢è¿è¡æä½æ¯æç®æ´ææçèªå¨åæµè¯æ¹å¼ãç§æAPIç»åiOSåå æµè¯æ¡æ¶OCUnitçç»åå®å ¨é常æ£ï¼è³å°å¯¹iOSå¼åå·¥ç¨å¸æ¥è¯´ãå¨è¿ç§ç±»åçæµè¯æ¡æ¶ä¸ï¼<a href="https://github.com/kif-framework/KIF">KIF</a>æ¯å¿ é¡»ä»ç»çãåå å¾ç®åï¼Googleå¨ä½¿ç¨ã对äºé£äºå¯¹Googleæ çç±å´æç人们ï¼èµ¶ç´§ç¨èµ·æ¥å§ã</p> 581 582<p>ç¬è å ³æ³¨äºKIF䏿®µæ¶é´ï¼èµ·å1.0çæ¬çæ¶åï¼çå¿çä¸å¥½ç¨ãå½ç¶å·¥å ·çç»´æ¤è 乿è¯å°äºè¿ä¸ªæ¹é¢çé®é¢ï¼æ¨åºäºKIFç2.0çæ¬ï¼æ´æ°äºå¾å¤çAPIãå¨2.0çæ¬æ¶ï¼è¿ä¸éã妿æ³å纯UIç颿ä½çè¯ï¼ä¸æ¨è使ç¨KIFã</p> 583 584<h3>æ³¨å ¥ç¼è¯å</h3> 585 586<p>æ³¨å ¥ç¼è¯åæ¯æå¨ç¼è¯æ¶æ³¨å ¥ä¸ä¸ªServerå°Appå é¨ï¼éè¿Server对å¤éä¿¡å®æUIæä½æä»¤çæ§è¡ãå ¶ä¸æèåç代表为<a href="http://www.testingwithfrank.com/">Frank</a>å<a href="http://calaba.sh/">Calabash</a>. å®ä»¬è¿æ¯BDDæµè¯æ¡æ¶çæ°åºä»£è¡¨ãç»´æ¤å¤§åä½é½æ¯å ¨çç¥åçææ·å¨è¯¢å ¬å¸ã忬¢cucumberårubyç人å¯ä»¥èèã</p> 587 588<p>大æ¦ä»ç»å°è¿éï¼ä¹åä¼éç»è¿è¡æ¯ç§ç±»åç详ç»ä»ç»ã</p> 589</div> 590 591 592 593 594 </article> 595 596 597 <article> 598 599 <header> 600 601 <h1 class="entry-title"><a href="/blog/applescript-hong-fa-mo-ni-qi-nei-cun-gao-jing.html">UI Automation ä¸è§¦åiOS模æå¨å åè¦å</a></h1> 602 603 604 <p class="meta"> 605 606 607 608 609 610 611 612 613 614 615 616 617<time datetime="2014-01-09T19:18:00+08:00" pubdate data-updated="true">Jan 9<span>th</span>, 2014</time> 618 619 </p> 620 621 </header> 622 623 624 <div class="entry-content"><p>å¨UI Automationçapi䏿²¡ææä¾æ¨¡æå åè¦åçæ¥å£ãå¨Monkeyæµè¯çè¿ç¨ä¸ MemoryWarningè¿æ¯é常æç¨çãæä»¥éè¦æ³åæ³èªå·±å°ä¸ä¸ªsimulateMemoryWarningæ¥å£ã</p> 625 626<p>ç»è¿è°ç ï¼å³å®éç¨AppleScriptæ¥å®ç°åè½ï¼ç¶åå¨UI Automationä¸ä½¿ç¨host.performTaskWithPathArgumentsTimeoutè°ç¨AppleScriptæ¹å¼æ¥å®ç°ã</p> 627 628<p>è°è¯AppleScriptãå¨<a href="http://stackoverflow.com/questions/2784892/simulate-memory-warnings-from-the-code-possible" title="Title">stackoverflow</a> ä¸ï¼å¯ä»¥æ¾å°OCåAppleScriptçæ¬çå ååè¦å®ç°ãå ¶ä¸AppleScriptçå®ç°ä¸ºï¼</p> 629 630<figure class='code'><figcaption><span>AppleScript simulate memory warning</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 631<span class='line-number'>2</span> 632<span class='line-number'>3</span> 633<span class='line-number'>4</span> 634<span class='line-number'>5</span> 635<span class='line-number'>6</span> 636<span class='line-number'>7</span> 637<span class='line-number'>8</span> 638<span class='line-number'>9</span> 639<span class='line-number'>10</span> 640<span class='line-number'>11</span> 641</pre></td><td class='code'><pre><code class='applescript'><span class='line'><span class="k">tell</span> <span class="nb">application</span> <span class="s2">"System Events"</span> 642</span><span class='line'> <span class="k">tell</span> <span class="nv">process</span> <span class="s2">"iPhone Simulator"</span> 643</span><span class='line'> <span class="k">tell</span> <span class="na">menu</span> <span class="nv">bar</span> <span class="mi">1</span> 644</span><span class='line'> <span class="k">tell</span> <span class="na">menu</span> <span class="nv">bar</span> <span class="nb">item</span> <span class="s2">"Hardware"</span> 645</span><span class='line'> <span class="k">tell</span> <span class="na">menu</span> <span class="s2">"Hardware"</span> 646</span><span class='line'> <span class="nv">click</span> <span class="na">menu</span> <span class="nb">item</span> <span class="s2">"Simulate Memory Warning"</span> 647</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 648</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 649</span><span class='line'>
649 <span class="k">end</span> <span class="k">tell</span> 650</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 651</span><span class='line'><span class="k">end</span> <span class="k">tell</span> 652</span></code></pre></td></tr></table></div></figure> 653 654 655<p>ç®åçè°è¯åç°ä¸ç¨³å®ï¼æå¥½å å ¥ä¸ä¸ä»£ç ï¼</p> 656 657<figure class='code'><figcaption><span>AppleScript make sure iphone simulator activate</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 658<span class='line-number'>2</span> 659<span class='line-number'>3</span> 660</pre></td><td class='code'><pre><code class='applescript'><span class='line'><span class="k">tell</span> <span class="nb">application</span> <span class="s2">"iPhone Simulator"</span> 661</span><span class='line'> <span class="nb">activate</span> 662</span><span class='line'><span class="k">end</span> <span class="k">tell</span> 663</span></code></pre></td></tr></table></div></figure> 664 665 666<p>ä¹åçèæ¬åªè½æ¯æè±æçæä½ç³»ç»ï¼ä¸ºäºå ¼å®¹ä¸ææä½ç³»ç»ï¼å次å å ¥ä»£ç ï¼</p> 667 668<figure class='code'><figcaption><span>AppleScript get os language & simulate memory warning</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 669<span class='line-number'>2</span> 670<span class='line-number'>3</span> 671<span class='line-number'>4</span> 672<span class='line-number'>5</span> 673<span class='line-number'>6</span> 674<span class='line-number'>7</span> 675<span class='line-number'>8</span> 676<span class='line-number'>9</span> 677<span class='line-number'>10</span> 678<span class='line-number'>11</span> 679<span class='line-number'>12</span> 680<span class='line-number'>13</span> 681<span class='line-number'>14</span> 682<span class='line-number'>15</span> 683<span class='line-number'>16</span> 684<span class='line-number'>17</span> 685<span class='line-number'>18</span> 686<span class='line-number'>19</span> 687<span class='line-number'>20</span> 688<span class='line-number'>21</span> 689<span class='line-number'>22</span> 690<span class='line-number'>23</span> 691</pre></td><td class='code'><pre><code class='applescript'><span class='line'><span class="k">on</span> <span class="nv">get_language</span><span class="p">()</span> 692</span><span class='line'> <span class="no">return</span> <span class="nv">user</span> <span class="nv">locale</span> <span class="k">of</span> <span class="p">(</span><span class="k">get</span> <span class="nb">system info</span><span class="p">)</span> 693</span><span class='line'><span class="k">end</span> <span class="nv">get_language</span> 694</span><span class='line'><span class="k">set</span> <span class="nv">menubar</span> <span class="k">to</span> <span class="s2">"Hardware"</span> 695</span><span class='line'><span class="k">set</span> <span class="nv">menuclick</span> <span class="k">to</span> <span class="s2">"Simulate Memory Warning"</span> 696</span><span class='line'><span class="k">if</span> <span class="nv">get_language</span><span class="p">()</span> <span class="o">=</span> <span class="s2">"zh_CN"</span> <span class="k">then</span> 697</span><span class='line'> <span class="k">set</span> <span class="nv">menubar</span> <span class="k">to</span> <span class="s2">"硬件"</span> 698</span><span class='line'> <span class="k">set</span> <span class="nv">menuclick</span> <span class="k">to</span> <span class="s2">"模æå åè¦å"</span> 699</span><span class='line'><span class="k">end</span> <span class="k">if</span> 700</span><span class='line'><span class="k">tell</span> <span class="nb">application</span> <span class="s2">"iPhone Simulator"</span> 701</span><span class='line'> <span class="nb">activate</span> 702</span><span class='line'><span class="k">end</span> <span class="k">tell</span> 703</span><span class='line'><span class="k">tell</span> <span class="nb">application</span> <span class="s2">"System Events"</span> 704</span><span class='line'> <span class="k">tell</span> <span class="nv">process</span> <span class="s2">"iPhone Simulator"</span> 705</span><span class='line'>
705 <span class="k">tell</span> <span class="na">menu</span> <span class="nv">bar</span> <span class="mi">1</span> 706</span><span class='line'> <span class="k">tell</span> <span class="na">menu</span> <span class="nv">bar</span> <span class="nb">item</span> <span class="nv">menubar</span> 707</span><span class='line'> <span class="k">tell</span> <span class="na">menu</span> <span class="nv">menubar</span> 708</span><span class='line'> <span class="nv">click</span> <span class="na">menu</span> <span class="nb">item</span> <span class="nv">menuclick</span> 709</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 710</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 711</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 712</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 713</span><span class='line'><span class="k">end</span> <span class="k">tell</span> 714</span></code></pre></td></tr></table></div></figure> 715 716 717<p>ä¿å好æä»¶ä»¥åï¼æ¾å ¥åºå®çè·¯å¾ï¼ä½¿ç¨UI Automationè°ç¨ï¼å¯ä»¥åèä¸ä¸ä»£ç ï¼</p> 718 719<figure class='code'><figcaption><span>JavaScript UI Automation </span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 720<span class='line-number'>2</span> 721<span class='line-number'>3</span> 722<span class='line-number'>4</span> 723<span class='line-number'>5</span> 724<span class='line-number'>6</span> 725<span class='line-number'>7</span> 726<span class='line-number'>8</span> 727<span class='line-number'>9</span> 728<span class='line-number'>10</span> 729</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">simulateMemoryWarning</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span> 730</span><span class='line'> <span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">UIATarget</span><span class="p">.</span><span class="nx">localTarget</span><span class="p">();</span> 731</span><span class='line'> <span class="kd">var</span> <span class="nx">host</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">host</span><span class="p">();</span> 732</span><span class='line'> <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">host</span><span class="p">.</span><span class="nx">performTaskWithPathArgumentsTimeout</span><span class="p">(</span><span class="s2">"/usr/bin/osascript"</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">scriptPath</span><span class="o">+</span><span class="s2">"SMW.scpt"</span><span class="p">],</span> <span class="mi">5</span><span class="p">);</span> 733</span><span class='line'> <span class="k">if</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">exitCode</span><span class="o">==</span><span class="mi">0</span><span class="p">){</span> 734</span><span class='line'> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> 735</span><span class='line'> <span class="p">}</span><span class="k">else</span><span class="p">{</span> 736</span><span class='line'> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span> 737</span><span class='line'> <span class="p">}</span> 738</span><span class='line'><span class="p">}</span> 739</span></code></pre></td></tr></table></div></figure> 740 741 742<p>好çï¼åè½å°±åå®äºãè¿ç®é¡ºå©ï¼ä½æ¯å¦æä½ æ¯ä¸ä¸ªgeekçè¯ï¼ä¼è§å¾ä¹åçAppleScript䏿䏿®µå¾èç¼ç代ç ãæ²¡éæä¹è§å¾èç¼ï¼å¹¶ä¸æäºèå¤ä¹è§å¾èç¼ï¼æä»¥æä¸ä¸ªç°æç彿°å¯ä»¥ä½¿ç¨ï¼</p> 743 744<figure class='code'><figcaption><span>AppleScript use menu_click function</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span> 745<span class='line-number'>2</span> 746<span class='line-number'>3</span> 747<span class='line-number'>4</span> 748<span class='line-number'>5</span> 749<span class='line-number'>6</span> 750<span class='line-number'>7</span> 751<span class='line-number'>8</span> 752<span class='line-number'>9</span> 753<span class='line-number'>10</span> 754<span class='line-number'>11</span> 755<span class='line-number'>12</span> 756<span class='line-number'>13</span> 757<span class='line-number'>14</span> 758<span class='line-number'>15</span> 759<span class='line-number'>16</span> 760<span class='line-number'>17</span> 761<span class='line-number'>18</span> 762<span class='line-number'>19</span> 763<span class='line-number'>20</span> 764<span class='line-number'>21</span> 765<span class='line-number'>22</span> 766<span class='line-number'>23</span> 767<span class='line-number'>24</span> 768<span class='line-number'>25</span> 769<span class='line-number'>26</span> 770<span class='line-number'>27</span> 771<span class='line-number'>28</span> 772<span class='line-number'>29</span> 773<span class='line-number'>30</span> 774</pre></td><td class='code'><pre><code class='applescript'><span class='line'><span class="k">on</span> <span class="nv">menu_click</span><span class="p">(</span><span class="nv">mList</span><span class="p">)</span> 775</span><span class='line'> <span class="k">local</span> <span class="nv">appName</span><span class="p">,</span> <span class="nv">topMenu</span><span class="p">,</span> <span class="nv">r</span> 776</span><span class='line'> <span class="c">-- Validate our input</span> 777</span><span class='line'> <span class="k">if</span> <span class="nv">mList</span>'s <span class="nv">length</span> <span class="o"><</span> <span class="mi">3</span> <span class="k">
777then</span> <span class="k">error</span> <span class="s2">"Menu list is not long enough"</span> 778</span><span class='line'> <span class="c">-- Set these variables for clarity and brevity later on</span> 779</span><span class='line'> <span class="k">set</span> <span class="p">{</span><span class="nv">appName</span><span class="p">,</span> <span class="nv">topMenu</span><span class="p">}</span> <span class="k">to</span> <span class="p">(</span><span class="nb">items</span> <span class="mi">1</span> <span class="nb">through</span> <span class="mi">2</span> <span class="k">of</span> <span class="nv">mList</span><span class="p">)</span> 780</span><span class='line'> <span class="k">set</span> <span class="nv">r</span> <span class="k">to</span> <span class="p">(</span><span class="nb">items</span> <span class="mi">3</span> <span class="nb">through</span> <span class="p">(</span><span class="nv">mList</span>'s <span class="nv">length</span><span class="p">)</span> <span class="k">of</span> <span class="nv">mList</span><span class="p">)</span> 781</span><span class='line'> <span class="c">-- This overly-long line calls the menu_recurse function with</span> 782</span><span class='line'> <span class="c">-- two arguments: r, and a reference to the top-level menu</span> 783</span><span class='line'> <span class="k">tell</span> <span class="nb">application</span> <span class="s2">"System Events"</span> <span class="k">to</span> <span class="k">my</span> <span class="nv">menu_click_recurse</span><span class="p">(</span><span class="nv">r</span><span class="p">,</span> <span class="p">((</span><span class="nv">process</span> <span class="nv">appName</span><span class="p">)</span>'s <span class="se">¬</span> 784</span><span class='line'> <span class="p">(</span><span class="na">menu</span> <span class="nv">bar</span> <span class="mi">1</span><span class="p">)</span>'s <span class="p">(</span><span class="na">menu</span> <span class="nv">bar</span> <span class="nb">item</span> <span class="nv">topMenu</span><span class="p">)</span>'s <span class="p">(</span><span class="na">menu</span> <span class="nv">topMenu</span><span class="p">)))</span> 785</span><span class='line'><span class="k">end</span> <span class="nv">menu_click</span> 786</span><span class='line'><span class="k">on</span> <span class="nv">menu_click_recurse</span><span class="p">(</span><span class="nv">mList</span><span class="p">,</span> <span class="nv">parentObject</span><span class="p">)</span> 787</span><span class='line'> <span class="k">local</span> <span class="nv">f</span><span class="p">,</span> <span class="nv">r</span> 788</span><span class='line'> <span class="c">-- `f` = first item, `r` = rest of items</span> 789</span><span class='line'> <span class="k">set</span> <span class="nv">f</span> <span class="k">to</span> <span class="nb">item</span> <span class="mi">1</span> <span class="k">of</span> <span class="nv">mList</span> 790</span><span class='line'> <span class="k">if</span> <span class="nv">mList</span>'s <span class="nv">length</span> <span class="o">></span> <span class="mi">1</span> <span class="k">then</span> <span class="k">set</span> <span class="nv">r</span> <span class="k">to</span> <span class="p">(</span><span class="nb">items</span> <span class="mi">2</span> <span class="nb">through</span> <span class="p">(</span><span class="nv">mList</span>'s <span class="nv">length</span><span class="p">)</span> <span class="k">of</span> <span class="nv">mList</span><span class="p">)</span> 791</span><span class='line'> <span class="c">-- either actually click the menu item, or recurse again</span> 792</span><span class='line'> <span class="k">tell</span> <span class="nb">application</span> <span class="s2">"System Events"</span> 793</span><span class='line'> <span class="k">if</span> <span class="nv">mList</span>'s <span class="nv">length</span> <span class="ow">is</span> <span class="mi">1</span> <span class="k">then</span> 794</span><span class='line'> <span class="nv">click</span> <span class="nv">parentObject</span>'s <span class="na">menu</span> <span class="nb">item</span> <span class="nv">f</span> 795</span><span class='line'>
795 <span class="k">else</span> 796</span><span class='line'> <span class="k">my</span> <span class="nv">menu_click_recurse</span><span class="p">(</span><span class="nv">r</span><span class="p">,</span> <span class="p">(</span><span class="nv">parentObject</span>'s <span class="p">(</span><span class="na">menu</span> <span class="nb">item</span> <span class="nv">f</span><span class="p">)</span>'s <span class="p">(</span><span class="na">menu</span> <span class="nv">f</span><span class="p">)))</span> 797</span><span class='line'> <span class="k">end</span> <span class="k">if</span> 798</span><span class='line'> <span class="k">end</span> <span class="k">tell</span> 799</span><span class='line'><span class="k">end</span> <span class="nv">menu_click_recurse</span> 800</span><span class='line'><span class="k">tell</span> <span class="nb">application</span> <span class="s2">"iPhone Simulator"</span> 801</span><span class='line'> <span class="nb">activate</span> 802</span><span class='line'><span class="k">end</span> <span class="k">tell</span> 803</span><span class='line'><span class="nv">menu_click</span><span class="p">({</span><span class="s2">"iPhone Simulator"</span><span class="p">,</span> <span class="s2">"硬件"</span><span class="p">,</span> <span class="s2">"模æå åè¦å"</span><span class="p">})</span> 804</span></code></pre></td></tr></table></div></figure> 805 806 807<p>大æ¦ç©äºä¸ä¸AppleScriptï¼æè§è¯æ³æ¹é¢æç¹é¢ è¦ä¹åå¦è¿çè¯è¨ï¼ä½æ¯å¦æè½çç»äºä»¥åï¼å代ç å°±å说è¯ä¸ä¸ãæå ´è¶£çåå¦å¯ä»¥è¯è¯ã以ä¸ç¸å ³åè½ä»£ç å·²ç»å å ¥<a href="https://github.com/douban/ynm3k" title="Title">ynm3k</a>ä¸ãä¹å¯ä»¥ç´æ¥ä½¿ç¨çã</p> 808</div> 809 810 811 812 813 </article> 814 815 816 <article> 817 818 <header> 819 820 <h1 class="entry-title"><a href="/blog/octopress.html">æå¼å§åBlog</a></h1> 821 822 823 <p class="meta"> 824 825 826 827 828 829 830 831 832 833 834 835 836<time datetime="2013-05-08T23:01:00+08:00" pubdate data-updated="true">May 8<span>th</span>, 2013</time> 837 838 </p> 839 840 </header> 841 842 843 <div class="entry-content"><p>æ¯çï¼æå¼å§åBlogãä¹åä¸ç´æ³åï¼è¿æ ·å¯ä»¥æ²æ·ä¸äºä¸è¥¿ï¼ä½æ¯ä¸ç´æ²¡åã</p> 844 845<p>åé¦å·¥ä½åç¨ï¼åæµè¯å·¥ç¨å¸ä¹10å¹´äºï¼è¶åè¶è§å¾å¾å¤ä¸è¥¿æä¸å®ï¼å¾å¤é®é¢è§£å³ä¸äºãå½ç¶ï¼åäºBlogä¹è§£å³ä¸äºã</p> 846 847<p>æ ¢æ ¢æ¥å§ï¼ä¸åé½ä¼å¥½èµ·æ¥çï¼æ·±è¡¨æç ^_^ ï¼ã</p> 848 849<p>æ¬Blogä¸ºäºæ æ°ç«å¼ï¼ä¼éµå¾ªä»¥ä¸ååï¼</p> 850 851<ol> 852<li>å®è·µãæå¾å¤å®è·µéè¦æ²æ·æ»ç»ï¼å¸æè½èªå·±å®æç§¯ç´¯ãå¯è½æå¾å¤å®è·µå 容æé·åå«çï¼ä½æ¯å¯ä»¥ä¿è¯é½äº²æåè¿ï¼å¯ä»¥å®ç°ã</li> 853<li>åæ§½å°æãæµè¯æ¹é¢åå¨ç太å¤çæ§½ç¹ï¼å¯ä»¥åå¾å¤å¾å¤ãå¨åæ§½æ¶ï¼æä¼å°½å¯è½çä¿è¯å ¬æ£ï¼å°½éå¤ç说äºå®åç°è±¡ï¼å°½éå°ç表达è§ç¹ï¼åç»é£äºèªæç读è ã</li> 854</ol> 855 856</div> 857 858 859 860 861 </article> 862 863 <div class="pagination"> 864 865 <a href="/blog/archives">Blog Archives</a> 866 867 </div> 868</div> 869<aside class="sidebar"> 870 871 <section> 872 <h1>Recent Posts</h1> 873 <ul id="recent_posts"> 874 875 <li class="post"> 876 <a href="/blog/calabash-setup-and-simple-use.html">Calabash Android åå§ååä¸äºä½¿ç¨æå·§</a> 877 </li> 878 879 <li class="post"> 880 <a href="/blog/appium-chinese-input.html">Appium䏿è¾å ¥é®é¢çä¸äºæ¢ç´¢</a> 881 </li> 882 883 <li class="post"> 884 <a href="/blog/kan-wu.html">ãiOSæµè¯æåãå误ä¸</a> 885 </li> 886 887 <li class="post"> 888 <a href="/blog/ios-testframework.html">è¿äºå¹´ç¨è¿çiOSæµè¯æ¡æ¶</a> 889 </li> 890 891 <li class="post"> 892 <a href="/blog/applescript-hong-fa-mo-ni-qi-nei-cun-gao-jing.html">UI Automation ä¸è§¦åiOS模æå¨å åè¦å</a> 893 </li> 894 895 </ul> 896</section> 897 898<section> 899 <h1>GitHub Repos</h1> 900 <ul id="gh_repos"> 901 <li class="loading">Status updating…</li> 902 </ul> 903 904 <a href="https://github.com/houlianpi">@houlianpi</a> on GitHub 905 906
906<script type="text/javascript"> 907 $.domReady(function(){ 908 if (!window.jXHR){ 909 var jxhr = document.createElement('script'); 910 jxhr.type = 'text/javascript'; 911 jxhr.src = '/javascripts/libs/jXHR.js'; 912 var s = document.getElementsByTagName('script')[0]; 913 s.parentNode.insertBefore(jxhr, s); 914 } 915 916 github.showRepos({ 917 user: 'houlianpi', 918 count: 4, 919 skip_forks: true, 920 target: '#gh_repos' 921 }); 922 }); 923 </script>
923 924
924<script src="/javascripts/github.js" type="text/javascript"> </script>
924 925</section> 926 927 928<section> 929 <ul id="weibo"> 930 <li> 931 <iframe width="100%" height="200" class="share_self" frameborder="0" scrolling="no" src="http://widget.weibo.com/weiboshow/index.php?language=&width=0&height=200&fansRow=2&ptype=1&speed=0&skin=5&isTitle=1&noborder=1&isWeibo=0&isFans=0&uid=2644045772&verifier=eb301345&dpc=1"></iframe> 932 </li> 933 </ul> 934</section> 935<section> 936<div> 937
937<script type="text/javascript" src="http://www.douban.com/service/badge/mijun/?show=collection&n=2&columns=3" ></script>
937 938</div> 939</section> 940 941 942 943 944 945</aside> 946 947 </div> 948 </div> 949 <footer role="contentinfo"><p> 950 Copyright © 2015 - mijun(åè¸ç®) - 951 <span class="credit">Powered by <a href="http://houlianpi.github.com/">åè¸ç®</a></span> 952</p> 953 954</footer> 955 956 957 958 959 960 961 962 963 964 965 966 967</body> 968</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.