返回介绍

4.3.2 使用 Selenium 测试 HTML 页面

发布于 2025-04-21 21:10:08 字数 4111 浏览 0 评论 0 收藏 0

RestTemplate 对于简单的请求而言使用方便,是测试 REST 端点的理想工具。但是,就算它能对返回 HTML 页面的 URL 发起请求,也不方便对页面内容或者页面上执行的操作进行断言。结果 HTML 里的内容最好能够精确判断(这种测试很脆弱)。不过你无法轻易判断页面上选中的内容,或者执行诸如点击链接或提交表单这样的操作。

对于 HTML 应用程序测试,有一个更好的选择 - Selenium( www.seleniumhq.org ),它的功能远不止提交请求和获取结果。它能实际打开一个 Web 浏览器,在浏览器的上下文中执行测试。Selenium 尽量接近手动执行测试,但与手工测试不同。Selenium 的测试是自动的,而且可以重复运行。

为了用 Selenium 测试阅读列表应用程序,让我们先写一个测试来获取首页,为新书填写表单,提交表单,随后判断返回的页面里是否包含新添加的图书。

首先需要把 Selenium 作为测试依赖添加到项目里:

testCompile("org.seleniumhq.selenium:selenium-java:2.45.0")

现在就可以编写测试了。代码清单 4-6 是一个基本的 Selenium 测试模板,使用了 Spring Boot 的 @WebIntegrationTest

代码清单 4-6 在 Spring Boot 里使用 Selenium 测试的模板

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(
      classes=ReadingListApplication.class)
@WebIntegrationTest(randomPort=true)      ←---用随机端口启动
public class ServerWebTests {

  private static FirefoxDriver browser;

  @Value("${local.server.port}")     ←---注入端口号
  private int port;

  @BeforeClass
  public static void openBrowser() {
    browser = new FirefoxDriver();
    browser.manage().timeouts()
        .implicitlyWait(10, TimeUnit.SECONDS);    ←---配置 Firefox 驱动
  }

  @AfterClass
  public static void closeBrowser() {
    browser.quit();     ←---关闭浏览器
  }

}

和之前更简单的 Web 测试一样,这个类添加了 @WebIntegrationTest 注解,将 randomPort 设置为 true ,这样应用程序启动后会运行一个监听随机端口的服务器。同样,端口号注入 port 属性,这样我们就能用它来构造指向运行中应用程序的 URL 了。

静态方法 openBrowser() 会创建一个 FirefoxDriver 的实例,它将打开 Firefox 浏览器(需要在运行测试的服务器上安装该浏览器)。我们的测试方法将通过 FirefoxDriver 实例来执行浏览器操作。在页面上查找元素时, FirefoxDriver 配置了 10 秒的等候时间(以防元素加载过慢)。

测试执行完毕,我们需要关闭 Firefox 浏览器。因此要在 closeBrowser() 里要调用 FirefoxDriver 实例的 quit() 方法,关闭浏览器。

选择浏览器 虽然我们用 Firefox 进行了测试,但 Selenium 还提供了不少其他浏览器的驱动,包括 IE、Google 的 Chrome,还有 Apple 的 Safari。测试可以使用其他浏览器。你也可以使用你想支持的各种浏览器,这也许也是个不错的想法。

现在可以开始编写测试方法了,给你提个醒,我们想要加载首页,填充并发送表单,然后判断登录的页面是否包含刚刚添加的新书。代码清单 4-7 演示了如何用 Selenium 实现这个功能。

代码清单 4-7 用 Selenium 测试阅读列表应用程序

@Test
public void addBookToEmptyList() {
  String baseUrl = "http://localhost:" + port;

  browser.get(baseUrl);        ←---获取主页

  assertEquals("You have no books in your book list",
               browser.findElementByTagName("div").getText());   ←---判断图书列表是否为空

  browser.findElementByName("title")
         .sendKeys("BOOK TITLE");
  browser.findElementByName("author")
         .sendKeys("BOOK AUTHOR");
  browser.findElementByName("isbn")
         .sendKeys("1234567890");
  browser.findElementByName("description")
         .sendKeys("DESCRIPTION");
  browser.findElementByTagName("form")
         .submit();       ←---填充并发送表单

  WebElement dl =
      browser.findElementByCssSelector("dt.bookHeadline");
  assertEquals("BOOK TITLE by BOOK AUTHOR (ISBN: 1234567890)",
               dl.getText());
  WebElement dt =
      browser.findElementByCssSelector("dd.bookDescription");
  assertEquals("DESCRIPTION", dt.getText());     ←---判断列表中是否包含新书
}

该测试方法所做的第一件事是使用 FirefoxDriver 来发起 GET 请求,获取阅读列表的主页,随后查找页面里的一个 <div> 元素,从它的文本里判断列表里没有图书。

接下来的几行查找表单里的元素,使用驱动的 sendKeys() 方法模拟敲击键盘事件(实际上就是用给定的值填充那些表单域)。最后,找到 <form> 元素并提交。

提交的表单经处理后,浏览器就会跳到一个页面,上面的列表包含了新添加的图书。因此最后几行查找列表里的 <dt><dd> 元素,判断其中是否包含测试表单里提交的数据。

运行测试时,你会看到浏览器打开,加载阅读列表应用程序。如果够仔细,你还会看到填充表单的过程,就好像幽灵在操作,当然,并没有幽灵使用你的应用程序 - 这只是一个测试。

这个测试里最值得注意的是, @WebIntegrationTest 可以为我们启动应用程序和服务器,这样 Selenium 才可以用 Web 浏览器执行测试。但真正有趣的是你可以使用 IDE 的测试功能来运行测试,运行几次都行,无需依赖构建过程中的某些插件启动服务器。

要是你觉得使用 Selenium 进行测试很实用,可以阅读 Yujun Liang 和 Alex Collins 的Selenium WebDriver in Practicehttp://manning.com/liang/ ),该书更深入地讨论了 Selenium 测试的细节。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。