如何在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 数据。