Мой горький и сладкий опыт с некоторыми плагинами Grails’а


Сейчас я полностью сам делаю проект и у меня полное право выбора всего стека технологий. Ну то-есть выбора плагинов для Grails 🙂
Хочу накидать небольшую заметку, с полученным ценным опытом, мне бы пригодилось месяц назад.

TL;DR;

Вы скорбите по тем временам, когда мужчины были настоящими мужчинами и сами писали драйверы устройств?

Торвальдс, Из анонса одной из первых версий Linux.
Почти все плагины сырые и делаются одиночками. Много плагинов дублирующих функциональность друг друга. Много заброшенных плагинов. Принцип The search is over тут не работает. Готовьтесь морально допиливать плагины ручками. Радует то что плагины можно просто копировать себе в проект и делать с ними что хочешь.
Готовьтесь форкать и комитить, комитить, комититить…

Spring Security

Для авторизации раньше я всегда работал с плагином Apache Shiro, и он очень простой и лёгкий.
В этот раз я решил воспользоватся плагином Spring Security (для просто ты называется S2), поскольку он поддерживается самими создателями Grails и вообще является дэ факто стандартом.
Spring Security разбит на несколько плагинов: S2 Core — ядро, S2 OpenId — интеграция с OpenId и S2 UI — плагин который даёт сразу админку для управления пользователями.
Так вот, S2 Core плагин это просто адское гавно. Хуже него только плагин S2 UI! Прям фрактал плохого дизайна.
Я вляпался с ним не слабо, потому что пришлось его переписывать полностью. Переписывать пришлось маленькими шажочками и очень вдумчиво. Даже те вещи которые я сразу понял что нужно выкинуть. Мне нужно было знать полностью все аспекты этого плагина чтобы самому потом не напортачить.
Это поломало все дадлайны.
Если когда нибудь появится время и желание я обязательно опишу всё что мне не понравилось в них — это очень ценный урок из серии «как писать нельзя».
Самая главная ошибка плагина: он не предоставляет доменных объектов для пользователя и ролей.
Вместо этого ты генерируешь эти классы и в конфигурации потом прописываешь имена этих классов. А ещё ты можешь переопределить имена стандартных полей.
В результате код превращается в такой ООПец:

	def user = lookupUserClass().newInstance(email: command.email, username: command.username, accountLocked: true, enabled: true)
...
String lookupUserClassName() {
	return grailsApplication.config.userLookup.userDomainClassName
}

Т.е. по сути этот код делает вот что:

def user = new User(email: command.email, username: command.username, accountLocked: true, enabled: true)

И это я ещё сократил код, на самом деле он ещё разбросан между разными классами с наследованием и прочими прелестями. Да, и в нём ещё и ошибка, потому что имена полей тоже можно конфигурить.
Переделанный вариант плагина я постараюсь выложить в open source, но боюсь он будет обратно не совместим с S2. И мне даже страшно представить сколько емейл переписки мне предстоит с Бартом чтобы пропихнуть свои комиты.

Captcha

С капчей тоже лажа: есть два плагина JCaptha и SimpleCaptcha. И первый и второй обновлялись ещё чёрт знает когда. Уже не помню почему но выбрал JCaptha (может испугало слово Simple).
Связался с автором плагина Робом Флетчером, попросил выложить исходники на гитхаб. Он выложил, так что потом тоже буду форкать и допиливать напильником. Пока фикс мелкой баги отпулреквестил.
Кстати я решил что нужно исключить похожие символы из капчи чтобы сделать её более гуманной.
Например английская o похожа на ноль 0. Также i похоже на маленькую l и единицу 1.
Также я сделал проверку капчи отключаемой чтобы автотесты могли пройти через неё в test environment. Нужно будет тоже пулреквестнуть.

Тестирование

Несмотря на то что я постоянно всех зомбирую «пишите тесты, мать вашу!», «TDD, TDD, TDD!!!» сам я должен признаться что сапожник без сапог.
Я ещё ни разу не работал на проекте где были бы нормальные автотесты. Если честно мне даже кажется что почти невозможно писать нормальные тесты — всё время получается какое то гавно на выходе: куча given кода, тесты хрупкие и blinking, все flow и крайние случаи не покрываешь, в итоге тестируются какие то моки а не сам код. Но самое мучителеное для меня придумывать километровые названия тестовых методов.
Не смотря на то что я перечитал реально тонны литературы всё равно каждый раз написание тестов для меня становится головной болью. Потому что ни одна литература не заменить хороших примеров кода. А их у меня я повторюсь не было:
В Лите тестами я успел покрыть только самодельную прослойку к БД для седьмого Delphi. И кстати они реально выручили когда я решил эту либу использовать в Delphi 2007 — вдруг поменялась логика Variant Truth в одном случае, и я бы наблюдал фееричные глюки непонимая откуда они берутся.
В КАИ тесты я успел написать только на некоторые свои компоненты и были они не очень, потому что большинство из них были визуальными.
В ИМСЕ я впервые в жизни почти всё покрыл тестами. Мокать тогда было нечем и у меня был интеграционные тесты. И я тогда просто задолбался поддерживать тестовый набор — после каждого теста он изменялся. Написать свой DBUnit у меня тогда времени не было.
За всё время работы в Неткрекер я не написал ни одного теста вообще. Да если честно я вообще в NC толком ничего покодить и не успел — я только свичнулся на яву и упорно учил её, изучал IntelliJ и бесконечно огромную документацию по NC.
На Hotwire тесты по началу не писали вообще а потом резко сказали что теперь без тестов новый функционал не будет проходить ревью. Но как это это не очень строго было да и особенность проекта там была такая что интеграционный тест ты хрен вообще напишешь. Функциональные тесты никто не умел делать и наверное даже никто не знал что это такое. Пацаны это до этого не писавшие тестов, когда показывали мне на ревью свои тесты у меня из глаз бежала кровь. Они городили кучу boilerplate code из всяких fixtures только для того чтобы потестить какой-то жирный приватный метод.
Но они старались, учились и количество тестов довольно активненько росло. Недавно видел на JEEConf джуна из HW он рассказал что они реально уже всё привели в порядок. Молодцы, такой большой и неповоротливый mature проект стабильно доводят до ума.
В Грамант тестов не писали вовсе. Причём это не специфика самой компании а специфика культуры русских программистов. Там почти все проекты для внутреннего рынка и продуктовые, и если нас украинцев на аутсорсах хоть с опозданием в несколько лет но американцы пинают делать код правильно, то в России этот процесс идёт только от энтузиастов.
Я пытался осилить магию тестов в Grails, пускай не сразу, но у меня что-то там получалось, но один хрен кроме меня эти тесты никто не запускал. В результате код менялся, тесты валились а я даже не знал поменялась ли логика программы либо это реальный баг.
Писал я только юнит тесты. Я пытался писать юнит тесты для контроллеров но для этого нужно было чтобы не было SQL в коде. А его было много. С тех пор я теперь не просто избегаю SQL, а прям панически его боюсь.

И вот теперь у меня появилось время, мотивация и свобода выбора чтобы наконец начать делать тесты по взрослому.

Spock

Spock
Spock — это одно из лучшего что я видел за последнее время. Это BDD фреймворк, клон RSpec’а.
Я как-то раньше его просто недооценивал потому что думал что вся польза от него это только сахарок given: when: then: и where: блок.
Оказалось что споком можно ещё и мокать.

Короче, я его сейчас активно осваиваю. Кстати клёвая лекция про него на Infoq.

Geb

У меня всегда была проблема с функциональными тестами на Selenium. Мне оно всё таким сложным и монструозным казалось, и дальше тренировок на кошечках я не мог зайти. Но сейчас я прорвался в этом направлении. Имя этому прорыву — Geb.
Geb — это большой праздник для меня. Это обычная обвёртка над Selenium WebDriver но в него уже интегрировано понятие PageObject и что самое главное для меня он даёт jQuery-like DSL! Т.е. вместо совершенно упоротого .sendKeys("Hello!") можно написать .text("Hello!").
Это очень здорово, потому что я сразу просто сел, и поехал. Все мои предыдущие знания jQuery сейчас снова работают на меня. А GebReportingSpec позволяет получать скриншоты по каждой странице. Почти как в Thucydides.
Если вы Ява программист то вы ОБЯЗАНЫ попробовать Geb+Spock. Эта статья Питера Ледбрука будет хорошим началом: THE FUTURE OF FUNCTIONAL WEB TESTING?
Делает Geb кстати Роб Флетчер, это тот же что и плагин для JCaptcha.

У Geb есть конкурент который раньше был стандартом де-факто: functional testing plugin. Плагин написал Марк Палмер. Использует внутри HtmlUnit, поэтому тестить яваскриптик не выйдет. У плагина своё АПИ обвёртка над Селенумом.
Вообщем Geb лучше во всём: API лучше, он может использовать тот же HtmlUnit но просто как драйвер наравне с Firefox или Chrome.
Прошёл слушок, что в Grails 2.3 Spock станет дефолтным тестовым фреймворком.

Кстати в этой же переписке в твитере немного похоливарили между собой авторы Geb и Functional testing.
Geb+Spock это как раз яркие примеры почему важен динамизм в языке и какие клёвые DSL’ы можно делать на Groovy. Может быть не всё приложение, но уж точно все тесты вы просто обязаны переписать на Groovy.

Я не буду писать дальше про другие плагины, это уже не так важно и интересно.
Отмечу только что однозначно в проект подключите Fields Plugin и JodaTime. Оба плагина сделал тот же Роб Флетчер 🙂

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s