关于Selenium中的异常处理,你需要知道的一切

486 阅读9分钟

关于Selenium中的异常处理,你需要知道的一切

发布者:Ramit DhamijaRamit Dhamija inEnterprise Java October 20th, 2021 0 Views

在技术的世界里,异常据说和编程本身一样古老。在代码执行过程中出现的异常可能会导致意想不到的行为,除非在代码中对异常进行适当处理。异常并不是坏事,而是现代编程的一个基本组成部分。与其对异常产生恐惧,不如知道如何在什么时候处理什么异常。接下来,我们将讨论如何优雅地处理异常,并利用异常处理来编写更易于维护的干净代码。

什么是 "异常"?

异常是一个程序员常用的术语,与任何特定的编程语言无关。异常 "顾名思义是指程序突然结束而不显示预期输出的事件。

各种编程语言有多种处理异常的方法。异常处理是一个众所周知的处理异常的过程。异常处理是一个强制性的过程,因为异常是为了打破程序的正常执行流程。一旦已知的异常被处理,代码就会被防止出现类似的中断,并可以继续顺利地执行程序。

异常发生的背后有几个已知的条件。

  • Java虚拟内存(JVM)耗尽内存
  • 要求访问的文件在系统中不存在
  • 用户提供了无效的数据
  • 网络在通信过程中出现故障

Java中的异常类型。

  1. 检查的异常。这 些异常在编译过程中被编译器检查,以验证该异常是否被处理。如果异常没有被处理,那么系统会显示编译错误。由于这些异常是在编译过程中验证的,所以通常被称为编译时异常。下面是一些检查过的异常的例子。
  • SQLException : 这种异常可能发生在基于SQL语法的数据库查询执行时。
  • IOException : 这种异常可能发生在对文件进行无效的I/O流操作时。
  • ClassNotFoundException : 当JVM无法找到所需的Java类时就会发生这种异常。
  1. 未检查的异常。 这些异常发生在程序执行过程中。因此,通常被称为Runtime Exceptions。这类异常在编译过程中不被检查,通常在整个编译过程中被忽略。这些异常一般指的是逻辑错误。下面是一些属于未检查的异常的类别。
  • NullPointerException : 这个异常发生在访问一个有空值的对象时。
  • ArrayIndexOutofBound : 当访问一个数组时,索引值无效,就会发生这种异常。
  • IllegalArgumentException : 当参数被传递到一个方法中时,会发生这种异常。
  • NumberFormatException : 当一个字符串被传递到一个方法中而不能被转换成数字时,可能会发生这种异常。
  • ArithmeticException : 当一个不正确的算术操作被执行时,例如用一个数字除以0,就会发生这种异常。

异常处理标准

随着时间的推移,面向对象的编程(OOP)已经提升到了一个新的水平,其中异常处理支持已经成为现代面向对象编程语言的一个关键因素。如今,多种编程语言都对异常处理提供了强有力的支持。异常处理不仅能保持代码的干净,而且还能提高可维护性、可扩展性和可读性。

下面是一些常用于处理异常的Java标准。

Try-Catch: try-catch关键字的组合被用来捕获异常。try "块被放在开头,而 "catch "块被放在try块的结尾,这有助于捕捉异常,并在检测到异常时执行必要的操作。

在遇到异常时,可以创建一个异常类的对象,可以进一步使用以下预定义的方法来显示调试信息。

  • printStackTrace() 。这个函数用来打印堆栈跟踪、异常名称和其他重要的异常信息。
  • getMessage()。这个函数有助于获得对一个异常的深入描述。
try
{
// Code
} catch (Exception e) {
// Code for Handling exception
}

Try-Catch块可以用于其他高级方法来处理异常。

  • 多重捕获块: 由于有各种类型的异常,从一个代码块中期待一个以上的异常并不是什么大问题。在try块之后的多个catch块可以帮助通过不同的catch块处理不同的异常。对于在一个尝试块之后使用的catch块的数量没有限制。
try
{
//Code
} catch (ExceptionType1 e1) {
//Code for Handling Exception 1
} catch (ExceptionType2 e2) {
//Code for Handling Exception 2
}
  • 抛出/抛出。 如果程序员想明确地抛出一个异常,可以使用'throw'关键字和一个异常对象在运行时进行处理。如果程序员想 "抛出 "一个异常,那么就必须处理相同的异常,可以在方法签名中使用 "throws "关键字来处理,这样调用者方法就可以理解该方法可能抛出的异常。
public static void exceptionProgram() throws Exception{

try {
// write your code here
} Catch (Exception b) {

// Throw an Exception explicitly
throw(b);
}
}
  • 多个异常:在 方法签名的throws子句中可以提到各种异常。
public static void exceptionProgram() throws ExceptionType1, ExceptionType2{

try {
// write your code here
} catch (ExceptionType1 e1) {
// Code to handle exception 1
} catch (ExceptionType1 e2) {
// Code to handle exception 2
}
  • 最后: "final "块可能是在try-catch块之后创建的,并且无论异常是否被抛出都会执行。
try {
//Code
} catch (ExceptionType1 e1) {
//Catch block
} catch (ExceptionType2 e2) {
//Catch block
} 
 finally {
//The finally block always executes.
}

Selenium中的常见异常

虽然在Selenium中,WebDriverException下定义了多种异常,但我们将简要介绍一些常见的异常,以及Selenium中异常处理的简短解决方案。

1.NoSuchElementException

当WebDriver无法找到所需的元素时,Selenium会出现这种异常。NoSuchElementException是NotFoundException类的一个子类。这种异常发生的常见原因是使用了无效的定位器。

从另一个角度考虑,这种异常也可能由于延迟而发生,假设所需的定位器在下一个页面,而webdriver仍然停留在前一个页面或加载下一个页面。因此,用适当的等待来处理测试可以将这种异常的发生率降到最低。

此外,可以在捕获块中捕获异常,并在捕获块中执行所需的操作,以继续执行自动化测试。例子。

try {
driver.findElement(By.id("form-save")).click();
} catch (NoSuchElementException e)
{
System.out.println(“WebDriver couldn’t locate the element”);
}

2.NoSuchWindowException

这个异常也是NotFoundException类的一个子类。如果一个驱动程序试图切换到无效的浏览器窗口,WebDriver会抛出NoSuchWindowException。

建议切换窗口的最好方法是先获得活动的窗口会话,然后在窗口上执行所需的操作。例子。

for (String windowHandle : driver.getWindowHandles()) {
try {
driver.switchTo().window(handle);
} catch (NoSuchWindowException e) {
System.out.println(“Exception while switching browser window”);
}
}

3.NoAlertPresentException

当WebDriver试图切换到一个不存在或无效的警报时,selenium会出现这种异常。

建议使用显式或流畅的等待来处理浏览器警报。如果警报仍然不存在,可以用catch块来捕获这个异常。例子。

try {
driver.switchTo().alert().accept();
} catch (NoSuchAlertException e)
{
System.out.println(“WebDriver couldn’t locate the Alert”);
}

4.ElementNotVisibleException

当WebDriver试图对一个不可见的元素或不可交互的元素进行操作时,Selenium会出现这种异常。ElementNotVisibleException被定义为ElementNotInteractableException类的一个子类。

为了避免这种异常的发生,推荐的方法是在确切需要的地方应用带有适当超时的selenium waits。例子。

try {
driver.findElement(By.id("form-save")).click();
} catch (ElementNotVisibleException e)
{
System.out.println(“WebDriver couldn’t locate the element”);
}

5.ElementNotSelectableException

在Selenium中,这个异常说明元素存在于网页上,但不能被WebDriver选择。ElementNotSelectableException是InvalidElementStateException类的一个子类。

通过catch块,可以完成selenium的异常处理,并且可以用相同或不同的技术重试选择相同的元素。例子。

try {
Select dropdown = new Select(driver.findElement(By.id(“swift”)));
} catch (ElementNotSelectableException e)
{
System.out.println("Element could not be selected")
}

6.NoSuchSessionException

这种异常在Selenium中通常发生在通过driver.quit()命令退出自动浏览器会话后调用测试方法。在浏览器崩溃或网络中断的情况下,也会出现这种异常。

NoSuchSessionException可以通过在测试套件结束时退出浏览器并确保用于测试自动化的浏览器版本稳定来避免。

private WebDriver driver;
@BeforeSuite
public void setUp() {
driver = new ChromeDriver();
}
@AfterSuite
public void tearDown() {
driver.quit();
}

7.StaleElementReferenceException

StaleElementReferenceException是在所需元素不再存在于DOM中时抛出的。这可能发生在DOM没有正确加载或者WebDriver卡在一个错误的页面上。

这个异常可以用catch块来捕获,并且可以通过动态XPath或页面刷新来尝试重试。例子。

try {
driver.findElement(By.xpath(“//*[contains(@id,firstname’)]”)).sendKeys(“Aaron”);
} catch (StaleElementReferenceException e)
{
System.out.println("Could not interact with a desired element")
}

8.TimeoutException

在Selenium中,当WebDriver超过了执行下一步的等待时间限制时,就会出现这种异常。Selenium的等待通常用于避免像ElementNotVisibleException这样的selenium异常。即使使用了适当的等待,如果元素不能被交互,那么就会抛出TimeoutException。

为了避免这种异常,必须进行手动测试,以验证元素的缓慢程度,并进一步对等待进行相应的处理。

9.InvalidSelectorException

在Selenium中,当使用无效或不正确的选择器时,会抛出这种异常。这种情况可能发生在创建XPATH时。

为了避免这种情况,在将代码推送到主分支之前,必须对测试脚本进行审查,并对脚本的端到端流程进行测试。此外,像SelectorHub和ChroPath这样的工具也可以用来验证定位器。

10.NoSuchFrameException

当WebDriver试图切换到一个无效的或不存在于当前网页上的框架时,selenium中的这个异常会发生。NoSuchFrameException是NotFoundException类的一个子类。

为了避免这种异常,首先需要确保框架的名称或ID是正确的,其次要确保框架的加载不耗费时间。如果框架在网页上加载需要时间,就需要纠正等待处理。例子。

try {
driver.switchTo().frame("frame_1");
} catch (NoSuchFrameException e)
{
System.out.println("Could not find the desired frame")

}

结论

处理异常是任何自动化脚本或逻辑结构的一个重要方面,以适应各种情况。在这篇博客中,我们分享了一些我们在Selenium中常用的异常处理命令,在你的自动化脚本中使用它们之前,一定要理解每个异常的功能。我们还附上了一份有用的白皮书,阐明了使用Docker的Selenium网格基础设施的情况。

由我们JCG项目的合伙人Ramit Dhamija授权发表在Java Code Geeks上。点击这里查看原文。关于Selenium的异常处理,你需要知道的一切

Java Code Geeks撰稿人所表达的观点属于他们自己。

Selenium 2021-10-20

姚明