如何在Selenium Webdriver中处理AJAX调用
什么是 Ajax?
AJAX 代表 Asynchronous JavaScript & XML(异步 JavaScript 和 XML),它允许网页从服务器检索少量数据,而无需重新加载整个页面。
Ajax 是一种用于创建快速动态网页的技术。这项技术是异步的,并结合使用了 Javascript 和 XML。它将在不重新加载整个页面的情况下更新网页的部分内容。一些使用 AJAX 技术的著名应用程序有 Gmail、Google 地图、Facebook、Youtube 等。
Ajax 如何工作?
例如,当您点击提交按钮时,JavaScript 将向服务器发出请求,解释结果并更新当前屏幕,而无需重新加载网页。
- Ajax 调用是由浏览器发起的一种异步请求,不会直接导致页面转换。这意味着,如果您发出 Ajax 请求,用户仍然可以在应用程序上工作,而请求正在等待响应。
- AJAX 将 HTTP 请求从客户端发送到服务器,然后处理服务器的响应,而无需重新加载整个页面。因此,当您进行 AJAX 调用时,您不能完全确定服务器发送响应所需的时间。
从测试人员的角度来看,如果您正在检查要显示的内容或元素,您需要等待直到收到响应。在 AJAX 调用期间,数据以 XML 格式存储并从服务器检索。
如何在 Selenium Webdriver 中处理 Ajax 调用
处理 Ajax 调用的最大挑战是了解网页的加载时间。 由于网页加载时间仅持续几分之一秒,因此测试人员很难通过自动化工具测试此类应用程序。为此,Selenium Webdriver 必须在此 Ajax 调用上使用等待方法。
因此,通过执行此等待命令,Selenium 将暂停当前测试用例的执行,并等待预期的或新值。当新值或字段出现时,Selenium Webdriver 将执行暂停的测试用例。
以下是 Selenium Webdriver 可以使用的等待方法
Thread.Sleep()
- Thread.Sleep() 不是一个明智的选择,因为它会将当前线程暂停指定的时间。
- 在 AJAX 中,您永远无法确定确切的等待时间。因此,如果元素未在等待时间内显示,您的测试将失败。此外,它会增加开销,因为调用 Thread.sleep(t) 会使当前线程从运行队列移动到等待队列。
- 当时间“t”到达后,当前线程将从等待队列移动到就绪队列,然后需要一些时间才能被 CPU 选中并运行。
隐式等待()
- 此方法告诉 webdriver 如果元素不能立即获得,则等待,但此等待将持续整个浏览器打开时间。因此,页面上任何元素的搜索都可能需要隐式等待设置的时间。
显式等待()
- 显式等待用于冻结测试执行,直到满足特定条件或达到最大时间。
WebdriverWait
- 它可以用于任何条件。这可以通过 WebDriverWait 结合 ExpectedCondition 实现。
- 动态等待元素的最佳方法是每秒检查条件,一旦条件满足,就继续执行脚本中的下一个命令。
但是所有这些等待的问题是,您必须指定超时单位。如果元素仍未在时间内出现怎么办?因此还有一种等待叫做 Fluent Wait。
Fluent Wait
- 这是 Wait 接口的一个实现,它有自己的超时和轮询间隔。每个 FluentWait 实例都确定等待条件的最长时间,以及检查条件的频率。
在 Selenium Webdriver 中处理 Ajax 调用的挑战
- 使用“暂停”命令处理 Ajax 调用并非完全可靠。长时间的暂停会使测试变得不可接受地慢,并增加测试时间。相反,“waitforcondition”在测试 Ajax 应用程序时会更有帮助。
- 评估与特定 Ajax 应用程序相关的风险很困难
- 给予开发人员完全的自由来修改 Ajax 应用程序使得测试过程充满挑战
- 创建自动化测试请求对于测试工具可能很困难,因为此类 AJAX 应用程序通常使用不同的编码或序列化技术来提交 POST 数据。
使用 Selenium Webdriver 处理 Ajax 的代码示例
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class Ajaxdemo {
private String URL = "https://demo.guru99.com/test/ajax.html";
WebDriver driver;
WebDriverWait wait;
@BeforeClass
public void setUp() {
System.setProperty("webdriver.chrome.driver",".\\chromedriver.exe");
//create chrome instance
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.navigate().to(URL);
}
@Test
public void test_AjaxExample() {
By container = By.cssSelector(".container");
wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.presenceOfElementLocated(container));
//Get the text before performing an ajax call
WebElement noTextElement = driver.findElement(By.className("radiobutton"));
String textBefore = noTextElement.getText().trim();
//Click on the radio button
driver.findElement(By.id("yes")).click();
//Click on Check Button
driver.findElement(By.id("buttoncheck")).click();
/*Get the text after ajax call*/
WebElement TextElement = driver.findElement(By.className("radiobutton"));
wait.until(ExpectedConditions.visibilityOf(TextElement));
String textAfter = TextElement.getText().trim();
/*Verify both texts before ajax call and after ajax call text.*/
Assert.assertNotEquals(textBefore, textAfter);
System.out.println("Ajax Call Performed");
String expectedText = "Radio button is checked and it's value is Yes";
/*Verify expected text with text updated after ajax call*/
Assert.assertEquals(textAfter, expectedText);
driver.close();
}
}
摘要
- AJAX 允许网页从服务器检索少量数据,而无需重新加载整个页面。
- 要测试 Ajax 应用程序,应采用不同的等待方法
- ThreadSleep
- 隐式等待
- 显式等待
- WebdriverWait
- Fluent Wait
- 创建自动化测试请求对于测试工具可能很困难,因为此类 AJAX 应用程序通常使用不同的编码或序列化技术来提交 POST 数据。

