1. 概述

回归测试通过提供关键反馈确保构建版本可发布。随着代码库因新需求、缺陷修复和功能增强而不断演进,频繁运行这些测试对维护软件质量至关重要。

在 CI/CD 流水线中运行回归测试至关重要,因为当我们向远程仓库提交代码时,它们会自动执行,提供快速反馈

本教程将学习如何使用 GitHub Actions 运行 Selenium 回归测试。

2. GitHub Actions 是什么?

GitHub Actions 自动化构建、测试和部署工作流,这些工作流会构建和测试每个推送到远程仓库的拉取请求,从而实现更快的反馈循环。

这种反馈帮助我们在进入生产环境前修复问题。GitHub Actions 工作流可在 Windows、macOS 和 Linux 虚拟机上运行,也可在数据中心或云基础设施的自托管运行器上运行。

我们还可以将 GitHub Actions 与各种工具和框架结合使用来运行回归测试。例如,GitHub Actions 可以帮助执行使用 Selenium 进行自动化浏览器测试,使回归测试更高效。

3. 使用 GitHub Actions 运行 Selenium 回归测试

在讨论如何在 GitHub Actions 上运行 Selenium 回归测试之前,我们先了解项目设置、配置、测试场景和实现。

3.1. 设置和配置

在 Maven 项目的 pom.xml 文件中添加 Selenium WebDriver 依赖TestNG 依赖

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.27.0</version>
</dependency>

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>7.10.2</version>
    <scope>test</scope>
</dependency>

还需要添加 maven-surefire-plugin,因为它能在我们使用 GitHub Actions 工作流运行 mvn clean install 命令时执行 testng.xml 文件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.2.5</version>
    <executions>
        <execution>
            <goals>
                <goal>test</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <useSystemClassLoader>false</useSystemClassLoader>
        <properties>
            <property>
                <name>usedefaultlisteners</name>
                <value>false</value>
            </property>
        </properties>
        <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
        </suiteXmlFiles>
        <argLine>${argLine}</argLine>
    </configuration>
</plugin>

我们将使用 GitHub Actions 在云端运行 Selenium 回归测试,借助 LambdaTest 这类平台

LambdaTest 是一个 AI 驱动的测试执行平台,支持在 3000+ 真实浏览器、浏览器版本和操作系统上执行自动化测试

创建 BaseTest.java 添加所有 Selenium 和 LambdaTest 配置信息:

public class BaseTest {
    protected RemoteWebDriver driver;

    // 其他代码和方法...
}

BaseTest 类中添加 setup() 方法,在测试运行前配置 Selenium 和 LambdaTest:

@BeforeTest
public void setup() {
    String userName = System.getenv("LT_USERNAME") == null 
      ? "LT_USERNAME" 
      : System.getenv("LT_USERNAME");
    String accessKey = System.getenv("LT_ACCESS_KEY") == null 
      ? "LT_ACCESS_KEY" 
      : System.getenv("LT_ACCESS_KEY");
    String gridUrl = "@hub.lambdatest.com/wd/hub";
    try {
        this.driver = new RemoteWebDriver(
          new URL("http://" + userName + ":" + accessKey + gridUrl),
          getChromeOptions()
        );
    } catch (MalformedURLException e) {
        LOG.error("Could not start the remote session on LambdaTest cloud grid");
    }
    this.driver.manage()
      .timeouts()
      .implicitlyWait(Duration.ofSeconds(5));
}

平台、浏览器版本等 LambdaTest 相关配置将从 BaseTest 类中的 getChromeOptions() 方法获取。要生成自动化配置,可使用 LambdaTest 的自动化配置生成器

public ChromeOptions getChromeOptions() {
    var browserOptions = new ChromeOptions();
    browserOptions.setPlatformName("Windows 10");
    browserOptions.setBrowserVersion("latest");

    HashMap<String, Object> ltOptions = new HashMap<>();
    ltOptions.put("project", "LambdaTest e-commerce website automation");
    ltOptions.put("build", "LambdaTest e-commerceV1.0.0");
    ltOptions.put("name", "Homepage search product test");
    ltOptions.put("w3c", true);
    ltOptions.put("plugin", "java-testNG");

    browserOptions.setCapability("LT:Options", ltOptions);

    return browserOptions;
}

所有测试执行后,tearDown() 方法会更新 LambdaTest 云端测试状态并关闭驱动会话:

@AfterTest
public void tearDown() {
    this.driver.executeScript("lambda-status=" + this.status);
    this.driver.quit();
}

接下来我们将使用 Selenium 在 GitHub Actions 上实现以下测试场景,在 LambdaTest 云端最新版 Chrome 浏览器上运行。

3.2. 测试场景

使用以下场景演示使用 GitHub Actions 进行 Selenium 回归测试:

  1. 访问 LambdaTest 电子商务演示网站
  2. 在首页搜索产品。
  3. 验证产品搜索页面返回正确的产品详情。

3.3. 测试实现

创建 LambdaTestEcommerceTests 类实现测试场景,编写自动化测试脚本。该类继承 BaseTest 类以复用其字段和方法:

public class LambdaTestEcommerceTests extends BaseTest {
    @Test
    public void whenUserSearchesForAProduct_thenSearchResultsShouldBeDisplayed() {
        String productName = "iPhone";
        driver.get("https://ecommerce-playground.lambdatest.io/");
        HomePage homePage = new HomePage(driver);
        SearchResultPage searchResultPage = homePage.searchProduct(productName);
        searchResultPage.verifySearchResultPageHeader(productName);
        this.status = "passed";
    }
}

测试中使用了两个页面对象类。第一个是 HomePage 类,包含首页的所有页面对象和操作:

public class HomePage {
    private RemoteWebDriver driver;

    public HomePage(RemoteWebDriver driver) {
        this.driver = driver;
    }

    public SearchResultPage searchProduct(String productName) {
        WebElement searchBox = driver.findElement(By.name("search"));
        searchBox.sendKeys(productName);
        WebElement searchBtn = driver.findElement(By.cssSelector("button.type-text"));
        searchBtn.click();
        return new SearchResultPage(driver);
    }
}

searchProduct() 方法接受 productName 参数并搜索指定产品。成功搜索后出现搜索结果页面,因此该方法返回 SearchResultPage 类的新实例:

public class SearchResultPage {
    private RemoteWebDriver driver;

    public SearchResultPage(RemoteWebDriver driver) {
        this.driver = driver;
    }

    public void verifySearchResultPageHeader(String productName) {
        String pageHeader = driver.findElement(By.tagName("h1"))
          .getText();
        assertEquals(pageHeader, "Search - " + productName);
    }
}

verifySearchResultPageHeader() 方法检查搜索页面的标题是否包含搜索的产品文本。

3.4. 测试执行

创建 testng.xml 文件在 LambdaTest 云平台执行 Selenium 回归测试:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Selenium GitHub Actions demo">
  <test name="Searching a product from the HomePage">
      <classes>
          <class name="com.baeldung.LambdaTestEcommerceTests">
              <methods>
                  <include name="whenUserSearchesForAProduct_thenSearchResultsShouldBeDisplayed"/>
              </methods>
          </class>
      </classes>
  </test>
</suite>

3.5. 设置 GitHub Actions

设置和配置 GitHub Actions 需要以下先决条件:

  • GitHub 账户
  • GitHub 仓库

创建 GitHub 账户和仓库后,导航到 Actions 标签页配置 Java with Maven Action 工作流:

actions-tab

3.6. 创建 GitHub Actions 工作流

GitHub 会自动为我们生成工作流文件。可以选择继续使用 GitHub 提供的默认工作流,或添加自定义内容。

由于需要在 LambdaTest 云平台运行 Selenium 回归测试,我们将根据需求更新工作流内容:

name: Java CI with Maven

on:
  push:
    branches:
      - "main"
      - "test-*"
  pull_request:
    branches:
      - "main"
      - "test-*"

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      LT_USERNAME: ${{ secrets.LT_USERNAME }}
      LT_ACCESS_KEY: ${{ secrets.LT_ACCESS_KEY }}

    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven
      - name: Build and Test with Maven
        run: mvn clean install

需要在 LambdaTest 云端运行测试,因此必须将 LambdaTest 用户名和访问密钥添加为密钥。此外,我们将 Maven 命令更新为 mvn clean install,因为它能一次性下载所有依赖、构建项目并运行测试。

可通过导航到 GitHub 仓库的 Settings > Secrets and Variables > Actions 添加密钥值

new-repository

在 Actions Secrets and Variables 页面,点击 New repository secret 添加密钥变量及其值。

3.7. 触发 GitHub Actions 工作流

使用工作流文件中的 on 关键字可为单个或多个事件触发 GitHub Actions 工作流

按以下步骤在推送代码或创建拉取请求时触发工作流:

  1. 将工作流文件添加到 GitHub 仓库。我们将分支命名为 maven_github_actions,与 on push branches / on pull_request branches 名称 maven_ 匹配。

  2. maven_github_actions 分支中修改代码。推送代码到分支并向主分支创建拉取请求。成功推送后工作流自动触发,可在 GitHub 仓库的 Actions 标签页查看状态:

action-tab

点击工作流运行可查看详细作业信息。

工作流运行完成后,可在 LambdaTest Web Automation 仪表板查看 Selenium 回归测试结果:

web-automation-dashboard

构建作业实际运行在用户选择的配置机器上。该机器名称通过工作流中 jobs 块内的 runs-on 关键字设置。

本例中,我们使用 ubuntu-latest 机器运行 GitHub Actions 工作流。

4. 总结

GitHub Actions 有助于建立自动化流水线并运行各种工作流,包括回归测试。它可在多个事件(如向仓库推送代码或通过拉取请求合并代码到主分支)时触发工作流。这些工作流运行提供构建的快速反馈,使我们能在应用发布到生产环境前采取纠正措施。


原始标题:How to Run Selenium Regression Tests With GitHub Actions | Baeldung