UI Test, Record and Replay

  1. 1. 軟體開發故事04 - UI Test ,操作行為的錄製與播放
    1. 1.1. UI 要怎麼測?
    2. 1.2. 怎麼用機器怎麼測試?機器能做什麼??
    3. 1.3. 內建的很好用呀 為什麼不用內建的就好
    4. 1.4. 價值在那裡?

軟體開發故事04 - UI Test ,操作行為的錄製與播放

前情提要:工程師1把後端做好了

同時,另一位工程師2也把前端的UI也做好了,兩個前後端串接好後,直接交付由QA進行測試。

工程師2說:「前端不用測,QA會幫我們找到問題。」

如果你相信工程師2說的,那麼這章可以跳過不看。

UI 要怎麼測?

  • 原始時代 - 佷久很久以前,工程師自己手按一按
  • 漁獵時代 - 使用者來按或找有空的人一起幫忙按一下
  • 農業時代 - 找專職的QA 來按
  • 工業時代 - 用機器來測試程式
  • 資訊時代 - 寫測試程式來測試程式
    A- I時代 - 用人工智慧來測試

前三個時代就不講了,第四個時代的開始,其目的在減少QA的負擔(人數)

怎麼用機器怎麼測試?機器能做什麼??

大量、重覆、一成不變的工作,是可以由機器所取代的。

或許你用過XCode 內建的 Recorder 來錄製UITesting。

很簡單,在按下錄製鈕後,操作app,就會自動產生一堆程式碼了。看你想要重構與否,基本上就算是ui test了

UI Test Record

如果想要自己刻一個錄製機器呢?(為什麼待會會交代)

目標:做一個Mac APP,將模擬器上的操作錄製下來,儲存結束,並且可以回覆播放

1
2
3
4
5
1. 找到模擬器
2. 紀錄滑鼠位置與動作
3. 儲存結果
4. 重覆播放
5. 紀錄結果

開始吧

  1. 透過pid(process id)找到模擬器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
StopwatchStart();
CFArrayRef windowList = CGWindowListCopyWindowInfo(listOptions, kCGNullWindowID);
StopwatchEnd("Create Window List");

// Copy the returned list, further pruned, to another list. This also adds some bookkeeping
// information to the list as well as
NSMutableArray * prunedWindowList = [NSMutableArray array];
self.windowListData = [[WindowListApplierData alloc] initWindowListData:prunedWindowList];

CFArrayApplyFunction(windowList, CFRangeMake(0, CFArrayGetCount(windowList)), &WindowListApplierFunction, (__bridge void *)(self.windowListData));
CFRelease(windowList);

for (NSInteger i = prunedWindowList.count-1; i>=0; i--) {
//iOS
if([[[prunedWindowList objectAtIndex:i] objectForKey:@"applicationName"] containsString:@"Simulator"]){

}else{
[prunedWindowList removeObjectAtIndex:i];
}
}

其中 Application Name 是 Simulator, 如果你想用命令模式打開模擬器的話,可以用下面的指令玩看看

1
2
3
4
5
xcrun instruments -s  //列出所有可用的的設備
xcrun instruments -w "iPhone XS (12.0)" //開啟模擬器
xcrun simctl install booted <app路径> //安裝ipa
xcrun simctl launch booted <app identifier> //打開指定的app
xcrun simctl uninstall booted <app identifier> //解除安裝
  1. 模擬器開啟後,記錄模擬器的座標、尺寸、滑鼠的座標與滑鼠的動作

  2. 一連串的紀錄允許簡單的編輯修改,定義為一個action存在資料庫
    ,由許多action建構成一個 UI Test

  3. 將action用滑鼠事件回送到模擬器上,就可以重現QA的動作了

1
2
3
4
5
6
7
8
//calculate new touch point x,y
if(type==1){
[mMouseEvent mouseTouchDownWithPoint: CGPointMake(ex, ey)];
}else if(type==2){
[mMouseEvent mouseDragWithPoint: CGPointMake(ex, ey)];
}else if(type==3){
[mMouseEvent mouseTouchUpWithPoint: CGPointMake(ex, ey)];
}
  1. 拍畫面用以比對結果
1
2
3
4
5
6
StopwatchStart();
CGImageRef windowImage = CGWindowListCreateImage(imageBounds, singleWindowListOptions, windowID, imageOptions);
Profile(windowImage);
StopwatchEnd("Single Window");
[self setOutputImage:windowImage];
CGImageRelease(windowImage);

應用程式截圖
mac recorder

內建的很好用呀 為什麼不用內建的就好

舉例來說

我們想要在同一個時間內跑多個裝置的ui test,或是ui test的test case太多,能不能夠分成兩組以上同時跑?

也有時候座標記錄,相對來說,可利用性比較大一些。

比方說

IoT 寫字機
mac recorder

價值在那裡?

聽話、任勞任怨
比一個QA工程師的薪水便宜
bla bla bla