顯示具有 appium 標籤的文章。 顯示所有文章
顯示具有 appium 標籤的文章。 顯示所有文章

2014年11月25日 星期二

[Appium] 開啟appium server時創建log出現錯誤

開啟:

appium -a 127.0.0.1 -p 4723 --no-reset --session-override -lt 180000 --command-timeout 180000 --log /Users/jenkins/workspace/Orange/label/Mac_Mini_2014_1/junit/appium.log

出現錯誤:

uncaughtException: ENOENT, open '/Users/jenkins/workspace/Orange/label/Mac_Mini_2014_1/junit/appium.log'


原因:node沒有該資料夾讀寫的權限

解決辦法:

1.開放該位置讀寫的權限
2. $sudo chmod -R 1777 /Users/jenkins/workspace/Orange/label/Mac_Mini_2014_1/junit/

2014年11月24日 星期一

[Appium] Appium的元件定位方法

Appium元件的定位方法


wd.findElement(By.xpath(“xpath‘)); ,其中By有許多方式可以達成


By.xpath 絕對路徑  (Android、iOS)

主要用於完全無法定位的元件最後手段


Ex.
wd.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIAStaticText[11]"));


尋找方法:
使用Appium Inspector可以找到



By.name 名字  (iOS)
主要用於iOS RD寫app時有幫忙把元件標上名字時
Ex.
wd.findElement(By.name("topbar reload")).click();


尋找方法:
iOS在simulator中,Settings->Accessibility->Accessibility Inspector,
Appium Inspector也可以找到



By.id  resource ID  (Android)
主要用於Android RD有幫忙把元件標上名字時
Ex.
wd.findElement(By.id("com.myapp.test:id/url"));


尋找方法:
使用Android SDK中的hierarchy viewer,可使用含Android SDK的eclipse->DDMS->選擇Device->Dump hierarchy viewer


By.className 類別名稱  (Android、iOS)
用於從一個已知的節點,往下尋找沒有名子的特定類別的元件
尋找一個節點下面元件的方法:http://ffsonic.blogspot.tw/2014/11/appium.html


Ex.
Android:
wd.findElements(By.className("android.widget.TextView"));

iOS:
wd.findElement(By.className("UIASwitch")).click();



尋找方法:
Android - hierarchy viewer
iOS - Appium Inspector




ssss

2014年11月20日 星期四

[Appium] Appium server常用參數

Appium官方capabilities doc:

使用Terminal輸入 $appium 即可開啟appium server
開啟appium時可以添加參數使用,例如: $appium -a 127.0.0.1
輸入 $appium help  可觀看更多資訊


常用參數:


-a ip : 指定監聽的IP address
sample: -a 127.0.0.1


-p port : 指定監聽的port
sample: -p 4725


--no-reset: 每個session間不清除app資料。預設是false,每個session都會清除app data,加入此參數為 = true


-lt millisecond: 啟動app timeout秒數。session啟動app後,超過此時間app沒有launch會自動斷掉session,預設是60秒。
sample: -lt 180000


--command-timeout millisecond: 每個command之間的timeout秒數。超過此時間appium server沒有收到command會斷掉session。
sample: --command-timeout


--log directory: 輸出appium log到指定位置的檔案。
sample: --log /Users/Downloads/appium.log

--session-override: 強制覆寫session,預設為false。appium server一次只能接受一個session,當目前server正在執行一個session時有新的session進來,後來的session會被拒絕。使用此參數=true,當有新的session進來時會強制拋棄舊的seesion而使用新的session

2014年11月19日 星期三

[Appium] Appium跑iOS app的條件

大前提:台Mac的Xcode必須登入一個有iOS Development的帳號,不然連安裝app時都會失敗


1. 跑在simulator:
build app時必須額外加入simulator SDK

2.跑在device
必須有原始碼,開啟xcode -> Product -> Build For -> Testing
.app位置: /Users/Library/Developer/Xcode/DerivedData/workspace/Build/Products/Debug-iphones/

build app的電腦跟跑的電腦可以不一樣,只要apple id都有權限就可以

[Appium] 使用一個總設定檔管理全部script的設定

script跟appium server溝通主要有兩個重點:

1.Capabilities
2.ip

如果把這兩個變數都寫死在全部的腳本裡面,會造成想要修改參數時非常麻煩
例如:你有50個script,當想要修改ip的時候得把50個script檔案都打開來修改...

可以寫一個總設定檔,把設定寫成function在裡面,當腳本需要連線時呼叫函數回傳設定

範例:


總設定檔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class AllSettings {
 

 public static DesiredCapabilities Set(){
  //set all Capability
  DesiredCapabilities set = new DesiredCapabilities();
  set.setCapability("appium-version", "1.3.1");
  set.setCapability("device", "iOS Simulator");
  set.setCapability("deviceName", "iPad Air");
  set.setCapability("platformName", "iOS");
  set.setCapability("platformVersion", "8.1");
  set.setCapability("showSimulatorLog", "true");
  set.setCapability("app","/Users/blabla/blabla");
  return set;
 }

 public static String URL(){
  return "http://127.0.0.1:4725/wd/hub";
 }
}

腳本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import AllSettings;

public class sample {
 AppiumDriver wd = null;

 @Test
 public void test() throws MalformedURLException, InterruptedException {
  wd = new AppiumDriver(new URL(AllSettings.URL()),AllSettings.Set());
  wd.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
  
 }
 
}


這樣對於管理全部的腳本非常方便,也不用每個腳本都去確認設定是否正確




[Appium] Appium在device上launch app時不斷閃退又重開

iOS8以上可能遇到這個問題,到device settings裡面=>Developer=>enable UI Automation


2014年11月17日 星期一

[Appium] 一台電腦同時跑多台android device

1台appium server對應一個appium session
一台電腦中可以開啟多個appium server (需使用不同的port)
開啟appium server時,給-U udid 參數即可指定要跑的device (不然會全部跑在同一台上)
UDID可用 adb devices得到


[Appium] Appium for Mac安裝

http://testerhome.com/topics/1225


2014年11月16日 星期日

[Appium] iOS點擊或滑動螢幕坐標報錯超出範圍

http://testerhome.com/topics/1589

滑動:從起始點X.Y 長按到結束點X.Y

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void ScrollDown(AppiumDriver wd) throws InterruptedException {
  JavascriptExecutor js = (JavascriptExecutor) wd;
  HashMap<String, Double> flickObject = new HashMap<String, Double>();
  // set start point and end point
  flickObject.put("startX", 300.0);
  flickObject.put("startY", 800.0);
  flickObject.put("endX", 300.0);
  flickObject.put("endY", 500.0);
  flickObject.put("duration", 500.0);
  //do action
  js.executeScript("mobile: flick", flickObject);
  Thread.sleep(delay);
 }


這邊有個坑,如果你是用Appium Inspector 找iOS中的一個坐標要滑動或是點擊,像是這樣的話


要注意! Appium Inspector的坐標是Device放大過後的坐標,而上面那語法是點擊最底層的logic screen,而不是被放大過後的Device screen

以iPad retina來說是放大兩倍,所以要把抓到的坐標/2,寫在code裡面,這樣點擊的坐標才會是正確的



原理:

http://www.iosres.com/

[Appium] 使用Appium Inspector

Appium Inspector: 一個appium的工具,可以即時分析目前device畫面上的元件


下載appium.app (from官網)後可以使用(點放大鏡)

執行前必須先建立appium連線,且必須使用port4725(Inspector好像只監聽這個port)

記得把timeout時間設長,不然還沒找完你要的資訊就會因為timeout,appium session斷掉app就被close了



public class inmac {
public static void main(String[] args) throws InterruptedException {
AndroidDriver wd = null;
try {
wd = new AndroidDriver(new URL("http://127.0.0.1:4725/wd/hub"),
App.AppSet());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}




wd.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

System.out.println("11");







}
}


[Appium] 使用CI+Appium收集log

1258
gigayaya 1楼 · 9天前 喜欢  
我也有這個問題,appium log在sever啟動時就建立了。換句話說,如果你的server沒有重啟過,那不管你跑多少條test case都會存在同一個log,不僅檔案會越來越大,也會越來越難撈你要的資料。
我目前的做法是,用Jenkins控制整個流程,如下:
  1. 啟動test project
  2. test project一啟動先刪除workspace下所有東西
  3. test project通過git獲得code
  4. test project啟動appium project
  5. appium project啟動appium server
  6. appium server啟動,將log存到test project的workspace中
  7. 執行test case
  8. 結束,上傳test report跟appium log
  9. 設置timeout,appium project閒置過久自動close project

[Appium] 安裝失敗

“
npm ERR! Error: EACCES, symlink '../lib/node_modules/appium/bin/appium.js'
npm ERR!  { [Error: EACCES, symlink '../lib/node_modules/appium/bin/appium.js']
npm ERR!   errno: 3,
npm ERR!   code: 'EACCES',
npm ERR!   path: '../lib/node_modules/appium/bin/appium.js' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! System Darwin 13.2.0
npm ERR! command "node" "/usr/local/bin/npm" "install" "-g" "appium"
npm ERR! cwd /Users/yytest
npm ERR! node -v v0.10.29
npm ERR! npm -v 1.4.14
npm ERR! path ../lib/node_modules/appium/bin/appium.js
npm ERR! code EACCES
npm ERR! errno 3
npm ERR! stack Error: EACCES, symlink '../lib/node_modules/appium/bin/appium.js'
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/yytest/npm-debug.log
npm ERR! not ok code 0
”

問題:Node沒有得到該資料夾的權限

解決:


sudo chown -R $USER /usr/local






[Appium] 根據一個已找到的位置,往下尋找子結點

如果我的目標是這裡:
xpath: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/UIATableCell[6]/UIASwitch[1]
那code應該是這樣:
WebElement aa = wd.findElement(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]"));
List<WebElement> bb= aa.findElements(By.className("UIATableCell"));
WebElement cc = bb.get(5);
WebElement dd = cc.findElement(By.className("UIASwitch"));

dd.click();
列出某一節點下面全部元素(不過無法顯示元素類別):

code:
List<WebElement> wblist= wd.findElements(By.xpath("//UIAApplication[1]/UIAWindow[1]/UIATableView[1]/*"));
System.out.println(wblist);
output:
[[[AppiumDriver: iOS on MAC (] -> xpath: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/*], [[AppiumDriver: iOS on MAC ()] -> xpath: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/*], [[AppiumDriver: iOS on MAC ()] -> xpath: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/*], [[AppiumDriver: iOS on MAC ()] -> xpath: //UIAApplication[1]/UIAWindow[1]/UIATableView[1]/*]]

[Appium] Appium架構

圖片轉自:http://blog.csdn.net/zhubaitian/article/details/39453505


文字版:

Test code           =>          Appium         =>      Device
         1                2                 3                4            5                               


1.
Test code:
任何一種Appium支持的語言寫的腳本

2.
code通過JSON跟Appium server溝通傳輸資料

3.Appium
一個Node.js編寫的server,負責把收到的資料(test code),翻譯成Device聽得懂的語言(UIA or etc)來執行

4.
Appium透過Device聽得懂的語言傳送動作指令

5.
執行動作的Device (ios or android)