如何对TestNG断言错误和RunTime异常使用单个catch块

时间:2017-05-19 14:00:29

标签: java selenium testng

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

// 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个字段的用户名和密码。以下代码用于登录。(登录,用户名,密码和logoutBtn是webElements)

  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语句,该语句验证登录是否成功。

同样,如果我使用上面的 AssertionError ,那么catch块将能够捕获断言失败但无法捕获任何其他问题的场景。 因此,我需要一些关于我能在这做什么的建议。 我有成千上万行代码,所以我不想同时使用RuntimeException和AssertionError catch块(如2个catch块。我想要一个catch块)

任何其他建议或最佳实践都会非常感激。

4 个答案:

答案 0 :(得分:0)

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

catch (AssertionError e) { ... }

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

    try{

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

答案 1 :(得分:0)

以下是您的问题的答案:

你需要在这里解决很多问题:

  1. 您已定义isElementPresent(WebElement element)以返回boolean但是当您致电isElementPresent(element);时,您根本没有使用返回boolean状态。因此,我需要检查boolean循环中的for状态,然后继续element.click();
  2. 此处的Assert.assertTrue实施不正确,如Assert.assertTrue(isElementPresent(logoutBtn));。 来自Assertions的{​​{1}}旨在验证TestNG结果。这些结果是您和您的组织可能希望跟踪的信息。永远不要在@Test块中写Assertions只是为了捕捉try块中的失败断言&强制将它们转换为状态Catch
  3. 了解Pass&的关系try/catch您可以考虑查看此discussion
  4. 在您的代码中,您尝试将Assertions按钮Assert Logout作为Assert.assertTrue(isElementPresent(logoutBtn));。这不应该是一个断言。相反,您可以诱导ImplicitlyWaitExplicitWait Logout按钮可点击。
  5. 现在,您要寻找的答案是Where and How do you implement Assertions? Assertions肯定会从try块中写出来。断言可以应用于页面上的Page TitlePage Source或任何Element。根据最佳实践,有两种方法可以实现断言。首先,断言可以成为Test类的一部分。第二个,根据POM中的PageFactory,断言应该在一个单独的包/类中处理。您需要调用包含断言的类的方法。
  6. 在您的代码中,如果要添加任何断言,可以在打开目标URL时最初添加它,然后在登录到验证Page Title的Web应用程序后再添加一个断言。
  7. 如果这回答你的问题,请告诉我。

答案 2 :(得分:0)

所有这些断言/验证和等待相关的实现应该由底层自动化框架提供。您可以使用可用的高效自动化框架之一,如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();

它还有您可以使用的预定义step library。在这种情况下,您的登录信息如下所示:

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-step-by-step-tutorial

答案 3 :(得分:0)

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

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;
    }
}

通过这两个更改,我可以使用RuntimeException catch块来捕获运行时和assetionErrors