如何对 TestNG 断言错误和运行时异常使用单个捕获块



我会尽量提供尽可能多的信息。 我正在使用带有Java的TestNG框架+Selenium 以下是我编写的 2 个自定义方法。

// Checks if a WebElement is present on the screen
public boolean isElementPresent(WebElement element) {
try {
element.isDisplayed();
return true;
} catch (RuntimeException e) {
return false;`
}
}

// Used to click on the desired element
public void clickWebElement(WebElement element) {
isElementPresent(element);
element.click();
}

protected void enterDataintoField(WebElement element,String fieldData) {
isElementPresent(element);
element.click();
element.clear();
element.sendKeys(fieldData);    
}

现在假设有一个链接说登录。单击登录将打开一个页面,其中包含 2 个字段用户名和密码。以下代码用于登录。(登录名,用户名,密码和注销Btn是网络元素)

public void login(String username, String password)
{
try{
clickWebElement(Login);
//pause few seconds for page load
enterDataintoField(username, "Adam");
enterDataintoField(password, "mypassword");
//pause few seconds to login
Assert.assertTrue(isElementPresent(logoutBtn));
}catch({**ErrorType**} e){
//Some code here
}
}

现在我的问题来了。如果我在上面的 catch 块中将ErrorType设置为RuntimeException,那么万一出现任何问题,例如用户名字段未显示或登录按钮丢失,那么此 catch 块将能够捕获该问题。但是这个 catch 块将无法捕获上面的 Assert 语句,该语句验证登录是否成功。

同样,如果我使用上面的断言错误,那么 catch 块将能够捕获断言失败但无法捕获任何其他问题的情况。 因此,我需要一些关于我能在这里做什么的建议。 我有数千行代码,所以我不想在任何地方都使用 RuntimeException 和 AssertionErrorcatch 块(如 2 个 catch 块。我想要一个捕获块)

任何其他建议或最佳做法将不胜感激。

你的 catch 块只捕获扩展java.lang.ExceptionAssertionError可抛出对象是一个错误(因为它扩展了 java.lang.Error),但是,如果你真的想在 catch 块中捕获AssertionError- 你需要使用以下 catch 块语法:

catch (AssertionError e) { ... }

所以这意味着你不能在同一个 catch 块中同时处理异常和错误;但你可以做的是尝试使用两个单独的 catch 块,一个处理异常,另一个处理错误,如下所示:

try{
}catch(Exception e){
...
}
catch(AssertionError e){
...   
}

以下是您问题的答案:

您需要在此处解决很多问题,如下所示:

  1. 您已经定义了返回booleanisElementPresent(WebElement element),但是当您调用isElementPresent(element);时,您根本没有使用返回boolean状态。所以我的做法是检查for循环中的boolean状态,然后继续element.click();
  2. Assert.assertTrue的实现在这里不正确,就像在Assert.assertTrue(isElementPresent(logoutBtn));中一样。 来自TestNGAssertions旨在验证@Test结果。这些结果是提供给您和您的组织的信息,您可能希望对其进行跟踪。永远不要在块中写入Assertionstry只是为了捕获Catch块中的失败断言并强制将它们转换为状态Pass
  3. 要了解try/catchAssertions之间的关系,您可以考虑查看此讨论。
  4. 在您的代码中,您尝试将Logout按钮的存在AssertAssert.assertTrue(isElementPresent(logoutBtn));。这不应该是一个断言。相反,您可以诱导Logout按钮可单击的ImplicitlyWaitExplicitWait
  5. 现在,您要寻找的答案是Where and How do you implement Assertions?肯定会从try块中写出Assertions。断言可以应用于Page TitlePage Source或页面上存在的任何Element。根据最佳实践,有两种方法可以实现断言。首先,断言可以是Test类的一部分。第二个,根据POM中的PageFactory,断言应该在单独的包/类中处理。您需要调用包含断言的类的方法。
  6. 在代码中,如果要添加任何断言,可以在打开预期的 URL 时先添加它,接下来可以在登录到验证Page Title的 Web 应用程序后再添加一个断言。

让我知道这是否回答了您的问题。

所有这些断言/验证和等待相关的实现都应该由底层自动化框架提供。您可以使用可用的高效自动化框架之一,例如 QAF。您的实现可能如下所示:

// Checks if a WebElement is present on the screen
element.isPresent()
// verify  WebElement is present on the screen
element.verifyPresent()
// assert  WebElement is present on the screen
element.assertPresent()
//actions and other element methods no need to wait
element.click();

它还具有您可以使用的预定义步骤库。在这种情况下,您的登录名可能如下所示:

public void login(String username, String pwd){
//loc provided in locator file
sendKeys(username, "username.txt.loc");
sendKeys(text, "password.txt.loc");
click("login.btn.loc");
}

如果你想使用BDD

When send keys 'my text' to 'username.loc' 
And send keys 'my text' to 'password.loc' 
And click on 'login.loc'
They verify 'welcome.msg.loc' is present

您可以参考 qaf 分步教程

弄清楚我需要做什么。 我写了一个自定义断言方法:

public void myAssertTrue(Boolean condition){
try {
Assert.assertTrue(condition);
} catch (AssertionError e) {
e.printStackTrace();
throw new RuntimeException();
}
}

修改了 isElementPresent 方法:

// Checks if a WebElement is present on the screen
public void isElementPresent(WebElement element) {
try {
element.isDisplayed();
} catch (RuntimeException e) {
throw e;
}
}

通过这两个更改,我可以使用运行时异常捕获块来捕获运行时和资产错误

最新更新