设置你自己的测试自动化环境

在本文中,我们将教你如何安装自己的自动化环境,并使用 Selenium/WebDriver 和一个测试库(例如 Node 的 selenium-webdriver)运行自己的测试。我们还将探讨如何将本地测试环境与上一篇文章中讨论的商业工具集成。

预备知识 熟悉核心的 HTMLCSSJavaScript 语言;了解 跨浏览器测试自动化测试 的高级原则。
目标 展示如何在本地设置 Selenium 测试环境并运行测试,以及如何将其与 LambdaTest、Sauce Labs 和 BrowserStack 等工具集成。

Selenium

Selenium 是最流行的浏览器自动化工具。虽然还有其他方法,但使用 Selenium 的最佳方式是通过 WebDriver,这是一个功能强大的 API,它建立在 Selenium 之上,并调用浏览器进行自动化操作,执行诸如“打开此网页”、“将鼠标悬停在此页面元素上”、“点击此链接”、“查看此链接是否打开此 URL”等操作。这对于运行自动化测试非常理想。

如何安装和使用 WebDriver 取决于你希望使用哪种编程环境来编写和运行测试。大多数流行的环境都提供了包或框架,用于安装 WebDriver 以及使用该语言(例如 Java、C#、Ruby、Python、JavaScript (Node) 等)与 WebDriver 通信所需的绑定。有关不同语言的 Selenium 设置的更多详细信息,请参阅设置 Selenium-WebDriver 项目

不同的浏览器需要不同的驱动程序,以允许 WebDriver 与它们通信并控制它们。有关从何处获取浏览器驱动程序等的更多信息,请参阅Selenium 支持的平台

我们将介绍如何使用 Node.js 编写和运行 Selenium 测试,因为它启动快速简便,并且对于前端开发人员来说是一个更熟悉的环境。

注意:如果你想了解如何在其他服务器端环境中使用 WebDriver,还可以查看Selenium 支持的平台以获取一些有用的链接。

在 Node 中设置 Selenium

  1. 首先,按照上一章中设置 Node 和 npm 中讨论的方法,设置一个新的 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. 打开你的 .zprofile(如果你的系统使用 bash shell,则为 .bash_profile)文件。

    注意:如果你看不到隐藏文件,你需要显示它们,请参阅在 macOS 中快速显示/隐藏隐藏文件在 Ubuntu 中显示隐藏文件夹)。

  2. 将以下内容粘贴到文件底部(根据你机器上的实际路径更新路径)

    bash
    # Add WebDriver browser drivers to PATH
    export PATH=$PATH:/Users/bob
    
  3. 保存并关闭此文件,然后重新启动你的终端/命令提示符以重新应用你的 Bash 配置。

  4. 通过在终端中输入以下内容,检查你的新路径是否在 PATH 变量中

    bash
    echo $PATH
    

    你会在终端中看到它被打印出来。

注意:要在 Windows 上设置 PATH 变量,请按照 如何将新文件夹添加到我的系统路径? 中的说明操作。

让我们做一个快速测试,以确保一切正常。

  1. 在你的项目目录中创建一个名为 duck_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://duckduckgo.com/");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.wait(until.titleIs("webdriver at DuckDuckGo"), 1000);
        console.log("Test passed!");
      } catch (e) {
        console.log(`Error: ${e}`);
      } finally {
        await driver.sleep(2000); // Delay long enough to see search page!
        await driver.quit();
      }
    })();
    

    注意:此函数是一个 IIFE(立即执行函数表达式)。

  3. 在终端中,确保你位于项目文件夹内,然后输入以下命令:

    bash
    node duck_test
    

你应该会看到一个 Firefox 实例自动打开!DuckDuckGo 将自动在一个标签页中加载,“webdriver”将被输入到搜索框中,并点击搜索按钮。WebDriver 将然后等待 1 秒;然后访问文档标题,如果它是“webdriver at DuckDuckGo”,我们将返回一条消息,表明测试通过。

然后我们等待 2 秒,之后 WebDriver 将关闭 Firefox 实例并停止。

同时在多个浏览器中测试

没有什么能阻止你同时在多个浏览器上运行测试。让我们试试这个!

  1. 在你的项目目录中创建另一个名为 duck_test_multiple.js 的新文件。你可以随意更改对我们添加的其他一些浏览器的引用、删除它们等,具体取决于你的操作系统上有哪些可用的浏览器进行测试。你需要确保你的系统上已设置正确的浏览器驱动程序。至于在 .forBrowser() 方法中用于其他浏览器的字符串,请参阅 Browser enum 参考页面。

  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("https://duckduckgo.com/");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.sleep(2000);
        const title = await driver.getTitle();
        if (title === "webdriver at DuckDuckGo") {
          console.log("Test passed");
        } else {
          console.log("Test failed");
        }
      } finally {
        driver.quit();
      }
    }
    
    searchTest(driver_fx);
    searchTest(driver_chr);
    
  3. 在终端中,确保你位于项目文件夹内,然后输入以下命令:

    bash
    node duck_test_multiple
    

注意:如果你使用 Mac 并决定测试 Safari,你可能会收到类似“无法创建会话:你必须在 Safari 的开发菜单中启用‘允许远程自动化’选项,才能通过 WebDriver 控制 Safari。”的错误消息。如果遇到此问题,请按照给定的说明操作,然后重试。

你可能会收到一条消息,说你无法打开驱动程序应用程序,因为它不是从经过验证的来源下载的。如果你收到此消息,你可以仅为该驱动程序应用程序覆盖该安全设置。例如,在 Mac 上,按 Ctrl + 点击应用程序,选择“打开”,然后从弹出的对话框中再次选择“打开”。

所以这里我们像以前一样进行了测试,只不过这次我们把它封装在一个函数 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, "130", "MAC").build();

你也可以使用环境变量设置这些选项,例如:

bash
SELENIUM_BROWSER=firefox:130:MAC

让我们创建一个新的测试,以便在我们讨论代码时进行探索。在你的 Selenium 测试项目目录中,创建一个名为 quick_test.js 的新文件,并向其中添加以下代码:

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

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

你可以通过在终端中输入以下命令来测试该示例:

bash
node quick_test

获取要测试的文档

要加载你实际要测试的页面,你使用你之前创建的驱动程序实例的 get() 方法,例如:

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

注意:有关本节及以下功能的详细信息,请参阅 WebDriver 类参考

你可以使用任何 URL 指向你的资源,包括 file:// URL 来测试本地文档。

js
driver.get("file:///Users/bob/git/examples/test_file.html");

or

js
driver.get("https://:8888/test_file.html");

但最好使用远程服务器位置,这样代码更灵活——当你开始使用远程服务器运行测试时(参见后文),如果你尝试使用本地路径,你的代码将中断。

如下更新你的 example() 函数,用你计算机上 HTML 文件的真实本地路径替换占位符路径,然后尝试运行它:

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

(async function example() {
  const driver = await new Builder().forBrowser(Browser.FIREFOX).build();
  driver.get("file:///Users/bob/git/examples/test_file.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}'`);
  });
})();

像以前一样使用 node 运行示例。你应该会在控制台中看到按钮的文本标签。

让我们做一些更有用的事情。将之前的代码替换为 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, Key } = 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("Bob Smith");

  input.sendKeys(Key.TAB);

  const input2 = driver.findElement(By.id("age"));
  input2.sendKeys("65");
})();

你可以使用 Key 对象的属性提交无法用普通字符表示的按键。例如,上面我们使用以下方法在表单输入之间进行切换:

js
input.sendKeys(Key.TAB);

等待某事完成

有些时候你会希望让 WebDriver 等待某件事情完成后再继续。例如,如果你加载一个新页面,你会希望等待页面的 DOM 完成加载,然后才尝试与其任何元素交互,否则测试很可能会失败。

例如,在我们的 duck_test_multiple.js 测试中,我们包含了这一行:

js
await driver.sleep(2000);

sleep() 方法接受一个值,该值指定等待的时间(以毫秒为单位)——该方法返回一个 Promise,该 Promise 在该时间结束时解析。我们使用 await 关键字暂停封闭函数,直到 Promise 解析,之后执行该方法之后的代码。

我们也可以在 quick_test.js 测试中添加一个 sleep() 方法——尝试像这样更新你的 example() 函数:

js
const { Builder, Browser, By, Key } = 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("Bob Smith");

  driver.sleep(1000).then(() => {
    input.getAttribute("value").then((value) => {
      if (value !== "") {
        console.log("Form input filled out");
      } else {
        console.log("Text could not be entered");
      }
    });
  });
})();

尝试运行更新后的代码。WebDriver 现在将填写第一个表单字段,等待一秒钟,然后通过使用 getAttribute() 检索其 value 属性值来测试其值是否已填写(即不为空)。然后它会向控制台打印一条消息以报告成功/失败。

注意:还有一个方法叫做 wait(),它会重复测试一个条件一段时间,然后继续执行代码。这也利用了 util 库,该库定义了与 wait() 一起使用的常见条件。

使用后关闭驱动程序

运行完测试后,你应该使用 driver.quit() 方法关闭所有已打开的驱动程序实例,以确保它们不会不必要地继续占用资源。如下更新 quick_test.js

js
const { Builder, Browser, By, Key } = 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("Bob Smith");

  driver.sleep(1000).then(() => {
    input
      .getAttribute("value")
      .then((value) => {
        if (value !== "") {
          console.log("Form input filled out");
        } else {
          console.log("Text could not be entered");
        }
      })
      .finally(() => {
        driver.quit();
      });
  });
})();

现在当你运行它时,你应该会看到测试执行,并且在测试完成后浏览器实例再次关闭。

测试最佳实践

关于编写测试的最佳实践已经有很多论述。你可以在 测试实践 中找到一些不错的背景信息。通常,你应该确保你的测试是:

  1. 使用好的定位策略:当您与文档交互时,请确保您使用不太可能更改的定位器和页面对象——如果您有一个可测试的元素要执行测试,请确保它具有稳定的 ID,或页面上可以使用 CSS 选择器选择的位置,该位置不会随着下一个站点迭代而更改。您希望您的测试尽可能不脆弱,即它们不会在某些内容更改时轻易中断。
  2. 编写原子测试:每个测试只测试一件事,以便轻松跟踪哪个测试文件正在测试哪个标准。我们上面看的 duck_test.js 测试相当好,因为它只测试一件事——搜索结果页面的标题是否设置正确。我们可以努力给它一个更好的名字,以便在添加更多测试时更容易理解它做什么。也许 results_page_title_set_correctly.js 会稍微好一点?
  3. 编写自主测试:每个测试都应该独立工作,不依赖于其他测试才能工作。

此外,我们应该提到测试结果/报告——我们在上面的示例中使用简单的 console.log() 语句报告结果,但这都是在 JavaScript 中完成的,因此你可以使用任何你想要的测试运行和报告系统,无论是 MochaChai 还是其他工具。让我们快速过一个示例:

  1. 在您的项目目录中创建我们的 mocha_test.js 示例的本地副本。将其放在名为 test 的子文件夹中。此示例使用一个长的 Promise 链来运行我们测试中所需的所有步骤——WebDriver 使用的基于 Promise 的方法需要解析才能正常工作。

  2. 通过在你的项目目录中运行以下命令来安装 mocha 测试工具:

    bash
    npm install --save-dev mocha
    
  3. 你现在可以使用以下命令运行测试(以及你放置在 test 目录中的任何其他测试):

    bash
    npx mocha --no-timeouts
    
  4. 你应该包含 --no-timeouts 标志,以确保你的测试不会因为 Mocha 的任意超时(3 秒)而失败。

注意:saucelabs-sample-test-frameworks 包含几个有用的示例,展示了如何设置不同组合的测试/断言工具。

运行远程测试

事实证明,在远程服务器上运行测试并不比在本地运行测试困难多少。你只需要创建你的驱动程序实例,但要指定更多的特性,包括你想要测试的浏览器的功能、服务器的地址以及访问它所需的(如果有的话)用户凭据。

BrowserStack

让我们创建一个示例,演示如何在 BrowserStack 上远程运行 Selenium 测试。

  1. 在你的项目目录中,创建一个名为 bstack_duck_test.js 的新文件。

  2. 给它以下内容:

    js
    const { Builder, By, Key } = require("selenium-webdriver");
    
    // 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://duckduckgo.com/");
        await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN);
        await driver.sleep(2000);
        const title = await driver.getTitle();
        if (title === "webdriver at DuckDuckGo") {
          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 账户和个人资料详细信息页面中,获取你的用户名和访问密钥(参见“用户名和访问密钥”)。

  4. 将代码中的 YOUR-USER-NAMEYOUR-ACCESS-KEY 占位符替换为你的实际用户名和访问密钥值(并确保它们安全)。

  5. 使用以下命令运行你的测试:

    bash
    node bstack_google_test
    

    测试将发送到 BrowserStack,测试结果将返回到你的控制台。这显示了包含某种结果报告机制的重要性!

  6. 现在,如果你回到 BrowserStack 自动化仪表板,你将看到你的测试已列出,其中包含详细信息,包括测试的视频录制以及与其相关的多个详细信息日志:BrowserStack 自动化结果

注意:Browserstack 自动化仪表板上的“资源”菜单选项包含大量有关使用它运行自动化测试的有用信息。有关 Node specific 信息,请参阅 NodeJS 上的 Selenium

以编程方式填写 BrowserStack 测试详情

你可以使用 BrowserStack REST API 和其他一些功能来为你的测试添加更多细节,例如它是否通过,为什么通过,测试属于哪个项目等。BrowserStack 默认不了解这些细节。

让我们更新我们的 bstack_duck_test.js 演示,展示这些功能是如何工作的:

  1. 通过在你的项目目录中运行以下命令来安装 axios 模块:

    bash
    npm install axios
    
  2. 导入 axios 模块,以便我们可以使用它向 BrowserStack REST API 发送请求。在代码的最顶部添加以下行:

    js
    const axios = require("axios");
    
  3. 现在我们将更新我们的 capabilities 对象,以包含一个项目名称——在右括号之前添加以下行,请记住在上一行的末尾添加一个逗号(你可以更改构建和项目名称,以在 BrowserStack 自动化仪表板中以不同窗口组织测试):

    js
    const capabilities = {
      // …
      project: "DuckDuckGo test 2",
    };
    
  4. 接下来,我们将检索当前会话的 sessionId,并使用它(以及您的 userNameaccessKey)来组装发送请求的 URL,以更新 BrowserStack 数据。在创建 driver 对象的块下方(以 const driver = new Builder() 开头)包含以下行:

    js
    let sessionId;
    let bstackURL;
    
    driver.session_.then((sessionData) => {
      sessionId = sessionData.id_;
      bstackURL = `https://${capabilities["bstack:options"].userName}:${capabilities["bstack:options"].accessKey}@www.browserstack.com/automate/sessions/${sessionId}.json`;
    });
    
  5. 最后,更新代码底部附近的 if...else 块,根据测试通过或失败向 BrowserStack 发送适当的 API 调用:

    js
    if (title === "webdriver at DuckDuckGo") {
      console.log("Test passed");
      axios.put(bstackURL, {
        status: "passed",
        reason: "DuckDuckGo results showed correct title",
      });
    } else {
      console.log("Test failed");
      axios.put(bstackURL, {
        status: "failed",
        reason: "DuckDuckGo results showed wrong title",
      });
    }
    

测试完成后,我们会向 BrowserStack 发送 API 调用,以更新测试并通过或失败状态以及结果原因。

如果你现在回到 BrowserStack 自动化仪表板,你应该会看到你的测试会话和以前一样,但附加了你的自定义数据。它显示状态为“通过”,以及 REST API 报告的通过原因:

BrowserStack Custom Results

Sauce Labs

让我们看一个示例,演示如何在 Sauce Labs 上远程运行 Selenium 测试:

  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

总结

这个模块应该很有趣,并且应该为您提供了足够的编写和运行自动化测试的见解,让您开始编写自己的自动化测试。