Ohhnews

分类导航

$ cd ..
Baeldung原文

WebDriverManager 自动化驱动程序管理入门指南

#selenium#自动化测试#java#浏览器驱动#webdrivermanager

1. 简介

Java Web 自动化的目的很简单:本质上就是打开浏览器并与网页进行交互。然而,浏览器本身带来了一个直接的挑战,即二进制兼容性问题。具体来说,每个浏览器都需要相应的驱动程序二进制文件,且该文件必须与安装的浏览器版本相匹配。即使是微小的版本不匹配也会导致运行时错误。Java 中的 WebDriverManager 通过在基于 Java 的 Selenium 项目中实现驱动程序管理的自动化,解决了这一问题。

在本教程中,我们将介绍 WebDriverManager。首先,我们将探讨该驱动程序的目的和必要性。随后,我们将了解如何在代码中引入 WebDriverManager。最后,我们将讨论 WebDriverManager 与不同库的集成。

2. 什么是 WebDriverManager

WebDriverManager 是一个 Java 库,可以自动解析、下载和配置 Selenium 所需的浏览器驱动程序。该库无需手动管理二进制文件和系统属性,而是以编程方式处理这些步骤。它会自动检测已安装的浏览器版本,查找正确的驱动程序版本,在必要时进行下载,并完成配置以便 Selenium 使用。

值得注意的是,Selenium 包含一个名为 Selenium Manager 的内置工具,它也能实现驱动管理的自动化,消除了手动下载浏览器驱动的需要。然而,WebDriverManager 是一个功能更强大的替代方案,具备驱动缓存控制、支持 Docker 化浏览器以及在复杂环境中更灵活等额外特性。

传统的 Selenium 设置需要在代码中显式指定驱动程序路径。例如,对于 Chrome 浏览器,我们使用 setProperty 设置驱动:

$ java
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();

这种方法在初期有效,但扩展性较差。每当浏览器更新时,相应的驱动程序也必须手动更新。在 CI/CD 流水线或团队项目等共享环境中,保持驱动版本的一致性变得非常困难。此外,硬编码路径也使得代码在不同系统间的可移植性变差。

相比之下,WebDriverManager 通过动态处理驱动解析消除了这种负担。它还会将下载的驱动程序缓存在本地,因此重复执行测试不会触发不必要的下载。结果是,测试执行变得更快且更可靠。

要使用 WebDriverManager,我们需要将其作为依赖项添加到 XML 文件中。

对于 Maven,我们使用 <dependency> 标签:

$ xml
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>6.3.3</version>
    <scope>test</scope>
</dependency>

对于 Gradle,我们使用依赖项配置:

$ gradle
dependencies {
    testImplementation("io.github.bonigarcia:webdrivermanager:6.3.3")
}

这确保了该库仅在测试执行期间可用,而不会影响生产构建。

3. 使用 WebDriverManager

在这个示例中,我们来看一种使用 WebDriverManager 进行简单调用的基本方法:

$ java
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SimpleWebDriver {
     public static void main(String[] args) {
          WebDriverManager.chromedriver().setup();
          WebDriver driver = new ChromeDriver();
          driver.get("https://google.com");
          driver.quit();
     }
}

在上面的例子中,WebDriverManager.chromedriver() 创建了一个专门针对 Chrome 的管理器实例。该实例隐藏了处理 ChromeDriver 二进制文件所需的所有逻辑。

进一步解释代码,调用 .setup() 会触发解析过程

  1. 检查系统以检测已安装的 Chrome 版本。
  2. 确定兼容的驱动程序版本。
  3. 如果尚未缓存,则下载正确的驱动程序版本。
  4. 设置相应的系统属性 webdriver.chrome.driver

因此,随后的 ChromeDriver() 行无需任何手动配置即可正常工作。

此外,driver.get() 打开指定的 URL,而 driver.quit() 关闭浏览器并释放资源。

4. 在不同库中使用 WebDriverManager

在本节中,我们将探讨 WebDriverManager 如何与 JUnit 集成以进行结构化测试执行,以及它如何通过统一的接口支持多种浏览器。此外,我们还将探讨它如何扩展到更高级的用例,例如通用驱动程序实例化和浏览器检测。

4.1. 在 JUnit 中使用 WebDriverManager

在专业的测试环境中,最佳实践是每个测试类执行一次设置操作,而不是在每次单个测试之前重复执行。当结合 JUnit 5 的 @BeforeAll 注解时,WebDriverManager 正好符合这一模式:

$ java
import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class GoogleTest {
    @BeforeAll
    static void setupClass() {
        WebDriverManager.chromedriver().setup();
    }

    @Test
    void testGoogle() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.google.com");
        driver.quit();
    }
}

@BeforeAll 注解保证了 setupClass() 方法在类中的任何测试方法运行之前仅执行一次。通过在此阶段调用 WebDriverManager.chromedriver().setup(),框架会提前下载并配置正确的 ChromeDriver 二进制文件,因此后续测试无需重复此过程。这避免了每个测试用例中冗余的驱动程序解析。一旦设置完成,每个单独的测试方法就可以专注于浏览器交互、导航至 URL 以及退出驱动程序。

4.2. 使用多种浏览器

WebDriverManager 的优势之一是它能够使用相同的一致模式管理多种浏览器的驱动程序。该库不需为每个浏览器编写单独的设置逻辑,而是提供了专用的管理器方法,无论目标浏览器是什么,它们都遵循相同的结构:

$ java
// Firefox
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new org.openqa.selenium.firefox.FirefoxDriver();

// Microsoft Edge
WebDriverManager.edgedriver().setup();
WebDriver driver = new org.openqa.selenium.edge.EdgeDriver();

每个方法都会返回一个特定于浏览器的管理器对象,该对象处理相应浏览器驱动程序二进制文件的解析和配置。

4.3. 通用管理器用法

通用管理器用法的一种场景是当我们在编译时不知道目标浏览器类型时。

例如,当浏览器类型作为运行时参数传递,或者从配置文件中读取时,我们可以使用 WebDriverManager 动态确定相应的管理器

$ java
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class GenericExample {
    public static void main(String[] args) {
        WebDriverManager.getInstance(ChromeDriver.class).setup();
        WebDriver driver = new ChromeDriver();
        driver.get("https://example.com");
        driver.quit();
    }
}

在上面的代码中,getInstance(ChromeDriver.class) 调用接受一个驱动程序类作为参数,并使用它在运行时识别并返回正确的管理器。这意味着只需更换类引用,同一行代码就可以解析任何受支持浏览器的管理器。在实际应用中,这在参数化或数据驱动的测试框架中非常有用,因为浏览器类型通常是从外部源注入的。

5. 结论

在本文中,我们首先对 WebDriverManager 进行了基本介绍。我们还讨论了如何将此驱动程序用于 Selenium 自动化,并探讨了如何将其与各种库结合使用。

总而言之,WebDriverManager 通过消除手动驱动程序管理简化了 Selenium 自动化。项目无需再处理下载、版本兼容性和配置问题,只需调用一个方法即可完成所有设置任务。这有助于保持代码整洁、减少运行时错误并提高可维护性。

源代码可在 GitHub 上获取