Используем супер силу Kotlin в тестах

Продолжаем наше знакомство с миром kotlin. В прошлый раз я писал о первых впечатлениях. Все глубже изучая язык, на данный момент я успел прочитать 80% книги kotlin in action и понять идиомы языка и основные, заложенные в него, идеи.

Мнение: если вы начинающий тестировщик или совсем мало работаете с Java, вам будет сложно понять смысл Котлина. Если вы пробовали С#, Groovy и Python, то многие вещи покажутся уже знакомыми.

Просто читать книги и статьи о котлине не достаточно. В интернете появляется все больше материалов, в которых пишут о том, какой он классный, что он почти не тормозит, и вообще совместим с джавой просто на ура. Маркетинг и хайп - это хорошо, но давайте посмотрим на реальность.

ИМХО самой крутой фишкой являются extension методы. С их помощью можно легко нафигачить дополнительных методов в любой java класс.

ext.kt
fun webdriver.open(url: string, autoclose: boolean? = true) {
    autoclose(autoclose)
    get(url)
}

fun webdriver.autoclose(enabled: boolean? = true) {
    if (enabled!!) {
        runtime.getruntime().addshutdownhook(object : thread() {
            override fun run() = quit()
        })
    }
}

fun webdriver.find(cssselector: string): webelement {
    return findelement(by.cssselector(cssselector))
}

fun webelement.setvalue(value: any) {
    clear()
    sendkeys(value.tostring())
}

И потом использовать все это в своем коде:

val driver = chromedriver()
driver.open("http://juliemr.github.io/protractor-demo/")
driver.apply {
    find("input[ng-model='first']").set(1)
    find("input[ng-model='second']").set(2)
}

Мегакруто! В джаве такого можно добиться с помощью lombok, но для этого нужно понаставить плагинов в idea.

А как этот код можно вызвать в джава классе? Смотрим:

import com.driver.extkt;

webdriver driver = new chromedriver();
extkt.open(driver, "http://juliemr.github.io/protractor-demo/", true);
extkt.find(driver,"input[ng-model='first']").sendkeys("1");
extkt.find(driver,"input[ng-model='second']").sendkeys("2");

Красота, не правда ли? =)) Такова уж природа джавы.

Давайте глянем еще на один пример c лямбдами. В котлине их реализовали схожим образом с Groovу.

val userlist = listof(user("ivan", 26),user("dima", 12))
assert userlist.filter { it.name == "ivan" }.first().age == 26

Намного лучше и удобнее джавы. Но как на счет такого кода? Скажем, мы пишем такой DSL

browser.drive {
    to(::calculatorpage) {
        first.setvalue(10)
        second.setvalue(2)
        command.set("/")
        gobtn.click()
        result.shouldbe(5)
    }
}

Джава эквивалент будет таким:

Browser.Companion.drive(browser -> {
      browser.to(Calculator::new, calculator -> {
      calculator.getFirst().setValue("10");
      calculator.getSecond().setValue("2");
      сalculator.getSelect().deselectByVisibleText("/");
      calculator.getGoBtn().click();
      calculator.getResult().should(new Have().text("5"));
      return Unit.INSTANCE;
   });
   return Unit.INSTANCE;
});

Неплохая попытка. Я считаю, это - следующий убийца Selenide =)

На самом деле (без шуток) это все - часть моих безумных экспериментов. Чтобы понять язык, нужно с ним поиграться и попробовать разные идеи. Конечно же, максимальная совместимость Котлин и Джава задумывалась для более простой миграции на этот самый Котлин, а не наоборот.

На деле язык оставляет хорошее впечатление и облегчает решение повседневных задач. Да, есть проблемы с идиоматичными Котлин библиотеками, так как местами приходится строить костыли, делая вызовы в стиле

toJson(KotlinUser.klass.javaClass)

Но взамен вы получаете лаконичный синтаксис и ежедневный фан при работе с языком в Idea. Продолжаем погружение в яркий мир Котлин! Проект Kirk обрастает новыми фишками и идеями и даже появился в Maven Central.

P/S Так на Котлине ж пишут всего 2% разрабочиков? А, пофиг. Если что, пойдем формошлепить на джаваскрипте =))