网页自动化正日益广泛,我们大多数人都有所涉猎。它几乎是我们日常工作的一部分,自动化处理多种场景,穿梭于众多网页之间。
但你可曾好奇,当网页在Selenium WebDriver中加载时,幕后究竟发生了什么?我们熟知一些用于导航至网页的WebDriver方法,如get()和navigate(),但这些是否决定了页面的加载方式,抑或后台还有其他机制在运作?
答案是肯定的!这由Selenium WebDriver中的页面加载策略所决定。WebDriver通过页面加载策略来确定网页加载的时机,以便进行后续交互;执行下一步操作。
在本篇关于Selenium页面加载策略的博文中,我们将深入探讨这一策略,尝试理解其不同类型以及如何在自动化代码中实现它们。
让我们开始吧!
什么是页面加载策略?
页面加载策略定义了在自动化代码启动浏览器并使用get()或navigate().to()方法时,何时认为页面已加载完毕。默认情况下,Selenium WebDriver采用标准页面加载策略,即NORMAL。这意味着要等待整个网页及其组件(如CSS、图像、框架等)全部加载完成。
若因上述组件(或限速网络条件)导致页面加载时间延长,且对脚本不重要,可将其更改为EAGER或NONE以加速执行。此设置适用于整个会话,故需明智选择以避免测试不稳定。
页面加载策略的使用作为Selenium 4特性之一被引入。与以往版本不同,它不再依赖默认页面加载超时。
页面加载策略如何运作?
为判断页面是否加载完成,Selenium利用document.readyState属性。该属性描述了文档的加载状态,这里的文档指浏览器中加载的任何网页。
文档的Ready State方法得到所有浏览器的支持,使其成为与Selenium的PageLoadStrategy配合使用的可靠选项。
正如存在默认的PageLoadStrategy,Selenium WebDriver等待的默认document.readyState为Complete。
浏览器文档对象的readyState属性表示页面加载过程的当前状态,其值可能为:
- loading – 页面仍在加载中。
- interactive – 页面已加载完毕,但子资源如图片、样式表及框架可能仍在加载。
- complete – 页面及其所有子资源均已完成加载。
您可以使用readyState属性来确定页面何时完全加载并准备好通过JavaScript或其他方式进行操作。例如,在Selenium中,您可以使用readyState属性来确定页面何时加载完毕,页面上的元素可以通过Selenium命令进行交互。
在继续之前,让我们通过一个简短的练习来更深入地了解文档的readyState。
- 访问该网站。
- 一旦网站加载完成,右键点击->选择检查->打开控制台并执行命令document.readyState。
3. 执行此命令后,您将看到输出为“complete”,这表示文档的当前状态。这意味着整个页面已加载必要的资源(如图片、CSS等)。
4. 接下来,刷新页面并再次执行上述命令。您将能够看到文档此刻的加载状态,如下所示。
如果在4-5次刷新后仍看不到加载状态,尝试通过将网络设置为较慢的选项来限制互联网条件。您可以通过这篇关于在不同网络条件下测试网站的博客了解更多信息。我们也将采用同样的方法进行演示。
这展示了document.readyState在实际中的工作原理。你还可以使用LT浏览器,一个移动友好测试工具,来检查网站在不同网络条件下的性能。LT浏览器是LambdaTest提供的辅助工具,允许你测试网站在超过50种不同设备上的响应性,包括智能手机、平板电脑和笔记本电脑。它还提供了创建自定义分辨率、模拟不同网络条件以及使用Google Lighthouse生成性能报告的功能。
接下来,让我们深入了解这些值以及它们如何与PageLoadStrategy值相对应。
PageLoadStrategy与document.readyState映射
文档的readyState可以是以下之一:
- 加载中:文档加载正在进行。
- 交互中:文档已加载并解析,但子资源如脚本、图像、CSS和框架仍在加载。此时,DOMContentLoaded事件被触发。
- 完成:文档及其所有子资源已加载完毕。这标志着加载事件的触发。
每种PageLoadStrategy都根据特定的document.readyState值进行映射,WebDriver将完成导航方法并继续执行下一步。
PageLoadStrategy | document.readyState | Description |
Normal | complete | Used by default by browser and Selenium WebDriver. Waits for all the resources to be downloaded. |
Eager | interactive | Resources like images and CSS might still be loading, but DOM is accessible and ready to interact. |
None | any | WebDriver is not blocked at all. Execution continues without any wait as soon as the initial page is loaded. |
Selenium中的页面加载策略类型
在Web自动化中,通常有三种类型的Selenium页面加载策略可以使用。
NORMAL(默认,未指定时)
这种Selenium页面加载策略使得WebDriver等待直到页面加载完成,即加载事件被触发。
加载事件在页面及其依赖资源(如CSS、JavaScript、iFrames和图像)全部加载完成后触发。
它等待HTML内容及其所有子资源下载和解析完毕。
EAGER
采用这种Selenium页面加载策略时,WebDriver仅等待初始页面加载及DOMContentLoaded事件触发。
与加载事件不同,DOMContentLoaded事件在DOM加载完成后立即触发,无需等待CSS、JavaScript、iFrames和图像等附加资源加载。
它仅等待HTML内容下载和解析。
NONE
在此Selenium页面加载策略中,WebDriver不会被阻塞,而是继续执行测试。
它仅等待HTML内容下载。
演示:使用不同的Selenium页面加载策略设置WebDriver
既然我们已经对不同的Selenium页面加载策略有了基本了解,接下来通过代码示例来理解其实现方式。
为此,我们将编写一个针对以下场景的自动化测试脚本。
- 通过云端Selenium Grid创建RemoteWebDriver实例。为此,我们将使用LambdaTest平台。
- 设置WebDriver能力以指定PageLoadStrategy。
- 接下来,使用驱动程序启动浏览器并导航至此处。
- 为此,我们将记录页面加载完成所需的时间,以观察在相同条件下,不同的Selenium页面加载策略之间的差异。页面加载时间的差异有助于更清晰地理解所有策略。
项目设置
对于这篇关于Selenium页面加载策略的博客,我们将使用基于Java的Eclipse IDE的Maven项目。如果你不偏好Eclipse,可选择任何你喜欢的IDE,并执行相同的步骤。该项目将利用Selenium WebDriver和TestNG依赖项来自动化与页面元素的交互及测试案例执行。强烈建议使用最新稳定版本以获得更好的效果。
现在让我们开始吧。
- 启动Eclipse或你选择的IDE。
- 创建一个新的Maven项目,并命名为PageLoadStrategy。
- 在src文件夹内,添加一个测试包,并在其中创建一个名为TestPageLoadStrategy的测试类。该类将包含本次演示的全部代码。
4. 在编写实际测试案例之前,更新pom.xml文件以包含使用TestNG进行Selenium测试的最新依赖项,如下所示。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>PageLoadStrategy</groupId>
<artifactId>PageLoadStrategy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
5. 更新pom.xml后,将以下代码添加到测试案例文件TestPageLoadStrategy.java中。该文件将包含三个测试,展示Selenium三种页面加载策略的使用。
package test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.*;
import java.util.HashMap;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Test;
public class TestPageLoadStrategy {
public RemoteWebDriver driver = null;
String username = "";
String accessKey = "";
ChromeOptions chromeOptions = new ChromeOptions();
HashMap ltOptions = new HashMap();
private void setup(String buildName) {
chromeOptions.setPlatformName("Windows 10");
chromeOptions.setBrowserVersion("108.0");
ltOptions.put("project", "Page Load Strategy");
ltOptions.put("selenium_version", "4.0.0");
ltOptions.put("w3c", true);
ltOptions.put("networkThrottling", "Regular 2G");
ltOptions.put("build", buildName);
}
private void checkPageLoad() {
try {
driver = new RemoteWebDriver(
new URL("https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub"), chromeOptions);
Instant startTime = Instant.now();
System.out.println("Page load started at : " + startTime.toString());
System.out.println("Navigating to the URL");
driver.get("https://ecommerce-playground.lambdatest.io/");
Instant endTime = Instant.now();
System.out.println("Page load ended at : " + endTime.toString());
Duration duration = Duration.between(startTime, endTime);
System.out.println("Total PageLoad time : " + duration.toMillis() + " milli seconds");
} catch (MalformedURLException e) {
System.out.println("Invalid grid URL");
} finally {
driver.quit();
}
}
@Test
public void testNormalStrategy() {
// 设置PageLoadStrategy = 正常
setup("Page Load Strategy - Normal");
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
chromeOptions.setCapability("LT:Options", ltOptions);
checkPageLoad();
}
@Test
public void testEagerStrategy() {
// 设置PageLoadStrategy = 急切
setup("Page Load Strategy - Eager");
chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
chromeOptions.setCapability("LT:Options", ltOptions);
checkPageLoad();
}
@Test
public void testNoneStrategy() {
// 设置PageLoadStrategy = 无
setup("Page Load Strategy - None");
chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
chromeOptions.setCapability("LT:Options", ltOptions);
checkPageLoad();
}
}
代码解析:TestPageLoadStrategy.java
此Java文件是演示使用不同函数实现所有策略的主要测试类。
让我们详细了解每一步。
步骤1. 首先,需要创建一个RemoteWebDriver实例。这是为了支持在云Selenium Grid上执行。
使用云Selenium Grid能提高Java自动化测试的扩展性和速度,并允许用户在多个操作系统和浏览器组合上进行广泛的并行和跨浏览器测试。
步骤2. 如前一步所述,由于我们使用LambdaTest平台,需要提供用户名和访问密钥以连接到云中心。这些信息可在创建账户后,在LambdaTest个人资料部分找到。
步骤3. 创建一个ChromeOptions类的对象。此类用于操作Chrome驱动程序的各种属性,我们将使用它来执行操作。此chromeOptions对象将在每个测试用例中用于设置PageLoadStrategy,然后传递给WebDriver。
步骤4. 创建一个名为ltOptions的HashMap变量。这将设置LambdaTest云网格执行的各种属性。
步骤5. 接下来是setup()方法,用于在chromeOptions和ltOptions中设置一些基本属性。这些是所有三种PageLoadStrategy情况下的共同属性。
此外,请注意我们正在使用LambdaTest的networkThrottling属性将网络设置为常规2G,下载速度为250 Kbps,上传速度为50 Kbps。这将有助于在所有场景中更好地展示加载时间,如前一节所述。
使用LambdaTest平台提供了这种优势,您可以直接选择浏览器和版本详细信息,并且您的功能将自动使用LambdaTest功能生成器生成。您只需将它们添加到代码中。
此方法接受一个参数buildName。此参数用于显示构建名称。
步骤6. 添加一个新函数checkPageLoad()。在try块中,我们编写代码以使用在chromeOptions中定义的属性连接到LambdaTest平台上的RemoteWebDriver。
连接建立后,创建Java.time包中Instant类的一个对象,用于存储并记录即将启动浏览器并开始导航时的起始时间。随后,调用驱动程序启动浏览器并加载测试网站。
一旦网站根据设定的PageLoadStrategy被视为已加载,驱动程序将控制权传递给下一个命令,这又是一个Instant类对象,用于再次获取当前时间,即结束时间。
至此,页面已按照我们请求的策略加载完毕,并且我们已获取到起始和结束时间。通过计算两个时间点之间的差值,可以确定网页加载所需的时间(以毫秒为单位)。为此,我们使用了同一包中的Duration类来实现这一功能。
您会注意到,在所有测试案例中,针对不同策略的加载时间均有所不同。
A catch block is added next for the try block to handle the exception if it occurs. MalformedURLException is to catch the exception in case our RemoteWebDriver URL has invalid syntax. Once everything is done, we finally close the driver instance. To learn more about it, you can go through this blog on the most common exceptions in Selenium.
testNormalStrategy()
此测试案例旨在展示正常策略。
首先,setup()方法定义了浏览器和LambdaTest平台的基本属性。接着,在chromeOptions中将PageLoadStrategy设置为NORMAL,并随后设置其他能力。
最后,调用checkPageLoad()方法加载网页并记录加载时间,我们将在执行部分对每种策略的加载时间进行比较。
testEagerStrategy()
此测试案例旨在展示急切策略。
在此情况下,所有步骤与前一案例相似,唯一区别在于chromeOptions中将PageLoadStrategy设置为EAGER,随后调用checkPageLoad()方法。
testNoneStrategy()
本测试案例旨在展示None策略的运用。
此处chromeOptions中PageLoadStrategy的值设为NONE,其余步骤与之前讨论的测试案例相同。
测试执行
理解了所有PageLoadStrategy的工作原理与实现后,我们现在执行代码,观察本地及LambdaTest仪表板上的执行结果。
测试案例将通过TestNG执行。执行步骤如下:
- 在Eclipse IDE中右键点击测试案例名称。
- 选择Run Test,然后点击TestNG Test开始执行。
我们逐一执行各案例,观察不同策略下的加载时间是否有所差异。
NORMAL策略
在此情况下,TotalPageLoad时间为70852毫秒,因为我们使用的是常规2G网络速度。已知此值应为三个案例中最高。截至目前,它应是三者中的最高值。我们可以通过运行Eager和None案例并进行比较来验证这一点。
EAGER策略
如预期,在相同场景下,Eager策略的PageLoadTime即70231毫秒,相较于Normal策略有所减少。
NONE策略
请注意,None策略的PageLoadTime明显低于其他两种策略,因为它不需要等待任何资源下载。
以下是不同策略页面加载时间的快速总结
PageLoadStrategy | PageLoadTime (in milliseconds) |
Normal | 70852 |
Eager | 70231 |
None | 28908 |
您还可以通过导航到LambdaTest仪表板查看每种PageLoadStrategy的执行结果,如下所示:
要查看自动化构建的详细信息,请导航至自动化下的构建部分。
PageLoadStrategy.NORMAL的构建详情:
PageLoadStrategy.EAGER的构建详情:
PageLoadStrategy.NONE的构建详情:
结论
至此,我们完成了关于Selenium WebDriver中不同页面加载策略的Selenium TestNG教程。在本教程中,我们学习了这些Selenium页面加载策略的进一步使用和运作方式,以及如何在自动化脚本中集成它们并在Selenium云网格上执行。
I hope now you can implement these in your use cases more efficiently.
祝加载愉快!
Source:
https://dzone.com/articles/a-complete-guide-to-selenium-page-load-strategy