? ? appium支持用戶使用多種語言編寫測試用例。由于本人對java比較熟悉,所以采用了java語言。
? ? appium提供各種語言的客戶端類庫,我們先到官網(wǎng)(appium.io)下載java 客戶端類庫。下載完畢后,還需要準(zhǔn)備如下環(huán)境:Android 開發(fā)環(huán)境、jdk、Android sdk,請自行搭建,不再贅談。
? ? 打開Android studio,新增一個項目File--New--New Project,按提示一步步往下走,直到項目創(chuàng)建成功為止。
? ? 接著導(dǎo)入appium java client類庫包,我們可以通過在build.grable中直接添加依賴,然后重新構(gòu)建項目,也可以通過File--Project Structure進入到項目配置頁面,在Dependencies頁簽下導(dǎo)入本地類包。由于appium會引用到selenium的API,所以需要把selenium的jar包通過上述方式引入項目。到這里,是不是所有的jar包都導(dǎo)入完畢了呢。很遺憾并沒有,后續(xù)還需要導(dǎo)入其他jar包,而且jar包之間還有嚴(yán)格的版本配套規(guī)則。一旦版本不一致,用例就無法運行成功。下面是我導(dǎo)入的所有jar包,由于版本不一致,可能導(dǎo)入的jar包也不一樣,僅作參考:


? ? 當(dāng)然,我們也可以采用另外一種方式檢查是否遺漏jar包未導(dǎo)入,就是直接編寫appium自動化代碼,然后運行,根據(jù)報錯信息,去加入需要的jar包,我當(dāng)時就是通過這種方式把第一個demo跑起來的。以Android項目為例,代碼如下:
public void addition_isCorrect()throws Exception {
? ? ? ? AndroidDriver driver;
? ? ? ? DesiredCapabilities cap=new DesiredCapabilities();
? ? ? ? cap.setCapability("automationName", "Appium");//appium做自動化
? ? ? ? cap.setCapability("deviceName", "HUAWEI P10");//設(shè)備名稱
? ? ? ? cap.setCapability("platformName", "Android"); //安卓自動化還是IOS自動化
? ? ? ? cap.setCapability("platformVersion", "8.0"); //安卓操作系統(tǒng)版本
? ? ? ? cap.setCapability("udid", "SJE0217B30001350"); //設(shè)備的udid (adb devices 查看到的)
? ? ? ? cap.setCapability("appPackage","com.med.doc");//被測app的包名
? ? ? ? cap.setCapability("appActivity",".activity.splash.StartActivity");//被測app的入口Activity名稱
? ? ? ? cap.setCapability("unicodeKeyboard", "True"); //支持中文輸入
? ? ? ? cap.setCapability("resetKeyboard", "True"); //支持中文輸入,必須兩條都配置
? ? ? ? cap.setCapability("newCommandTimeout", "30"); //沒有新命令,appium30秒退出
? ? ? ? cap.setCapability("autoAcceptAlerts","true");
? ? ? ? driver =new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),cap);//把以上配置傳到appium服務(wù)端并連接手機
? ? ? ? driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//隱式等待
//通過resource name定位元素
? ? ? ? WebElement phone = driver.findElement(By.id("com.medtrust.doctor:id/login_pwd_edtTxt_phone"));//捕獲帳號輸入框
? ? ? ? phone.sendKeys("1111111");//輸入賬號
? ? ? ? WebElement pwd = driver.findElement(By.id("com.medtrust.doctor:id/login_pwd_edtTxt_pwd"));//捕獲密碼框
? ? ? ? pwd.sendKeys("1");
? ? ? ? TouchAction action =new TouchAction(driver);
? ? ? ? action.tap(885, 286).perform();//點擊登錄按鈕
? ? }
? ? 運行上述代碼時,請選擇Android Junit方式運行,可以通過Run--Edit Configurations為本方法 新增一個Android Junit運行方式。然后啟動appium服務(wù)端,并連接真機(由于有公司的測試機,所以沒試過模擬器運行的場景,模擬器場景不知道能否成功運行,建議連接真機)運行上述代碼。這個過程中,我遇到過下面兩種錯誤:
1.Exception in thread main java.lang.NoClassDefFoundError:xxx/xxx/xxx
顯而易見,運行的時候找不到某個類導(dǎo)致報錯,應(yīng)該是某個jar包未導(dǎo)入導(dǎo)致的,解決方法:在百度上搜索缺少的類名所屬的jar包,然后下載并導(dǎo)入到項目中即可。
2.java.lang.NoSuchMethodError:xxx.xxx.xxx.xxx
上述表示程序找得到需要的類,但是這個類沒有提供供程序調(diào)用的方法,應(yīng)該是jar包的版本不一致。到網(wǎng)上下載其他版本的jar包,檢查jar包中對應(yīng)類下有無此方法。若無則繼續(xù)下載其他版本驗證,若有則導(dǎo)入該jar包即可解決問題。要是導(dǎo)入后,仍無法解決問題,還有一種可能:該項目存在兩個不同版本但API相同的jar包。這種情況有個特點,就是有時能運行成功,有時會報上述錯誤(因為運行時會出現(xiàn)概率性調(diào)用到正確版本的jar包),解決方法就是刪掉其中一個版本jar包。
? ? 不斷重復(fù)運行上述代碼,直到編譯通過并能執(zhí)行代碼,則表示jar包已導(dǎo)入完整。當(dāng)然,接下來執(zhí)行代碼時,你可能會遇到下面幾個問題:
1.被測APP有些輸入框的輸入法無法彈出。
解決方案:由于執(zhí)行代碼時,appium會自動在手機上安裝一個appium輸入法,所以會導(dǎo)致原先的輸入法無法彈出。我們可以在手機設(shè)置里面把appium輸入法取消,這樣原先的輸入法又可以正常彈出使用了。
? ? 2.運行時,發(fā)現(xiàn)每次都會自動安裝appium setting 和unlock兩個APP,且啟動被測APP時,經(jīng)常會彈出權(quán)限請求的窗口,甚至導(dǎo)致用例執(zhí)行失敗。
? ? 解決方案:修改appium代碼,禁止appium安裝appium setting 和unlock,修改后,自動化用例就能正常執(zhí)行了。
? ? 修改appium代碼操作如下(直接在網(wǎng)上復(fù)制下來的):
? ? 這里以mac版本的appium為例子:(appium 根路徑有可能不一樣,請按照自身實際情況修改)
1、文件:?/usr/local/lib/node_modules/appium/node_modules/appium-android-driver/lib/driver.js,注釋以下幾句代碼
await?this.adb.uninstallApk(this.opts.appPackage);
await?helpers.installApkRemotely(this.adb,?this.opts);
await?helpers.resetApp(this.adb,?this.opts.app,?this.opts.appPackage,?this.opts.fastReset);
await?this.checkPackagePresent();
2、文件:/usr/local/lib/node_modules/appium/node_modules/appium-android-driver/build/lib/driver.js?注釋以下幾句代碼
return_regeneratorRuntime.awrap(_androidHelpers2['default'].resetApp(this.adb,?this.opts.app,?this.opts.appPackage,?this.opts.fastReset));
return_regeneratorRuntime.awrap(this.adb.uninstallApk(this.opts.appPackage));
return_regeneratorRuntime.awrap(_androidHelpers2['default'].installApkRemotely(this.adb,?this.opts));
return_regeneratorRuntime.awrap(this.checkPackagePresent());
3、文件:/usr/local/lib/node_modules/appium/node_modules/appium-android-driver/lib/android-helpers.js?注釋以下幾句代碼
await?adb.install(unicodeIMEPath,?false);
await?helpers.pushSettingsApp(adb);
await?helpers.pushUnlock(adb);
4、文件?/usr/local/lib/node_modules/appium/node_modules/appium-android-driver/build/lib/android-helpers.js?替換以下幾句代碼
return_regeneratorRuntime.awrap(helpers.initUnicodeKeyboard(adb))?替換為returncontext$1$0.abrupt('return',?defaultIME);
return_regeneratorRuntime.awrap(helpers.pushSettingsApp(adb));?替換為returncontext$1$0.abrupt('return',?defaultIME);
return_regeneratorRuntime.awrap(helpers.pushUnlock(adb));?替換為returncontext$1$0.abrupt('return',?defaultIME);
? ? 修改后,重新啟動appium服務(wù)器,再次連接真機,執(zhí)行上述腳本,此時腳本就能正常執(zhí)行了。