Java + SikuliX 基於影象實現自動化測試

2023-02-09 06:02:51

轉載請註明出處❤️

作者:測試蔡坨坨

原文連結: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簡介

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();

常用API

等待元素出現: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); // 快捷鍵

SikuliX實現百度搜尋

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();
    }

SikuliX實現檔案上傳

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();
    }