【问题标题】:Custom annotation implementation for WebElements name in test report测试报告中 WebElements 名称的自定义注释实现
【发布时间】:2017-01-15 05:24:14
【问题描述】:

我使用 Selenium 创建了测试框架并设置了 ExtentReports 以获取测试报告。使用页面对象模型和@FindBy 注释字段为每个页面创建自己的 WebElement 存储。现在我想创建自定义注释@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?

但无法获取我的点击方法中使用的特定元素的描述。

有什么想法可以实现吗?

【问题讨论】:

    标签: java selenium reflection annotations


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多