Introduction
之前文章中,介紹給大家透過Sikuli Script的方式將RobotFramework與Sikuli整合在一起的方法。這篇文章要教你另外一種透過將Sikuli API寫成RobotFramework Plugin的方式。
Plugin-Based Sikuli-Robot Integration
High Level Architecture
讓我們來看看將Sikuli做成TestLibrary整合示意圖:
基本上就是我們需要去實做一個Sikuli的TestLibrary,我稱為SikuliLibrary,它會依靠Sikuli。實做方法據我所知有兩個,一個是依靠Sikuli自帶的sikuli-script.jar,另外一個是靠同樣SikuliLab的Sikuli API。由於Sikuli API已經將繁複的操作給包成API,因此我選擇它來實做TestLibrary。
Sikuli API
在Sikuli API的官方文件已經有一些Sample Code教導大家如何使用,我就不贅述只做總結。 它有幾個核心物件ScreenRegion、Target、Mouse、Keyboard與Canvas。
- ScreenRegion: 螢幕區域,讓你可以在它的範圍內找尋Target。預設範圍為整個桌面。
- Target: 目標,基本上就是指你要想操作的圖片。
- Mouse: 提供滑鼠相關操作,包含Drag&Drop。
- Keyboard: 提供鍵盤相關操作。
- Canvas: 畫布,我把它拿來Debug用。可以針對你想要的ScreenRegion做一些畫框框或印文字的動作,讓你可以知道行為操作是否正常。
在Linux上,Sikuli API會相依於OpenCV的函式庫。我是將OpenCV 2.4版抓下來編譯後再將那些so取來用,讓TestLibrary可以portable。
Keywords
目前我想到的操作有:
- Send Combo Keys: 送出組合鍵。輸入值為AWT KeyEvent名稱,例如Ctrl + Alt + D為VK_CONTROL + VK_ALT + VK_D。
- Type String: 輸入字串。
- Move Image: 移動圖片到目標位置。
- Click Image: 點擊圖片。
- Find All Image: 搜尋圖片出現的所有位置,這意味著圖片會顯示在多個地方。回傳結果設計為index 0代表著數量,接著都是以x與y座標為一組資料。Ex. [ 2, 100, 200, 150, 250 ]。
- Find Image: 搜尋圖片位置。回傳結果為x與y座標,Ex. [ 150, 250 ]。
- Image Should Exist: 確認某個圖片是否存在。
- Disable Debug Mode: 取消偵錯模式。
- Enable Debug Mode: 啟用偵錯模式,透過Canvas去標示出操作圖片。
- Set Timeout: 設定搜尋圖片的Timeout。
我的類別基本宣告,物件生命週期為Test Suite。
public class SikuliLibrary { public static final String ROBOT_LIBRARY_VERSION = "1.0"; public static final String ROBOT_LIBRARY_SCOPE = "TEST SUITE"; private Mouse mMouse = new DesktopMouse(); private Keyboard mKeyboard = new DesktopKeyboard(); private ScreenRegion mDesktopSR = new DesktopScreenRegion(); private boolean mIsDebugEnable = false; private int mTimout = 5000;
以Click Image為例,我會透過mDesktopSR去搜尋圖片,如果找到它會回傳圖片的ScreenRegion,如果沒找到就回拋例外SikuliLibraryException。拋例外也會造成Keyword Failed,Robot Assertion就是透過拋例外達成。這邊也有show出Canvas的使用方式,display(3)代表顯示三秒的意思。其它大同小異我就不特別說明了。
public void clickImage(String aImagePath) throws SikuliLibraryException{ ScreenRegion sr = getScreenRegionEx(aImagePath); mMouse.click(sr.getCenter()); } private void showDebugCanvas(ScreenRegion aSR){ if( mIsDebugEnable && aSR != null ){ showCanvas(aSR); } } private void showCanvas(ScreenRegion aSR){ if( aSR != null ) { Canvas canvas = new DesktopCanvas(); canvas.addBox(aSR).display(3); } } private ScreenRegion getScreenRegionEx(String aImagePath) throws SikuliLibraryException{ Target target = new ImageTarget(new File(aImagePath)); ScreenRegion sr = mDesktopSR.wait(target, mTimout); if( sr == null ){ throw new SikuliLibraryException("Image dones't exist: " + aImagePath); } showDebugCanvas(sr); return sr; }
用它吧!
在執行Robot的script中必須將這個類別jar檔加入classpath中,並且要設定java.library.path好讓sikuli api可以找的到這些so檔。
#!/bin/sh FULLPATH=`dirname "$0"`/`basename "$0"` SHPATH=`readlink -f "$FULLPATH"` BASEPATH=`dirname "$SHPATH"` RFPATH=$BASEPATH/robotframework.jar NATIVE_LIB_PATH=$BASEPATH/libs/native CLASSPATH=$RFPATH java -Djava.library.path="$NATIVE_LIB_PATH" \ -cp "$CLASSPATH" org.robotframework.RobotFramework -P "$BASEPATH/libs/*" "$@"
在撰寫測試案例時,必須匯入Library:
接著就是用它拉,這個範例是送Alt+F9組合鍵縮小視窗並確認某張圖片是否存在,我將圖片放在TestSuite的相對目錄中:測試結果如下:
註: 目前已知問題在Ubuntu中Enable Debug Mode會出現Error setting window transparency或The window must use a translucency-compatible graphic的錯誤,我想應該和我在VM上執行有關係吧。
Summary
Script-Based與Plugin-Based彼此間有什麼優缺點呢?
Script-Based | Plugin-Based | |
---|---|---|
程式碼活動性 | 敗,修改維護必須透過SikuliIDE | 勝,直接在Robot中透過Keyword操作流程 |
第一次開發 | 勝,有SikuliIDE可以做截圖提升開發速度 | 敗,必須自行找工具截圖 |
大小 | 敗,必須將整包Sikuli包到測試環境中 | 勝,僅需jar檔與native lib |
這些比較是我個人想法,要怎麼使用還是要看大家專案環境去決定。
Reference
- How to sikuli and robot framework?
- Robot User Guide - Exteding Robot Framework
- Java6 SDK - KeyEvent
- Build OpenCV on CentOS5.8
- OpenCV 2.4.3 FAQ
留言
張貼留言