测试报告中WebElements名称的自定义注释实现

时间:2017-01-14 19:16:35

标签: java selenium reflection annotations

我使用Selenium创建了测试框架,并为测试报告设置了ExtentReports。用于字段的已使用页面对象模型和@FindBy批注为每个页面创建自己的WebElements存储。现在我想创建自定义注释@Name

@Name(description = "google main page")
@FindBy(linkText = "Gmail")
private WebElement gmail;

并为其实现,以便能够在我的报告中稍后使用每个WebElement的描述。我有自己的click()方法实现

public static void click(WebElement element) {
    try{
        element.click();
        TestReport.addLog(LogStatus.INFO, "Element "+NameImpl.getDescription(element)+" clicked");
    } catch (NoSuchElementException e) {
        TestReport.addLog(LogStatus.ERROR, "Element "+NameImpl.getDescription(element)+" not found");
    }
}

我能够通过像这里的反射那样获得在课堂上注释的所有元素的描述

Is it possible to read the value of a annotation in java?

但无法获取我的click方法中使用的特定元素的说明。

任何想法如何实现?

1 个答案:

答案 0 :(得分:0)

仅从传递给click方法的参数中,没有获取注释的方法。这个原因是注释在gmail字段上,而不在WebElement类上。因此,获取@Name注释的唯一方法是首先获取代表Field字段的gmail,并且必须通过声明类来完成:

ClassWithGmailField.class.getField("gmail").getAnnotation(Name.class).description()

仅从click方法的参数中,您只能到达WebElement类本身定义的注释,例如:

@SomeAnnotation
public class WebElement {...}

但这对你的案件中的任何事情都没有用。

要实现类似于您想要的东西,您可能会:

  • 反思地分析该类,提取所有@Name'd字段并将字段值与字段值一起收集,也许可以用于某种包装器,例如: NamedElement来自@NameWebElement本身
  • 的说明
  • 反复调用click方法,为其提供所需的元数据(在您的案例中为描述)。但为此你需要以某种方式知道为每个字段调用哪个方法(例如通过另一个注释),使你的逻辑编码在你的实际代码之外。在某些情况下可能有意义,但一般来说可能是一个坏主意。

第一个想法的快速(未编译,未经测试的)代码示例:

public class NamedElement extends WebElement {

  public String description;
  public WebElement element;

  public NamedElement(String description, WebElement element) {
     this.description = description;
     this.element = element;
  }
}

public class NamedElementExtractor {

   public static Collection<NamedElement> getNamedElements(Object instanceWithWebElements) {
   //instanceWithElements in your case would be an instance of the class that has the "gmail" field, i.e. the one I referred to as ClassWithGmailField above
     Collection<NamedElement> namedElements = new List<NamedElement>();
     for (Field field : instanceWithWebElements.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        //maybe first check field.isAnnotationPresent(Name.class)
        String desc = field.getAnnotation(Name.class).description();
        WebElement element = field.getValue(instanceWithWebElements);
        namedElements.add(new NamedElement(desc, element));
     }
   }
}

...

for (NamedElement namedElement : NamedElementExtractor.getNamedElements(instanceWithWebElements))) {
   Click.click(namedElement);
}

...

public static void click(NamedElement namedElement) {
  try{
     namedElement.element.click();
     TestReport.addLog(LogStatus.INFO, "Element "+ namedElement.description +" clicked");
  } catch (NoSuchElementException e) {
     TestReport.addLog(LogStatus.ERROR, "Element "+ namedElement.description +" not found");
  }
}

不知道这是否适合您的情况,但这是值得深思的。