轉載請註明出處❤️
作者:測試蔡坨坨
原文連結:caituotuo.top/6d2908e8.html
你好,我是測試蔡坨坨。
由於目前大多數GUI工具均需要依賴於程式型別進行特徵屬性識別,例如:Selenium、Appium、UIAutomator。在進行WebUI自動化測試的時候,有些元素使用傳統的Selenium方法(傳統方法:使用id等屬性定位)很難或無法定位到,比如:object元素;基於Flash、JavaScript或Ajax等技術實現的檔案上傳功能。
對於非input框的檔案上傳問題,Python可以使用win32gui庫,而Java可以使用AutoIt,但是AutoIt只有Windows版本,又要考慮相容Windows和macOS。
對於這種情況,推薦一個好玩的東西SikuliX。
本篇就來聊聊SikuliX這個工具,什麼是SikuliX,如何使用,以及檔案上傳功能demo實現。
SikuliX是基於PC影象識別的自動化測試工具,由MIT(麻省理工學院)研究團隊釋出。
與其他UI自動化工具相比,SikuliX的優勢在於,它是基於畫素實現的元素定位,所以即使頁面上的元素沒有像id、name這些屬性,也可以通過影象識別進行UI的互動操作,無需關注元素有哪些屬性,所見即所得;適合非標準控制元件等自定義介面的定位;支援跨平臺,如:Windows、macOS、Linux。
但是,它也有一定的侷限性,由於是基於影象識別,因此圖片的大小、解析度、色彩都會對識別造成影響,定位不能百分百準確識別到元素,如果有兩個相同或相似的圖片,無法區分具體哪一個,需要手動調整精確度,工作量大;只能定位當前正在操作的視窗介面;若流程過長,則會造成指令碼過於臃腫;目前還不適合設計成一種測試框架。
儘管SikuliX用來實現複雜的測試場景不太現實,這也是所有GUI自動化測試無法改變的現實,但是用來做一些特定場景的測試還是遊刃有餘。對於Web自動化主要用該端的自動化框架,如Selenium,SikuliX作為輔助,可以和Selenium結合使用。
方法一(推薦):使用Maven構建工具,匯入pom依賴
<!-- https://mvnrepository.com/artifact/com.sikulix/sikulixapi -->
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>1.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sikulix/sikulixlibswin -->
<!-- 這裡是Windows版本,其他系統版本選擇參考 https://mvnrepository.com/artifact/com.sikulix -->
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixlibswin</artifactId>
<version>1.1.1</version>
</dependency>
方法二:手動下載jar包加入到參照庫
https://raiman.github.io/SikuliX1/downloads.html
SikuliX提供兩大核心類,Region(介面部分割區域識別)和Screen(全螢幕識別)。
範例化Region:
Region r = new Region(100, 100, 100, 100);
說明:
class Region
Region(x, y, w, h)
Region(region)
Region(Rectangle)
Create a region object
Parameters:
x – x position of a rectangle.
y – y position of a rectangle.
w – height of a rectangle.
h – width of a rectangle.
region – an existing region object.
rectangle – an existing object of Java class Rectangle
Returns:
a new region object.
範例化Screen:
Screen s = new Screen();
等待元素出現:wait()
s.wait(inputImg, 10);
判斷元素是否在螢幕上顯示:exists()
s.exists(inputImg);
在文字輸入框輸入指定文字內容:type()
s.type(inputImg, "caituotuo");
單擊元素:click()
s.click(btnImg);
右鍵單擊元素:rightClick()
s.rightClick(btnImg);
雙擊元素:doubleClick()
s.doubleClick(btnImg);
旋轉指定影象:wheel()
s.wheel(btnImg,25,0);
拖放圖片:dragDrop()
s.dragDrop(img,img2);
滑鼠懸停:hover()
s.hover(btnImg);
貼上覆制的字串:paste()
由於type()不支援輸入中文,所以可以用paste()來在指定的文字方塊中貼上文字
s.paste(inputImg,"蔡坨坨");
按下鍵盤鍵:type()
s.type(Key.ENTER);
s.type("c",Key.CTRL); // 快捷鍵
public static void baiduSearch() throws InterruptedException, FindFailed {
String imgPath = PathUtils.getProjectPath() + "src\\test\\resources\\images\\";
// Pattern baiduInput = new Pattern(imgPath + "baiduInput.png");
String baiduInput = imgPath + "baiduInput.png";
// Pattern baiduBtn = new Pattern(imgPath + "baiduBtn.png");
String baiduBtn = imgPath + "baiduBtn.png";
// 開啟瀏覽器
WebDriver driver = new ChromeDriver();
// 視窗最大化
driver.manage().window().maximize();
// 存取百度網站
driver.get("https://www.baidu.com");
// 等待1s
Thread.sleep(1000);
// 範例化Screen類
Screen s = new Screen();
// 等待搜尋方塊出現
s.wait(baiduInput, 10);
// s.type(baiduInput, "sikuli");
// 貼上文字
s.paste(baiduInput, "測試蔡坨坨");
// 按下確認鍵
s.keyDown(Key.ENTER);
// 判斷百度一下按鈕是否存在
s.wait(baiduBtn, 10);
// 點選百度一下
s.click(baiduBtn);
// 等待3s
Thread.sleep(3000);
// 關閉瀏覽器
driver.quit();
}
public static void uploadFileBySikuli() throws InterruptedException, FindFailed {
String imgPath = PathUtils.getProjectPath() + "src\\test\\resources\\images\\";
String img = PathUtils.getProjectPath() + "src\\test\\resources\\images\\avatar.png";
Screen s = new Screen();
Pattern fileInputTextBox = new Pattern(imgPath + "fileInputTextBox.png");
Pattern openButton = new Pattern(imgPath + "openButton.png");
// 啟動瀏覽器並開啟連結
WebDriver driver = new ChromeDriver();
driver.get("http://www.sahitest.com/demo/php/fileUpload.htm");
// 視窗最大化
driver.manage().window().maximize();
Thread.sleep(2000);
// 點選上傳按鈕
WebElement ele = driver.findElement(By.id("file"));
new Actions(driver).click(ele).perform();
// 等待檔案上傳彈窗出現,sikuli開始操作
s.wait(fileInputTextBox, 20);
// 輸入檔案路徑
s.type(fileInputTextBox, img);
// 點選回車
s.keyDown(Key.ENTER);
// 點選開啟按鈕
s.click(openButton);
Thread.sleep(3000);
driver.quit();
}