2019 年的增壓測試技巧:Java 自動化測試教程

已發表: 2022-03-11

每年,來自全球的測試自動化工程師都會研究最新的工具和技術,以使他們的測試自動化框架更穩定、更快、更易於使用和維護。 這對於確保在公司內繼續廣泛採用他們的框架至關重要。 一般來說,臃腫、過時的框架很快就會過時。

在這篇文章中,我們將了解一些可以為 2019 年更新框架的方法以及如何為 2020 年做好準備。為了改進我的框架,我總是專注於“痛點”。 這些是設置複雜或導致最多故障的區域。 我確定了三個我想簡化或改進的主要領域:

  1. 硒網格
  2. 等待
  3. Chrome 開發者工具

Selenium Grid 的設置是出了名的棘手,並且可能會在沒有警告的情況下失敗。 我想看看這裡有什麼改進。 我還想調查是否向 Selenium API 添加了任何新的waits ,以提高我創建的任何測試的穩定性。 最後,我想看看我是否可以通過 Selenium 開始與 Chrome DevTools 進行交互,Selenium 已成為任何測試人員工具包的重要組成部分。

提示 #1:Dockerize 你的 Selenium 網格

Selenium Grid 是出了名的難以在 CI 管道上設置、不穩定且難以部署或版本控制。 一種更簡單、穩定且可維護的方法是使用預先構建的 Selenium Docker 映像。

注意:這種方法的一個缺點是不支持 IE (Internet Explorer),因為它還不能容器化 Windows 操作系統。

開始設置

要啟動並運行,首先你需要在你的機器上安裝 Docker 和 Docker Compose。 如果您運行的是 Windows 10 或 Mac,那麼它們都將通過 Docker 桌面安裝。

開始你的網格

Docker Hub 上的官方 Selenium 存儲庫包含為您的 Selenium Hub 以及 Firefox 和 Chrome 節點預先構建的 Docker 映像。

在本地 Selenium Grid 中使用它們的最簡單方法是在項目的根目錄中構建一個 Docker Compose 文件。 將文件命名為docker-compose.yml以保持簡單。

我在下麵包含了一個示例,該示例創建了以下網格:

  • 單個 Selenium 集線器
  • 一個 Chrome 節點
  • 一個 Firefox 節點
#docker-compose.yml version: "3" services: selenium-hub: image: selenium/hub:3.141.59-neon container_name: selenium-hub ports: - "4444:4444" chrome: image: selenium/node-chrome:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444 firefox: image: selenium/node-firefox:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444

Docker Compose 文件描述了 Grid 的設置。 有關創建 Docker Compose 文件的更多信息,請參閱官方文檔。

要啟動 Grid,只需使用任何終端窗口(Windows 中的powershellcmd窗口)從項目的根目錄運行以下命令:

 docker-compose up

連接到電網

您可以像往常一樣以完全相同的方式連接到 Selenium Grid,因為 Hub 正在偵聽本地計算機的端口 4444。 這是一個示例,我們將驅動程序設置為使用我們的 Chrome 節點。

 // Driver.java protected static RemoteWebDriver browser; DesiredCapabilities cap = new DesiredCapabilities(); ChromeOptions chromeOptions = new ChromeOptions(); cap.setCapability(ChromeOptions.CAPABILITY, chromeOptions); cap.setBrowserName("chrome"); driver = new RemoteWebDriver(cap);

然後,您可以像往常一樣使用 TestNG 庫在多個節點上並行運行測試。

值得注意的是,可以在每個節點上運行多個瀏覽器。 然而,這是不鼓勵的,每個節點使用一個瀏覽器被認為是最佳性能的最佳實踐。

其他提示和技巧

如果您想查看瀏覽器上發生了什麼以便調試您的測試,那麼值得擁有一個docker-compose.yml文件的debug版本來下載debug瀏覽器節點。 它們包含一個 VNC 服務器,因此您可以在測試運行時觀看瀏覽器。

也可以無頭運行瀏覽器以提高速度(通常的方式),Selenium 還提供圖像的base版本,因此如果您需要安裝其他軟件,您可以構建自己的圖像。

要為您的 CI 管道創建一個穩定的網格版本,也可以將您的網格部署到 Kubernetes 或 Swarm 上。 這確保了任何 Docker 在它們發生故障時都能快速恢復或替換。

提示 #2:智能等待

任何測試自動化工程師都知道, waits對於測試自動化框架的穩定性至關重要。 他們還可以通過渲染任何冗餘的sleepspauses來加速您的測試,並克服緩慢的網絡和跨瀏覽器問題。 以下是一些讓您的waits更有彈性的提示。

Java 自動化測試教程 #2:等待中的邏輯運算符:特定於等待

ExpectedConditions類隨著時間的推移而發展壯大,現在幾乎涵蓋了所有可以想像的情況。 雖然ExpectedConditions.presenceOfElementLocated(locator)通常就足夠了,但最佳實踐是使用ExpectedCondition類中的方法通過將它們嵌入到Actions.java類中來涵蓋每個用戶操作。 這將使您的測試免受大多數跨瀏覽器或慢速網站問題的影響。

例如,如果單擊鏈接導致新選項卡打開,則使用ExpectedConditions.numberOfWindowsToBe(2) 。 這將確保該選項卡在嘗試切換到它之前就在那裡。

您還可以使用wait來確保在使用findElements時捕獲頁面上存在的所有元素。 如果search頁面需要時間來返回其結果,這將特別有用。 例如,這一行:

 List<WebElement> results = driver.findElements(locators.RESULTS);

如果您的搜索結果尚未加載,它可能會導致一個空的List數組。 相反,最好使用numberOfElementsToBeMoreThan預期條件等待結果大於零。 例如:

 WebElement searchButton = driver.findElement(locators.SEARCH_BUTTON); searchButton.click(); new WebDriverWait(driver, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locators.RESULTS, 0)); List<WebElement> results = driver.findElements(locators.RESULTS); results.get(0).click();

現在,您的findElements命令只會在搜索結果返回後運行。

當您處理與 Selenium 不兼容的前端(例如,Angular 網站)時,這種wait對於查找單個元素也很有用。 創建這樣的方法將保護您的測試,使它們更加穩定。

 protected static WebElement waitForElement(By locator){ try { new WebDriverWait(browser, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locator, 0)); } catch (TimeoutException e){ e.printStackTrace(); Assert.fail("Timeout: The element couldn't be found in " + WAIT + " seconds!"); } catch (Exception e){ e.printStackTrace(); Assert.fail("Something went wrong!"); } return browser.findElement(locator); }

甚至可以等待元素不再可見。 如果您在繼續測試之前單擊“ OK ”或“ Save ”按鈕後等待彈出窗口消失,這將特別有用。

 WebElement okButton = driver.findElement(locators.OK_BUTTON); okButton.click(); new WebDriverWait(driver, 30) .until( ExpectedConditions .invisibilityOfElementLocated(locators.POPUP_TITLE) );

上述所有方法以及更多方法都列在官方文檔中。 花十分鐘閱讀所有可能性並提高框架的穩定性是非常值得的。

Java 自動化測試教程 #2:等待中的邏輯運算符

waits中建立彈性的一個好方法是使用邏輯運算符。 例如,如果您想檢查一個元素是否已被定位並且它是可點擊的,您將使用以下代碼(請注意,這些示例返回一個布爾值):

 wait.until(ExpectedConditions.and( ExpectedConditions.presenceOfElementLocated(locator), ExpectedConditions.elementToBeClickable(locator) ) );

如果您不確定頁面的標題是否會更改,則 OR 運算符將是合適的。 然後,如果第一個條件失敗,您可以檢查 URL,以確認您確實在正確的頁面上。

 wait.until(ExpectedConditions.or( ExpectedConditions.titleIs(expectedTitle), ExpectedConditions.urlToBe(expectedUrl) ) );

或者,如果您想確保在頁面上執行操作後不再啟用複選框,則 NOT 運算符是合適的。

 wait.until(ExpectedConditions.not( ExpectedConditions.elementToBeClickable(locator) ) );

使用運算符可以使您的waits更有彈性,並導致測試不那麼脆弱。

提示 #3:Chrome DevTools:模擬網絡條件

在 localhost 或本地網絡上運行您的 Web 應用程序可能會在野外運行時對其性能產生錯誤的印象。 限制各種上傳和下載速度的能力將使您更好地了解您的應用程序將如何在 Internet 上運行,其中超時可能導致操作失敗。 我們可以開始使用 Chrome 的 DevTools 來模擬這個。

以下代碼將使用不同的下載和上傳速度打開 Toptal 主頁。 首先,我們將使用以下代碼將速度存儲在 TestNG 數據提供程序中:

 import org.testng.annotations.DataProvider; public class ExcelDataProvider { @DataProvider(name = "networkConditions") public static Object[][] networkConditions() throws Exception { return new Object[][] { // Upload Speed, Dowload Speed in kb/s and latency in ms. { 5000 , 5000, 5 }, { 10000, 7000, 5 }, { 15000, 9000, 5 }, { 20000, 10000, 5 }, { 0, 0 }, }; } }

注意:上傳和下載節流以kb/s為單位,延遲以ms為單位。

然後,我們可以使用這些數據在不同的網絡條件下運行我們的測試。 在測試中, CommandExecutor將在瀏覽器的當前會話中執行命令。 這反過來將激活 Chrome 開發者工具功能中的必要設置,以模擬我們的慢速網絡。 在運行一組測試時, if語句中的代碼可以包含在@BeforeClass方法中。

 import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.openqa.selenium.remote.Command; import org.openqa.selenium.remote.CommandExecutor; import org.openqa.selenium.remote.Response; public class TestClass { // load our data provider @Test(dataProvider = "networkConditions") public void test(int download, int upload, int latency) throws IOException { // only run if the network is throttled if (download > 0 && upload > 0) { CommandExecutor executor = driver.getCommandExecutor(); // create a hashmap of the required network conditions Map map = new HashMap(); // you can even test 'offline' behaviour map.put("offline", false); map.put("latency", latency); map.put("download_throughput", downloadThroughput); map.put("upload_throughput", uploadThroughput); // execute our code Response response = executor.execute( new Command(driver.getSessionId(), "setNetworkConditions", ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map)))); } // Open the website driver.get("https://www.toptal.com/"); // You can then check that elements are loaded etc. // Don't forget to use waits! } }
相關:自信地構建:JUnit 測試指南

額外提示:如何管理您的 Cookie

瀏覽器 cookie 可能會在您的應用程序中導致不同的行為,具體取決於它們是否已從先前的會話中保存(例如,應用程序可能會在用戶已登錄的情況下加載)。 在每次測試運行之前清除您的 cookie 以確保它們不會導致問題是一種很好的做法。

下面的代碼允許您刪除所有 cookie:

 driver.manage().deleteAllCookies();

您還可以按名稱刪除 cookie:

 driver.manage().deleteCookieNamed("CookieName");

或者獲取 cookie 的內容:

 String myCookie = driver.manage().getCookieNamed("CookieName").getValue();

或者獲取所有的 cookie:

 List<Cookie> cookies = driver.manage().getCookies();

2020 年的測試自動化:展望未來

Selenium 4 將在未來幾個月內發布。 它仍在開發中,但由於已經發布了 alpha 版本,因此值得看看它將提供哪些改進。

注意:您可以通過查看路線圖來跟踪他們的進度。

W3C WebDriver 標準化

Selenium 不再需要通過 JSON 有線協議與瀏覽器通信; 相反,自動化測試將直接與瀏覽器通信。 這應該解決 Selenium 測試著名的不穩定特性,包括防止瀏覽器升級。 希望測試速度也會提高。

更簡單的 Selenium 網格

Selenium Grid 在 Selenium 4 中將更加穩定,更易於設置和管理。用戶將不再需要單獨設置和啟動集線器和節點,因為網格將充當組合節點和集線器。 此外,將對 Docker 提供更好的支持,本機將包含並行測試,並將提供更多信息的 UI。 使用 Hooks 進行請求跟踪也將幫助您調試網格。

文檔

自 Selenium 2.0 發布以來,Selenium 文檔將得到急需的大修,尚未更新。

API 的更改

對 Opera 和 PhantomJS 瀏覽器的支持將被刪除。 可以使用 Chrome 或 Firefox 執行無頭運行,並且 Opera 是基於 Chromium 構建的,因此 Chromium 測試對於這個瀏覽器來說已經足夠了。

WebElement.getSize()WebElement.getLocation()現在替換為單個方法WebElement.getRect() 。 但是,由於這些通常用於創建單個元素的屏幕截圖,因此值得知道的是,在 Selenium 4 中還將有一個 API 命令來捕獲元素的屏幕截圖。

對於 WebDriver WindowgetPositiongetSize方法將被getRect方法替換, setPositionsetSize方法將被setRect方法替換。 fullscreenminimize方法將可用,因此可以在您的測試中執行這些操作。

其他顯著變化:

  • 現在,每個瀏覽器的Options類都將擴展Capabilities類。
  • 添加了driver.switchTo().parentFrame()方法以使框架導航更容易。
  • 將包括在當前定位器更高級別上運行的nice定位器。 它們將是By的子類。
  • 將有一個DevTools API 的實現,允許用戶利用使用 Chrome 調試協議(以及其他瀏覽器上的等效協議)提供的功能。 這些包括:
    • 整頁截圖(包括屏幕外元素)。
    • 流式傳輸日誌。
    • 等待頁面上的突變事件。
  • 許多不推薦使用的方法和類也將被刪除。

注意:您可以從 Maven 存儲庫獲取 Selenium 4 的 Alpha 版本。 強烈建議您針對您當前的框架(最好在沙箱分支上)嘗試此操作,以便您為更改做好準備。

結論

在本文中,我介紹了一些我改進了我的測試自動化框架的領域。 它現在比以前更加穩定和可用,這將對參與軟件交付生命週期的每個人產生積極影響。

進行我上面概述的更改是一個好的開始,但是,我強烈建議您查看整個框架的“痛點”,因為您可能會做出我沒有涵蓋的改進。 例如,您是使用 WebDriver Manager 來管理驅動程序還是仍在手動更新它們?

我還建議設置一個日期,至少每年一次,儘管理想情況下是每六個月一次。 在文章中,我介紹了 Selenium 4.0 中即將發生的變化。 請自己查看 Selenium 的alpha版本。 這些變化將是巨大的,您需要做好準備。 我希望你發現這很有用。 如果你在對你的框架進行一些春季大掃除時發現了任何新的方法或技術,請通過將它們添加到下面的評論部分與本博客的其他讀者分享。

此外,如果您想了解 Selenium 中的自動化測試,以及如何使用頁面對像模型來編寫可維護和可重用的測試例程,請查看Selenium 中的自動化:頁面對像模型和頁面工廠

相關: Dart 語言:當 Java 和 C# 不夠鋒利時