Lombok как способ трансформировать test automation project

Решил написать заметку о применении Lombok для построения автоматизации тестирования.

Lombok - это библиотека, с помощью которой вы можете сократить количество шаблонного кода, который нужно писать на Java.

Чем Lombok может помочь автоматизатору?

Применить ломбок можно разными способами - от уменьшения кода для простых Pojo, до использования Extension Methods.

Каноническая Java не поддерживает extension methods, хотя в языках Groovy, Kotlin и C# они есть. Можно долго дискутировать на предмет того, нужны они или нет, но после того, как я попробовал их применять в Groovy, в Джаве мне их не хватало.

Что такое extension method?

Это возможность добавлять методы в уже существующие классы.

Скажем, у нас есть класс WebElement, у которого есть свой API. Вот там нету метода

shouldHave(String text), а нам бы очень хотелось иметь такую штуку.

С помощью Lombok мы можем такой метод легко добавить:

public class WebElementExt{

    public static void shouldHave(WebElement el, String text){
          assertEquals(el.getText(),text)
    }

}

Затем используем в наших тестах:

@ExtensionMethod(WebElementExt.class)
class Test{

   @Test
   void testWithExt(){
        Webdriver driver = new ChromeDriver();
        driver.findElement(By.css(".header")).shouldHave("MainPage")
   }

}

Легко и просто. Это лучше, чем писать декоратор, который будет отличаться по типу класса.

Если брать более сложный пример, то мы можем написать экстеншн и для самого драйвера:

public class DriverExtension {

     public static void goTo(WebDriver driver, String url) {
       driver.get(url);
     }

     public static <T extends BasePage> T open(WebDriver driver, Class<? extends BasePage> tClass) {
       try {
         BasePage page = tClass.getDeclaredConstructor(WebDriver.class).newInstance(driver);
         driver.get(page.getUrl());
         return (T) page;
       } catch (InstantiationException e) {
         e.printStackTrace();
       } catch (IllegalAccessException e) {
         e.printStackTrace();
       } catch (NoSuchMethodException e) {
         e.printStackTrace();
       } catch (InvocationTargetException e) {
         e.printStackTrace();
       }
       return null;
     }

     public static UIElement $(WebDriver driver, String locator) {
       return new UIElement(new Locator(By.cssSelector(locator), driver));
     }

     public static UIElement $(WebDriver driver, By locator) {
       return new UIElement(new Locator(locator, driver));
     }
   }

Класс PageObject:

abstract class BasePage{

  protected WebDriver browser;

  public BasePage(WebDriver driver){
    this.browser = driver;
  }

  public abstract String getUrl();
}

@ExtensionMethod(DriverExtension.class)
public class MainPage extends BasePage{

  @Getter
  private String url = "http://automation-remarks.com/workshop";

  @Getter
  private UIElement mainLink;

  public MainPage(WebDriver driver) {
    super(driver);
    this.mainLink = driver.$("#nav > div.nav-panel > a.main_link > span");
  }
}

Класс UIElement:

public class UIElement {

  private Locator locator;

  public UIElement(Locator locator) {
    this.locator = locator;
  }

  public WebElement element() {
    return locator.find();
  }

  public void should(String text) {
    boolean res = element().getText().equals(text);
    assert res;
  }

  public void click() {
    element().click();
  }
}

И наконец мы можем использовать все это в наших тестах:

class Advanced{

  @Test
  void test(){
       val browser = Browser.chrome();
       MainPage mp = browser.open(MainPage.class);
       mp.getMainLink().click();
  }
}

Вы можете применять такой подход в своем существующем фреймворке практически безболезненно. Правда, есть одно НО - Lombok содержит определенный уровень магии, которую вы не будете понимать. Да и плагин для Intelij IDEA пока что не полностью поддерживает все фишки Lombok. Но, несмотря на это, я рекомендую обратить внимание на эту библиотеку и попробовать применить ее у себя на проекте.