18-ть лет программирую на Delphi. Знаю кроме всего прочего C, C++, Objective-C, asm PDP-11, asm-Intel86, FORTH и несколько "птичьих языков". Хочу делится тут ТЕХНИЧЕСКИМИ подробностями своей работы программистом. И своими мыслями по программированию/архитектуре.
Кроме программирования сильно интересуюсь TDD и UML.
Про TDD - регулярно слышу - "это нужно только Шуре" :-) и я к этому - "почти привык".
Действительно - тестирование - В ПЕРВУЮ ОЧЕРЕДЬ нужно - программистам. ХОРОШИМ программистам.. Ну или наоборот - ПЛОХИМ.. Не гениям... Тем кто не может ПРЕДСКАЗАТЬ - как поведёт их код при внесении МАЛЕЙШИХ изменений.
Приведу один пример. Я долго и нудно и с удовольствием и с интересом программировал редактор Эверест. И на нём сделан КОММЕРЧЕСКИЙ продукт.
Так вот - в Эвересте одна из граней функциональности - печать и предварительный просмотр печати. И как это отлаживать?
Когда документы бывают по нескольку тысяч страниц. Печатать? Несколько ПАЧЕК бумаги?
Даже виртуальный принтер не помогает.
И я ОЧЕНЬ долго правил код "машины печати". И попадал в "программистские качели". Правишь тут - сломалось там.. правишь там - сломалось тут.. И так - БЕСКОНЕЧНО... Мозги готовы били вскипеть... Хотелось убить кого-нибудь рядом... Функционал - не сходился...
А ещё Группа Качества находила одну ошибку за другой.. Группа Качества была как Бич Божий!! Они находили ошибки БЫСТРЕЕ, чем я их исправлял...
Всё время находилась 150-я страница документа, или 300-я или 550-я.. Которая не печаталась.. Или на которой приложение тупо падало....
И тут я задумался о ТЕСТИРОВАНИИ... Было страшно и жутко... Хотелось ПОКРЫТЬ весь функционал тестами.. Но я не понимал как это сделать... Мысли разбегались как тараканы.. Я думал - "как же найти СУПЕР-тест - чтобы СРАЗУ покрыл ВСЁ"....
И хотелось пойти и убиться головой об стену....
Но тут нашёлся умный человек...
Александр Можаев... Он сказал - "есть DUnit - Unit-тесты для Delphi... ты наверное знаешь.. ничего космического.. но очень полезно..." Я - НЕ ЗНАЛ...
И решил попробовать....
Когда я взял DUnit и посмотрел "внутрь" - РАЗАЧАРОВАНИЕ настигло меня... Не то что "ничего космического..." а..... аа... "ВООБЩЕ - НИЧЕГО"... код простой и "ровный"...
"Я тоже так умею"...
Я спросил Можаева - "и чо?"...
Он мне сказал - "попробуй.. понравится..."...
Я пожал плечами и решил попробовать...
К тому моменту за моими плечами было несколько написанных фреймворков.. Да и вообще я думал, что "я уж знаю как всех научить программировать" :-)
(это был сарказм конечно)
Взял я DUnit И начал "крутить в руках"...
"ничего необычного".. "где же тут серебряная пуля?"
ну published-методы, которые "зачем-то" показываются в "каком-то дереве"... ну и что?
Но я решил - "раз люди советуют - значит оно того стоит"...
И начал крутить дальше... И написал СВОЙ ПЕРВЫЙ ТЕСТ (конечно не первый в жизни, но ПЕРВЫЙ под DUnit).. Который просто печатал текст... Точнее строил "предварительный просмотр печати".. Через виртуальную канву.
И тест прошёл :-) И я увидел "зелёную полоску".
Дальше я занялся "сферическим конём в вакууме".. Я стал пытаться запустить этот тест в автоматическом режиме.. И тут меня постигло ОЧЕРЕДНОЕ РАЗАЧАРОВАНИЕ...
Я то думал, что достаточно запустить "экзюк" (спасибо Всеволоду Леонову за это слово - мы раньше говорили - "экзешник") и указать "экзюку" ключ запуска - "запусти мне тест в автоматическом режиме"....
НЕ ТУТ ТО БЫЛО!!!
ОКАЗАЛОСЬ - "ключа не было" НИКАКОГО....
Я стал "курить исходники" (как говаривал ещё один мой коллега).
После вдумчивого "курения исходников" - выяснилось, что для того, чтобы тесты выполнялись в автоматическом режиме - надо собрать ДРУГОЙ "экзюк" и в "консольной моде". Не GUITestRunner, а ConsoleTestRunner!
"что за чёрт!" - сказал я себе - "эти авторы DUnit наверное издеваются надо мной"....
Надо МНОЙ, над человеком, который укротил "птичий язык" и Rational Rose (это тоже был сарказм). Они издеваются?!!!
Но потом я подумал.. потом подумал ещё (и мне понравилось). И я решил - а почему собственно - я не могу иметь в ОДНОМ приложении и GUITestRunner и ConsoleTestRunner. Оказалось, что - НЕ МОГУ. Но это были ЧИСТО ТЕХНИЧЕСКИЕ сложности. И я их решил.
Я скрестил "ежа с ужом".. То есть GUITestRunner и ConsoleTestRunner, которые "допилил напильником". И ConsoleTestRunner получил ещё и наследника - KTestRunner - я тогда уже думал о публикации результатов работы тестов в нашей "базе знаний" и bug-треккере.
И в итоге тесты (ОДИН тест) - заработали как в "ручном" режиме, так и в автоматическом (если задавался ключ командной строки - ItsLAW).
Дальше я вставил тесты в автоматическом режиме в автоматический запуск из Scheduler'а и был СЧАСТЛИВ.
Счастлив - потому, что мне удалось заставить "это" работать, а не потому, что я понимал - "зачем это мне".
Пока.. Пока ТЕСТ НЕ УПАЛ!!! :-) И тут я ПОНЯЛ!! Меня - БУКВАЛЬНО осенило!
Я правил "очередную нудную ошибку от ГК". Опять же про ПЕЧАТЬ...
ВЧЕРА поправил, ЗАКРЫЛ ошибку и счастливый ушёл домой СПАТЬ.
Когда я пришёл утром - УПАЛ МОЙ ПЕРВЫЙ ТЕСТ!!!
И тут меня будто током ударило!!! Вот ОНО!! Я теперь "Знаю - ЗАЧЕМ"!!!
Я решил разобраться - "а в чём собственно дело? что же я сломал вчера?"
И тут (о боги!!!) я сделал НАИМУДРЕЙШУЮ вещь.. Я НЕ СТАЛ ПРАВИТЬ код... Я сделал ВТОРОЙ ТЕСТ.. Да.. да.. Это ОЧЕНЬ ПРОСТО.. когда знаешь это.. но я тогда - НЕ ЗНАЛ...
Я сделал (повторю) ВТОРОЙ ТЕСТ.. по мотивам ошибки, которую я закрыл вчера, и которую ГК проверила и тоже радостно закрыла.
И ВТОРОЙ ТЕСТ - КОНЧЕНО же прошёл...
А ПЕРВЫЙ ТЕСТ - как не проходил, так и не прошёл...
Дальше я НЕДЕЛЮ возился с тем, что я сломал в ПЕРВОМ ТЕСТЕ (ГК это пока не нашла) и это не давало мне покоя...
Я запускал этот тест в ручном режиме и крутил всякие разные колёсики... Я же - ПЛОХОЙ программист - я не могу АНАЛИТИЧЕСКИ решить сложную задачу (я пробовал). Я лишь могу - "крутить колёсики"....
И в какой-то момент... в какой-то момент.. в какой-то момент... Я КРУТАНУЛ НУЖНОЕ колёсико... И ПЕРВЫЙ ТЕСТ - ОТРАБОТАЛ!!!
Я запустил его раз и РАЗ.. и он - ОТРАБОТАЛ...
(напомню - я запускал тесты в "ручном" режиме - не ВСЕ сразу, а ОДИН - первый).
Я покоммител код. Написал ошибку и закрыл её. И довольный УШЁЛ ДОМОЙ....
Когда я пришёл на работу на следующий день - очередное РАЗАЧАРОВАНИЕ ждало меня...
Упал ВТОРОЙ ТЕСТ :-(
И опять хотелось пойти и "убиться головой об стену"....
Но я взял себя в руки (это опять был сарказм) :-)
И прогнал тесты - снова и снова... И "номер первый" (на деревянной ноге) - проходил, а "номер второй" (с босыми ногами) - упорно не хотел проходить...
Моё самолюбие "гениального программиста" и "укротителя Rational Rose" было уязвлено этим "маленьким босоногим дикарём", и я решился взяться за него всерьёз...
ЦЕЛЫЙ день я искал причину его падения.. и не мог найти... В конце-концов часам к 12-ти ночи причина была найдена.. Она крылась в "маленькой запятой".. Но что это была за запятая!!! Серебряная пуля меркнет по сравнению с ней. Но она была найдена.
И НОМЕР ВТОРОЙ - прошёл!!!
Счастью моему не было предела.
Я покоммител код. И собрался домой... Вышел из комнаты.. Запер её... Пошёл на стоянку...
Но ЧЕРВЬ СОМНЕНИЯ глодал меня... я осознавал, что "я что-то не доделал"....
И я вернулся...
И прогнал ОБА ТЕСТА в автоматическом режиме...
НОМЕР ВТОРОЙ - отработал.. А НОМЕР ПЕРВЫЙ - упал :-(
Моё самолюбие было опять уязвлено..
Идти домой катастрофически расхотелось...
"Качели" подумал я..
"Эти чёртовы пограммистские качели"...
И я не ушёл....
Ошибка нашлась сама собой.. Я же находился "в потоке" и я - ЗНАЛ - что я правил и в НОМЕРЕ ПЕРВОМ и в НОМЕРЕ ВТОРОМ.. И я проанализировал изменения...
И "узорчик"!!! СОШЁЛСЯ...
Я внёс изменнения и прогнал НОМЕРА ПЕРВОГО.. И он - ПРОШЁЛ..
Тогда я прогнал и НОМЕРА ВТОРОГО.. и он.. ТОЖЕ ПРОШЁЛ...
Я счастливый отправился ДОМОЙ...
Теперь - я ЗНАЛ, ЧТО ДЕЛАТЬ и "зачем всё это нужно"...
----------------------------
"Регрессионное тестирование" - спросите вы...
"Конечно!!" - отвечу я...
Но! Плохой Гениальный программист и "укротитель Rational Rose" - НЕ ЗНАЛ этого, хотя и прочитал "миллион статей".. где "умные люди" - пытались донести "это" до "него"...
Но теперь - Я ТОЧНО ЗНАЮ ЧТО ДЕЛАТЬ...
---------------------------
Теперь у нас порядка 2000 "регрессионных" тестов.. которые гоняются КАЖДУЮ ночь.. и КАЖДЫЙ день на РАЗНЫХ машинах.. немногих.. их по пальцам пересчитать.. и мы ЗНАЕМ ЧТО ДЕЛАТЬ.. главное, что мы можем - ОПЕРАТИВНО реагировать.. находясь "в потоке".. пока "вчерашние" изменения в памяти и на слуху.. и "узорчик" - чаще - складывается, чем не складывается...
----------------------------
Ну а тестов печати у нас - всего штук 100 (оценка сверху) и СУПЕР-тест, который "покрывает всё" - нам не понадобился.. И спим мы спокойно :-)
------------------------------
P.S. в следующий раз, если не остыну, я расскажу вам о знакомстве с VGScene (ака FireMonkey) И как я её ругал.. и как тупил.. и не мог проникнуть в "слоёный пирог" стилей.. и как Антон (сам того может быть не зная) - навёл меня на понимание гениальности архитектуры данной библиотеки...
P.P.S. Также хочется рассказать - как мы локализовывали приложения под Delphi и что мы из этого вынесли.
P.P.P.S Ещё хочется рассказать как я "на коленке" делал FORTH-машину для тестирования приложений под DUnit. Как Дима писал к этому обвязку и что из этого получилось.
P.P.P.P.S Интересно также рассказать про "программирование на UML" vs. "прототипирование на UML" и метафоре "номенклатуры микросхем" vs. "собирание логики на триггерах".
P.P.P.P.P.S Ну и конечно хочется рассказать "о деле всей жизни" - редакторе Эверест. Технические подробности и решения. Которые родились в процессе этой разработки.
Ну и команда, которая делала "ту самую версию":
Комментариев нет:
Отправить комментарий