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. Но, несмотря на это, я рекомендую обратить внимание на эту библиотеку и попробовать применить ее у себя на проекте.