設定自己的測試自動化環境

在本文中,我們將教你如何安裝自己的自動化環境,並使用 Selenium/WebDriver 和測試庫(如 Node 的 selenium-webdriver)執行自己的測試。我們還將探討如何將本地測試環境與前一篇文章中討論的商業工具整合。

先決條件 熟悉核心 HTMLCSSJavaScript 語言;瞭解 跨瀏覽器測試原則自動化測試 的高階概念。
目標 演示如何在本地設定 Selenium 測試環境並使用它執行測試,以及如何將其與 LambdaTest、Sauce Labs 和 BrowserStack 等工具整合。

Selenium

Selenium 是最流行的瀏覽器自動化工具。還有其他方法,但使用 Selenium 的最佳方法是透過 WebDriver,這是一個功能強大的 API,它建立在 Selenium 之上,並向瀏覽器發出呼叫以對其進行自動化,執行諸如“開啟此網頁”,“將滑鼠懸停在此頁面上的元素上”,“點選此連結”,“檢視此連結是否開啟此 URL”等操作。這非常適合執行自動化測試。

WebDriver 的安裝和使用方式取決於你想使用什麼程式設計環境來編寫和執行測試。大多數流行的環境都提供一個包或框架,可以安裝 WebDriver 和與 WebDriver 通訊所需的繫結,例如 Java、C#、Ruby、Python、JavaScript(Node)等。有關不同語言的 Selenium 設定的更多詳細資訊,請參閱 設定 Selenium-WebDriver 專案

不同的瀏覽器需要不同的驅動程式才能讓 WebDriver 與它們通訊並控制它們。有關從哪裡獲取瀏覽器驅動程式的更多資訊,請參閱 Selenium 支援的平臺

我們將介紹如何使用 Node.js 編寫和執行 Selenium 測試,因為它快速易於上手,並且對於前端開發人員來說是一個更熟悉的環境。

注意:如果你想了解如何在其他伺服器端環境中使用 WebDriver,請檢視 Selenium 支援的平臺,其中包含一些有用的連結。

在 Node 中設定 Selenium

  1. 首先,設定一個新的 npm 專案,如上一章 設定 Node 和 npm 中所述。將其命名為不同的名稱,例如 selenium-test
  2. 接下來,我們需要安裝一個框架,以便我們可以在 Node 內部使用 Selenium。我們將選擇 Selenium 官方的 selenium-webdriver,因為它的文件看起來相當最新且維護良好。如果你想要其他選擇,webdriver.ionightwatch.js 也是不錯的選擇。要安裝 selenium-webdriver,請執行以下命令,確保你位於專案資料夾中
    bash
    npm install selenium-webdriver
    

注意:即使你之前安裝了 selenium-webdriver 並下載了瀏覽器驅動程式,也建議你按照這些步驟操作。你應該確保一切都已更新。

接下來,你需要下載相關的驅動程式,以使 WebDriver 能夠控制你想要測試的瀏覽器。你可以在 selenium-webdriver 頁面上(參見第一部分的表格)找到有關從哪裡獲取它們的詳細資訊。顯然,有些瀏覽器是特定於作業系統的,但我們將堅持使用 Firefox 和 Chrome,因為它們在所有主要作業系統上都可用。

  1. 下載最新的 GeckoDriver(適用於 Firefox)和 ChromeDriver 驅動程式。
  2. 將它們解壓到某個易於導航的地方,例如主使用者目錄的根目錄。
  3. chromedrivergeckodriver 驅動程式的位置新增到系統 PATH 變數中。這應該從硬碟根目錄到包含驅動程式的目錄的絕對路徑。例如,如果我們使用的是 macOS 機器,我們的使用者名稱是 bob,並將驅動程式放在主資料夾的根目錄中,則路徑為 /Users/bob

注意:再說一遍,新增到 PATH 的路徑需要是包含驅動程式的目錄的路徑,而不是驅動程式本身的路徑!這是一個常見的錯誤。

要在 macOS 系統和大多數 Linux 系統上設定 PATH 變數

  1. 如果你還沒有使用 bash shell(例如,在 macOS 系統上,預設 shell 是 zsh,而不是 bash),請切換到 bash shell
    bash
    exec bash
    
  2. 開啟你的 .bash_profile(或 .bashrc)檔案(如果你看不到隱藏檔案,則需要顯示它們,請參閱 在 macOS 中顯示/隱藏隱藏檔案在 Ubuntu 中顯示隱藏資料夾)。
  3. 將以下內容貼上到檔案的底部(更新路徑,使其與你的機器上的實際路徑一致)
    bash
    #Add WebDriver browser drivers to PATH
    
    export PATH=$PATH:/Users/bob
    
  4. 儲存並關閉此檔案,然後重新啟動你的終端/命令提示符以重新應用 Bash 配置。
  5. 透過在終端中輸入以下內容來檢查你的新路徑是否在 PATH 變數中
    bash
    echo $PATH
    
  6. 你應該在終端中看到它被打印出來。

要在 Windows 上設定 PATH 變數,請按照 如何將新資料夾新增到系統路徑? 中的說明操作。

好了,讓我們嘗試一個快速測試以確保一切正常。

  1. 在專案目錄中建立一個名為 google_test.js 的新檔案
  2. 將其內容設定為以下內容,然後儲存它
    js
    const { Builder, Browser, By, Key, until } = require("selenium-webdriver");
    
    (async function example() {
      const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
      try {
        await driver.get("https://www.google.com/ncr");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.wait(until.titleIs("webdriver - Google Search"), 1000);
      } finally {
        await driver.sleep(2000); // Delay long enough to see search page!
        await driver.quit();
      }
    })();
    

    注意:此函式是 IIFE(立即呼叫的函式表示式)。

  3. 在終端中,確保你位於專案資料夾中,然後輸入以下命令
    bash
    node google_test
    

你應該會看到一個 Firefox 例項自動開啟!Google 應該自動載入在一個選項卡中,“webdriver” 應該在搜尋框中輸入,並且搜尋按鈕將被點選。WebDriver 然後將等待 1 秒;然後訪問文件標題,如果它是“webdriver - Google 搜尋”,我們將返回一條訊息,聲稱測試透過。然後我們等待 4 秒,之後 WebDriver 將關閉 Firefox 例項並停止。

在多個瀏覽器中同時進行測試

你也可以同時在多個瀏覽器上執行測試。讓我們試試這個!

  1. 在專案目錄中建立另一個名為 google_test_multiple.js 的新檔案。你可以隨意更改對我們新增的其他瀏覽器的引用,刪除它們,等等,具體取決於你可以在你的作業系統上測試的瀏覽器。你需要確保你的系統上已設定了正確的瀏覽器驅動程式。關於在 .forBrowser() 方法中使用什麼字串來表示其他瀏覽器,請參閱 Browser 列舉 參考頁面。
  2. 將其內容設定為以下內容,然後儲存它
    js
    const { Builder, Browser, By, Key } = require("selenium-webdriver");
    
    const driver_fx = new Builder().forBrowser(Browser.FIREFOX).build();
    
    const driver_chr = new Builder().forBrowser(Browser.CHROME).build();
    
    async function searchTest(driver) {
      try {
        await driver.get("http://www.google.com");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.sleep(2000).then(async () => {
          await driver.getTitle().then(async (title) => {
            if (title === "webdriver - Google Search") {
              console.log("Test passed");
            } else {
              console.log("Test failed");
            }
          });
        });
      } finally {
        driver.quit();
      }
    }
    
    searchTest(driver_fx);
    searchTest(driver_chr);
    
  3. 在終端中,確保你位於專案資料夾中,然後輸入以下命令
    bash
    node google_test_multiple
    
  4. 如果你使用的是 Mac 並決定測試 Safari,你可能會收到類似於“無法建立會話:你必須在 Safari 的“開發”選單中啟用“允許遠端自動化”選項才能透過 WebDriver 控制 Safari”的錯誤訊息。如果你遇到這種情況,請按照給定的說明操作,然後重試。

所以在這裡,我們之前已經完成了測試,只是這次我們把它包裝在一個函式 searchTest() 中。我們為多個瀏覽器建立了新的瀏覽器例項,然後將每個例項傳遞給函式,以便在所有三個瀏覽器上執行測試!

有趣吧?讓我們繼續,更詳細地看一下 WebDriver 語法的基本知識。

WebDriver 語法速成課程

讓我們看一下 WebDriver 語法的一些關鍵功能。有關更完整的詳細資訊,你應該諮詢 selenium-webdriver JavaScript API 參考 以獲取詳細的參考以及 Selenium 主文件的 Selenium WebDriver,其中包含以多種語言編寫的多個示例供你學習。

開始一個新的測試

要啟動一個新的測試,你需要包含 selenium-webdriver 模組,匯入 Builder 建構函式和 Browser 介面

js
const { Builder, Browser } = require("selenium-webdriver");

你使用 Builder() 建構函式來建立一個新的驅動程式例項,將 forBrowser() 方法連結起來以指定你想要使用此構建器測試的瀏覽器。build() 方法連結到末尾以實際構建驅動程式例項(有關這些功能的詳細資訊,請參閱 Builder 類參考)。

js
let driver = new Builder().forBrowser(Browser.FIREFOX).build();

請注意,可以為要測試的瀏覽器設定特定的配置選項,例如,你可以在 forBrowser() 方法中設定要測試的特定版本和作業系統

js
let driver = new Builder().forBrowser(Browser.FIREFOX, "46", "MAC").build();

你也可以使用環境變數設定這些選項,例如

bash
SELENIUM_BROWSER=firefox:46:MAC

讓我們建立一個新的測試,以便在討論它時探索此程式碼。在你的 Selenium 測試專案目錄中,建立一個名為 quick_test.js 的新檔案,並將以下程式碼新增到其中

js
const { Builder, Browser } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
})();

獲取你想要測試的文件

要載入你實際要測試的頁面,可以使用你之前建立的驅動程式例項的 get() 方法,例如

js
driver.get("http://www.google.com");

注意:有關本節和它下面的功能的詳細資訊,請參閱 WebDriver 類參考

你可以使用任何 URL 來指向你的資源,包括 file:// URL 來測試本地文件

js
driver.get(
  "file:///Users/chrismills/git/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html",
);

或者

js
driver.get("https://:8888/fake-div-buttons.html");

但是,最好使用遠端伺服器位置,這樣程式碼更加靈活——當你開始使用遠端伺服器執行測試時(見後文),如果你嘗試使用本地路徑,你的程式碼將無法執行。

更新你的 example() 函式,如下所示

js
const { Builder, Browser } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );
})();

與文件互動

現在我們有了要測試的文件,我們需要以某種方式與它互動,這通常涉及首先選擇一個特定的元素來測試有關它的內容。你可以在 WebDriver 中 以多種方式選擇 UI 元素,包括按 ID、類、元素名稱等。實際選擇由 findElement() 方法完成,它接受一個選擇方法作為引數。例如,要按 ID 選擇一個元素

js
const element = driver.findElement(By.id("myElementId"));

使用 CSS 查詢元素的最有用方法之一是 By.css() 方法,它允許你使用 CSS 選擇器選擇元素。

現在更新你的 example() 函式,如下所示

js
const { Builder, Browser, By } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );
  const button = driver.findElement(By.css("button:nth-of-type(1)"));
})();

測試你的元素

有許多方法可以與 Web 文件及其上的元素互動。你可以從 WebDriver 文件的 獲取文字值 開始,檢視一些有用的常見示例。

如果我們想要獲取按鈕內部的文字,我們可以這樣做

js
button.getText().then((text) => {
  console.log(`Button text is '${text}'`);
});

現在將此新增到 example() 函式的底部,如下所示

js
const { Builder, Browser, By } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();

  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );

  const button = driver.findElement(By.css("button:nth-of-type(1)"));

  button.getText().then((text) => {
    console.log(`Button text is '${text}'`);
  });
})();

確保你位於專案目錄中,嘗試執行測試

bash
node quick_test.js

你應該在控制檯中看到按鈕的文字標籤被報告出來。

讓我們做一些更有用的事情。將前面的程式碼條目替換為以下程式碼行 button.click();,如下所示

js
const { Builder, Browser, By } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );

  const button = driver.findElement(By.css("button:nth-of-type(1)"));

  button.click();
})();

嘗試再次執行你的測試;按鈕將被點選,並且 alert() 彈出視窗將出現。至少我們知道按鈕是有效的!

你也可以與彈出視窗互動。更新 example() 函式,如下所示,然後嘗試再次測試它

js
const { Builder, Browser, By, until } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();

  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );

  const button = driver.findElement(By.css("button:nth-of-type(1)"));

  button.click();

  await driver.wait(until.alertIsPresent());

  const alert = driver.switchTo().alert();

  alert.getText().then((text) => {
    console.log(`Alert text is '${text}'`);
  });

  alert.accept();
})();

接下來,讓我們嘗試將一些文字輸入到表單元素中。更新example()函式如下,然後嘗試再次執行您的測試

js
const { Builder, Browser, By, until } = require("selenium-webdriver");

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
  driver.get(
    "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
  );

  const input = driver.findElement(By.id("name"));
  input.sendKeys("Filling in my form");

  const button = driver.findElement(By.css("button:nth-of-type(1)"));

  button.click();
  await driver.wait(until.alertIsPresent());

  const alert = driver.switchTo().alert();

  alert.getText().then((text) => {
    console.log(`Alert text is '${text}'`);
  });

  alert.accept();
})();

您可以使用Key物件的屬性提交無法用普通字元表示的按鍵。例如,在上面我們使用此構造在提交表單輸入之前跳出表單輸入

js
driver.sleep(1000).then(() => {
  driver.findElement(By.name("q")).sendKeys(Key.TAB);
});

等待某些操作完成

有時您希望讓 WebDriver 等待某些操作完成,然後再繼續執行。例如,如果您載入新頁面,您可能希望等待頁面的 DOM 載入完畢,然後再嘗試與任何元素進行互動,否則測試很可能會失敗。

例如,在我們的google_test.js測試中,我們包含了此程式碼塊

js
driver.sleep(2000).then(() => {
  driver.getTitle().then((title) => {
    if (title === "webdriver - Google Search") {
      console.log("Test passed");
    } else {
      console.log("Test failed");
    }
  });
});

sleep()方法接受一個值,該值指定以毫秒為單位的等待時間 - 該方法返回一個在該時間結束時解析的承諾,此時then()內部的程式碼將執行。在這種情況下,我們使用getTitle()方法獲取當前頁面的標題,然後根據其值返回透過或失敗訊息。

我們也可以在quick_test.js測試中新增sleep()方法 - 嘗試像這樣更新您的example()函式

js
const { Builder, Browser, By, until } = require("selenium-webdriver");

const driver = new Builder().forBrowser("firefox").build();

(async function example() {
  try {
    driver.get(
      "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html",
    );

    driver.sleep(2000).then(() => {
      const input = driver.findElement(By.id("name"));

      input.sendKeys("Filling in my form");
      input.getAttribute("value").then((value) => {
        if (value !== "") {
          console.log("Form input editable");
        }
      });
    });

    const button = driver.findElement(By.css("button:nth-of-type(1)"));

    button.click();

    await driver.wait(until.alertIsPresent());

    const alert = driver.switchTo().alert();

    alert.getText().then((text) => {
      console.log(`Alert text is '${text}'`);
    });

    alert.accept();
  } finally {
    await driver.sleep(4000); // Delay long enough to see search page!
    driver.quit();
  }
})();

WebDriver 現在將等待 2 秒,然後再填寫表單欄位。然後我們透過使用getAttribute()檢索其value屬性值來測試其值是否已填充(即不為空),如果其不為空,則向控制檯列印一條訊息。

注意:還有一種名為wait()的方法,它會在一定時間內反覆測試條件,然後繼續執行程式碼。這也利用了util 庫,它定義了與wait()一起使用的常見條件。

使用後關閉驅動程式

完成測試執行後,您應該關閉開啟的所有驅動程式例項,以確保您的機器上不會出現大量未關閉的瀏覽器例項!這可以使用quit()方法完成。在您完成對驅動程式例項的操作後,在您的驅動程式例項上呼叫此方法。現在將此行新增到quick_test.js測試的底部

js
driver.quit();

執行它時,您現在應該看到測試執行,並且瀏覽器例項在測試完成後再次關閉。這對於避免用大量瀏覽器例項弄亂您的計算機非常有用,尤其是當您擁有的瀏覽器例項過多以至於導致計算機變慢時。

測試最佳實踐

已經有很多關於編寫測試最佳實踐的文章。您可以在測試實踐中找到一些有用的背景資訊。一般來說,您應該確保您的測試是

  1. 使用良好的定位策略:當您與文件互動時,請確保您使用的定位器和頁面物件不太可能發生更改 - 如果您有一個可測試的元素要對其執行測試,請確保它具有穩定的 ID,或者可以使用 CSS 選擇器選擇的頁面位置,該位置不會在下一次網站迭代中發生更改。您希望使您的測試儘可能地不脆弱,即它們不會在發生更改時輕易崩潰。
  2. 編寫原子測試:每個測試都應該只測試一項內容,這樣可以輕鬆地跟蹤哪個測試檔案測試了哪個標準。例如,我們上面看到的google_test.js測試非常好,因為它只測試了一件事 - 搜尋結果頁面的標題是否設定正確。我們可以努力為它起一個更好的名字,這樣如果我們新增更多 Google 測試,就可以更容易地確定它做了什麼。也許results_page_title_set_correctly.js會稍微好一些?
  3. 編寫自主測試:每個測試都應該獨立執行,而不依賴於其他測試才能執行。

此外,我們應該提一下測試結果/報告 - 我們一直在使用簡單的console.log()語句在我們上面的示例中報告結果,但這完全是在 JavaScript 中完成的,因此您可以使用任何您想要的測試執行和報告系統,無論是MochaChai還是其他工具。

  1. 例如,嘗試在您的專案目錄中製作我們mocha_test.js示例的本地副本。將其放在名為test的子資料夾中。此示例使用長長的承諾鏈來執行測試中所需的所有步驟 - WebDriver 使用的基於承諾的方法需要解析才能正常工作。
  2. 透過在您的專案目錄中執行以下命令來安裝 mocha 測試工具
    bash
    npm install --save-dev mocha
    
  3. 您現在可以使用以下命令執行測試(以及您放在test目錄中的任何其他測試)
    bash
    npx mocha --no-timeouts
    
  4. 您應該包含--no-timeouts標誌,以確保您的測試不會由於 Mocha 的任意超時(為 3 秒)而最終失敗。

注意:saucelabs-sample-test-frameworks包含多個有用的示例,展示瞭如何設定測試/斷言工具的不同組合。

執行遠端測試

事實證明,在遠端伺服器上執行測試與在本地執行測試並沒有那麼難。您只需要建立驅動程式例項,但需要指定更多功能,包括要測試的瀏覽器的功能、伺服器的地址以及您訪問它所需的(如果有)使用者憑據。

LambdaTest

讓 Selenium 測試在 LambdaTest 上遠端執行非常簡單。您需要的程式碼應該遵循下面看到的模式。

讓我們編寫一個示例

  1. 在您的專案目錄中,建立一個名為lambdatest_google_test.js的新檔案
  2. 賦予它以下內容
    js
    const { By, Builder } = require("selenium-webdriver");
    
    // username: Username can be found at automation dashboard
    const USERNAME = "{username}";
    
    // AccessKey: AccessKey can be generated from automation dashboard or profile section
    const KEY = "{accessKey}";
    
    // gridUrl: gridUrl can be found at automation dashboard
    const GRID_HOST = "hub.lambdatest.com/wd/hub";
    
    function searchTextOnGoogle() {
      // Setup Input capabilities
      const capabilities = {
        platform: "windows 10",
        browserName: "chrome",
        version: "67.0",
        resolution: "1280x800",
        network: true,
        visual: true,
        console: true,
        video: true,
        name: "Test 1", // name of the test
        build: "NodeJS build", // name of the build
      };
    
      // URL: https://{username}:{accessToken}@hub.lambdatest.com/wd/hub
      const gridUrl = `https://${USERNAME}:${KEY}@${GRID_HOST}`;
    
      // setup and build selenium driver object
      const driver = new Builder()
        .usingServer(gridUrl)
        .withCapabilities(capabilities)
        .build();
    
      // navigate to a URL, search for a text and get title of page
      driver.get("https://www.google.com/ncr").then(function () {
        driver
          .findElement(By.name("q"))
          .sendKeys("LambdaTest\n")
          .then(function () {
            driver.getTitle().then((title) => {
              setTimeout(() => {
                if (title === "LambdaTest - Google Search") {
                  driver.executeScript("lambda-status=passed");
                } else {
                  driver.executeScript("lambda-status=failed");
                }
                driver.quit();
              }, 5000);
            });
          });
      });
    }
    
    searchTextOnGoogle();
    
  3. 訪問您的LambdaTest 自動化儀表板,透過點選右上角的key圖示(參見使用者名稱和訪問金鑰)來獲取您的 LambdaTest 的使用者名稱和訪問金鑰。用您的實際使用者名稱和訪問金鑰值替換程式碼中的{username}{accessKey}佔位符(並確保您將它們保密)。
  4. 在您的終端中執行以下命令來執行您的測試
    bash
    node lambdatest_google_test
    
    測試將被髮送到 LambdaTest,並且您的測試輸出將在您的 LambdaTest 控制檯中反映出來。如果您希望從 LambdaTest 平臺提取這些結果以用於報告目的,那麼您可以透過使用LambdaTest restful API來實現。
  5. 現在,如果您轉到您的LambdaTest 自動化儀表板,您將看到您的測試列出;從這裡,您將能夠看到影片、螢幕截圖和其他此類資料。您還將看到透過失敗而不是完成的狀態,因為程式碼中有ifelse程式碼塊。LambdaTest 自動化儀表板 您可以為每個測試版本中的每個測試檢索網路、命令、異常和 Selenium 日誌。您還將找到 Selenium 指令碼執行的影片錄製。

注意:LambdaTest 自動化儀表板上的幫助按鈕將為您提供大量資訊,幫助您開始使用 LambdaTest 自動化。您也可以關注我們關於在 Node JS 中執行第一個 Selenium 指令碼的文件。

注意:如果您不想手動編寫測試的功能物件,您可以使用Selenium Desired Capabilities Generator來生成它們。

BrowserStack

讓 Selenium 測試在 BrowserStack 上遠端執行很簡單。您需要的程式碼應該遵循下面看到的模式。

讓我們編寫一個示例

  1. 在您的專案目錄中,建立一個名為bstack_google_test.js的新檔案。
  2. 賦予它以下內容
    js
    const { Builder, By, Key } = require("selenium-webdriver");
    const request = require("request");
    
    // Input capabilities
    const capabilities = {
      "bstack:options": {
        os: "OS X",
        osVersion: "Sonoma",
        browserVersion: "17.0",
        local: "false",
        seleniumVersion: "3.14.0",
        userName: "YOUR-USER-NAME",
        accessKey: "YOUR-ACCESS-KEY",
      },
      browserName: "Safari",
    };
    
    const driver = new Builder()
      .usingServer("http://hub-cloud.browserstack.com/wd/hub")
      .withCapabilities(capabilities)
      .build();
    
    (async function bStackGoogleTest() {
      try {
        await driver.get("https://www.google.com/");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.sleep(2000);
        const title = await driver.getTitle();
        if (title === "webdriver - Google Search") {
          console.log("Test passed");
        } else {
          console.log("Test failed");
        }
      } finally {
        await driver.sleep(4000); // Delay long enough to see search page!
        await driver.quit();
      }
    })();
    
  3. 從您的BrowserStack 帳戶 - 摘要中獲取您的使用者名稱和訪問金鑰(參見使用者名稱和訪問金鑰)。用您的實際使用者名稱和訪問金鑰值替換程式碼中的YOUR-USER-NAMEYOUR-ACCESS-KEY佔位符(並確保您將它們保密)。
  4. 使用以下命令執行您的測試
    bash
    node bstack_google_test
    
    測試將被髮送到 BrowserStack,測試結果將返回到您的控制檯中。這表明包含某種結果報告機制的重要性!
  5. 現在,如果您返回到BrowserStack 自動化儀表板頁面,您將看到您的測試列出:BrowserStack 自動化結果

如果您單擊測試的連結,您將進入一個新螢幕,在那裡您將能夠看到測試的影片錄製以及多個與之相關的詳細資訊日誌。

注意:Browserstack 自動化儀表板上的資源選單選項包含大量關於如何使用它執行自動化測試的有用資訊。有關 Node JS 特定資訊,請參見在 Node JS 中編寫自動化測試指令碼的 Node JS 文件。探索文件以找出 BrowserStack 可以執行的所有有用操作。

注意:如果您不想手動編寫測試的功能物件,您可以使用文件中嵌入的生成器來生成它們。請參見執行您的第一個測試

以程式設計方式填寫 BrowserStack 測試詳細資訊

您可以使用 BrowserStack REST API 和其他一些功能來為您的測試新增更多詳細資訊,例如它是否透過、為什麼透過、測試屬於哪個專案等等。BrowserStack 預設情況下不知道這些詳細資訊!

讓我們更新我們的bstack_google_test.js演示,以展示這些功能如何工作

  1. 透過在您的專案目錄中執行以下命令來安裝 request 模組
    js
    npm install request
    
  2. 然後,我們需要匯入節點 request 模組,以便我們可以使用它來向 REST API 傳送請求。在程式碼的最上面新增以下行
    js
    const request = require("request");
    
  3. 現在我們將更新我們的capabilities物件以包含專案名稱 - 在關閉的花括號之前新增以下行,記住在上一行的末尾新增逗號(您可以更改構建和專案名稱以在 BrowserStack 自動化儀表板中的不同視窗中組織測試)
    js
    'project' : 'Google test 2'
    
  4. 接下來,我們需要訪問當前會話的sessionId,以便我們知道將請求傳送到哪裡(該 ID 包含在請求 URL 中,您將在後面看到)。將以下幾行新增到建立driver物件的程式碼塊(let driver …)下方。
    js
    let sessionId;
    
    driver.session_.then((sessionData) => {
      sessionId = sessionData.id_;
    });
    
  5. 最後,更新程式碼底部附近的driver.sleep(2000)程式碼塊以新增 REST API 呼叫(同樣,請將程式碼中的YOUR-USER-NAMEYOUR-ACCESS-KEY佔位符替換為您的實際使用者名稱和訪問金鑰值)。
    js
    driver.sleep(2000).then(() => {
      driver.getTitle().then((title) => {
        if (title === "webdriver - Google Search") {
          console.log("Test passed");
          request({
            uri: `https://YOUR-USER-NAME:YOUR-ACCESS-KEY@www.browserstack.com/automate/sessions/${sessionId}.json`,
            method: "PUT",
            form: {
              status: "passed",
              reason: "Google results showed correct title",
            },
          });
        } else {
          console.log("Test failed");
          request({
            uri: `https://YOUR-USER-NAME:YOUR-ACCESS-KEY@www.browserstack.com/automate/sessions/${sessionId}.json`,
            method: "PUT",
            form: {
              status: "failed",
              reason: "Google results showed wrong title",
            },
          });
        }
      });
    });
    

這些程式碼非常直觀——測試完成後,我們會向 BrowserStack 傳送 API 呼叫,以更新測試狀態為透過或失敗,以及結果原因。

現在,如果您返回到BrowserStack 自動化儀表板頁面,您應該會看到您的測試會話可用,如之前一樣,但附加了更新的資料。

BrowserStack Custom Results

Sauce Labs

讓 Selenium 測試在 Sauce Labs 上遠端執行也非常簡單,並且與 BrowserStack 非常類似,只是語法略有不同。您需要的程式碼應遵循以下模式。

讓我們編寫一個示例

  1. 在您的專案目錄中,建立一個名為sauce_google_test.js的新檔案。
  2. 賦予它以下內容
    js
    const { Builder, By, Key } = require("selenium-webdriver");
    const username = "YOUR-USER-NAME";
    const accessKey = "YOUR-ACCESS-KEY";
    
    const driver = new Builder()
      .withCapabilities({
        browserName: "chrome",
        platform: "Windows XP",
        version: "43.0",
        username,
        accessKey,
      })
      .usingServer(
        `https://${username}:${accessKey}@ondemand.saucelabs.com:443/wd/hub`,
      )
      .build();
    
    driver.get("http://www.google.com");
    
    driver.findElement(By.name("q")).sendKeys("webdriver");
    
    driver.sleep(1000).then(() => {
      driver.findElement(By.name("q")).sendKeys(Key.TAB);
    });
    
    driver.findElement(By.name("btnK")).click();
    
    driver.sleep(2000).then(() => {
      driver.getTitle().then((title) => {
        if (title === "webdriver - Google Search") {
          console.log("Test passed");
        } else {
          console.log("Test failed");
        }
      });
    });
    
    driver.quit();
    
  3. 從您的Sauce Labs 使用者設定中獲取您的使用者名稱和訪問金鑰。將程式碼中的YOUR-USER-NAMEYOUR-ACCESS-KEY佔位符替換為您的實際使用者名稱和訪問金鑰值(並確保您將其保密)。
  4. 使用以下命令執行您的測試
    bash
    node sauce_google_test
    
    測試將被髮送到 Sauce Labs,測試結果將返回到您的控制檯。這表明包含某種結果報告機制的重要性!
  5. 現在,如果您轉到Sauce Labs 自動測試儀表板頁面,您將看到您的測試列表;從這裡,您將能夠看到影片、螢幕截圖和其他此類資料。Sauce Labs 自動測試

注意: Sauce Labs 的平臺配置器是一個有用的工具,用於生成要提供給您的驅動程式例項的功能物件,這些物件基於您想要測試的瀏覽器/作業系統。

注意:有關使用 Sauce Labs 和 Selenium 進行測試的更多有用詳細資訊,請檢視Selenium 自動網站測試入門即時 Selenium Node.js 測試

以程式設計方式填寫 Sauce Labs 測試詳細資訊

您可以使用 Sauce Labs API 用更多詳細資訊註釋您的測試,例如它是否透過、測試名稱等。預設情況下,Sauce Labs 不會知道這些詳細資訊!

為此,您需要

  1. 使用以下命令安裝 Node Sauce Labs 包裝器(如果您尚未為該專案完成此操作)
    bash
    npm install saucelabs --save-dev
    
  2. 需要 saucelabs——將此放在sauce_google_test.js檔案的頂部,位於之前的變數宣告下方
    js
    const SauceLabs = require("saucelabs");
    
  3. 建立一個新的 SauceLabs 例項,方法是在其下方新增以下內容
    js
    const saucelabs = new SauceLabs({
      username: "YOUR-USER-NAME",
      password: "YOUR-ACCESS-KEY",
    });
    
    同樣,將程式碼中的YOUR-USER-NAMEYOUR-ACCESS-KEY佔位符替換為您的實際使用者名稱和訪問金鑰值(請注意,saucelabs npm 包比較令人困惑地使用password而不是accessKey)。由於您現在已經使用了兩次,因此您可能希望建立幾個輔助變數來儲存它們。
  4. 在定義driver變數的程式碼塊下方(緊隨build()行之後),新增以下程式碼塊——這將獲取我們需要寫入作業的正確驅動程式sessionID(您可以在下一個程式碼塊中看到它在起作用)
    js
    driver.getSession().then((sessionid) => {
      driver.sessionID = sessionid.id_;
    });
    
  5. 最後,用以下內容替換程式碼底部附近的driver.sleep(2000)程式碼塊
    js
    driver.sleep(2000).then(() => {
      driver.getTitle().then((title) => {
        let testPassed = false;
        if (title === "webdriver - Google Search") {
          console.log("Test passed");
          testPassed = true;
        } else {
          console.error("Test failed");
        }
    
        saucelabs.updateJob(driver.sessionID, {
          name: "Google search results page title test",
          passed: testPassed,
        });
      });
    });
    

在這裡,我們設定了一個testPassed變數,根據測試是透過還是失敗,將其設定為truefalse,然後我們使用saucelabs.updateJob()方法更新詳細資訊。

現在,如果您返回到Sauce Labs 自動測試儀表板頁面,您應該會看到您的新作業現在附加了更新的資料。

Sauce Labs Updated Job info

您自己的遠端伺服器

如果您不想使用 Sauce Labs 或 BrowserStack 等服務,您可以隨時設定自己的遠端測試伺服器。讓我們看看如何做到這一點。

  1. Selenium 遠端伺服器需要 Java 才能執行。從Java SE 下載頁面下載適用於您平臺的最新 JDK。下載完成後進行安裝。
  2. 接下來,下載最新的Selenium 獨立伺服器——它充當您的指令碼和瀏覽器驅動程式之間的代理。選擇最新的穩定版本號(即不是 beta 版),然後從列表中選擇以“selenium-server-standalone”開頭的檔案。下載完成後,將其放在一個合適的位置,例如您的主目錄中。如果您尚未將該位置新增到您的PATH中,請立即新增(請參閱在 Node 中設定 Selenium部分)。
  3. 透過在伺服器計算機上的終端中輸入以下內容來執行獨立伺服器
    bash
    java -jar selenium-server-standalone-3.0.0.jar
    
    (更新.jar檔名)使其與您擁有的檔案完全匹配。
  4. 伺服器將在https://:4444/wd/hub上執行——現在嘗試訪問該地址,看看會發生什麼。

現在,伺服器已經執行,讓我們建立一個將在遠端 Selenium 伺服器上執行的演示測試。

  1. 複製您的google_test.js檔案,並將其命名為google_test_remote.js;將其放在您的專案目錄中。
  2. 更新程式碼行(以const driver = …開頭)如下
    js
    const driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .usingServer("https://:4444/wd/hub")
      .build();
    
  3. 執行您的測試,您應該會看到它按預期執行;但是這次,您將在獨立伺服器上執行它。
    bash
    node google_test_remote.js
    

所以這很酷。我們已經在本地測試過它,但您可以將其設定在幾乎任何伺服器上,以及相關的瀏覽器驅動程式,然後使用您選擇公開的 URL 連線您的指令碼。

將 Selenium 與 CI 工具整合

另外一點是,還可以將 Selenium 和 LambdaTest、Sauce Labs 等相關工具與持續整合 (CI) 工具整合——這很有用,因為這意味著您可以透過 CI 工具執行測試,並且只有在測試透過時才將新更改提交到您的程式碼儲存庫。

在本文中詳細介紹這個領域不在我們的範圍之內,但我們建議您從 Travis CI 開始——這可能是最容易上手的 CI 工具,並且與 GitHub 和 Node 等 Web 工具有很好的整合。

要開始使用,請參閱例如

注意:如果您希望使用無程式碼自動化執行持續測試,那麼您可以使用EndtestTestingBot

摘要

本模組應該很有趣,並且應該讓您對編寫和執行自動化測試有足夠的瞭解,以便您可以開始編寫自己的自動化測試。