LE Blog

Инженер с поэтической душой

24.12.2020 firtree_right Странные увлечения

Когда я смотрю на свои увлечения со стороны, мне и самому они кажутся очень странными. Я попадаю в какие-то крайне маргинальные сферы. Причём иногда с каким-то совершенно космическим опозданием. Отчего они ощущаются ещё более маргинальными. Вместо того, чтобы прогуливать пары с любителями MTG в универе, я внезапно подсел на неё через десять лет, когда найти партнёров в своём кругу уже не так-то просто. Вообще найти людей, сходящих с ума сходным со мною образом, довольно трудно. К тому же я почти не умею поддерживать социальные связи. Я знаю нескольких человек, которые это как-то умеют и делают в мою сторону, но сам я не особо стремлюсь инициировать контакты без повода. При этом, конечно, друзья мне дороги, и контакты с ними нужны, но по пустякам их как-то беспокоить не хочется. В связи с этим, кстати, и пандемия на моей повседневной жизни не особо сказалась.

В итоге кажется, что всеми моими странными хобби мне не с кем поделиться. А это вообще-то интересно :).

marginal hobbies

Как-то нашёл я на Ютюбе Бена Итера (Ben Eater), который собирал на макетной плате четырёхбитный компьютер. Смотрел весь плейлист просто запоем. И вот на прошлое Рождество он начал новый проект — компьютер на базе процессора 6502 всё на тех же макетных платах. И не просто так, а на американский манер ещё и наборы продавать решил. Получил я на почте этот набор, а у Бена под Рождество, да ещё и с таким количеством заказов, в видео образовалась пауза. А в Берлине на праздники делать особо нечего. Пить я почти не пью, по гостям ходить — смотри выше, погода — не очень, да ещё и магазины закрыты. И вот я сам без видео сел, прочитал все спецификации от производителей компонентов и компьютер собрал. Потом заказал на Амазоне другой дисплей, кнопок ещё, потом ещё микросхем, потом схему соединения доработал, и так Бен меня уже в своих тьюториалах за год и не догнал.

Ещё на работе у нас был товарищ, который увлекался механическими клавиатурами. И вот, казалось бы, можно в хобби уже не одному, а с кем-то. Но дружба у нас не задалась. А клавиатур я тем не менее себе собрал две. Причём одну я даже — отчасти поневоле — модифицировал. Подсветку мне было интересно припаять, а вот обычный диодик у меня отлетел, потому что корпус в него упирался в месте крепления. Пришлось припаять такой, который при сборке не мешается. Но хобби интересное. Можно спустить все деньги при желании. Спасает только то, что красивых кнопок с кириллицей очень мало.

pimp my keyboard

И тут внезапно возник у двух последних хобби микро-фьюжн. Я сделал клавиатуру для своего ретро-компьютера. Причём я помню, как раньше было сложно делать печатные платы. В детстве хотел собрать радиоуправляемую машинку, а отец зажилил мне хлорного железа. Он хранил его для своего несбыточного проекта светомузыки. Тогда я вычитал в технике молодёжи, что можно платы травить электричеством. И вытравил плату с помощью китайского блока питания, большой разогнутой канцелярской скрепки и ватки с раствором столовой соли. Моя машинка в итоге, как и отцовская светомузыка, упёрлась в отсутствие нужных деталей в магазинах. Но сегодня это просто какое-то чудо. Печатные платы стоят смешных денег, любые детали можно заказать по почте, даже припаять за тебя могут, даже, наверное, и играться потом за тебя с удовольствием будут, если опцию выберешь на сайте.

retro computer

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

26.08.2020 firtree_right Закон Ньюкома-Бенфорда

Мне кажется, что когда-то я уже об этом писал, но без примеров. Наверное, при консолидации блогов потерялось где-то. Поэтому напишу ещё раз. Посмотрели с Ирой «Connected» на «Нетфликсе», и я вспомнил, как когда-то был сильно впечатлён законом Ньюкома-Бенфорда. Суть в том, что существует категория случайных величин, которые будучи записаны в любой шкале подчиняются одному и тому же правилу. Первая значащая цифра 1 в них встречается 30.1% случаев, 2 — 17.6%, 3 — 12.5% и так далее. И удивительное в этом то, что этот закон рапространяется не только на длины рек, высоты гор, площади озёр и расстояния между галактиками, но и на сгенерированные людьми наборы чисел: суммы денег на счетах, число связей в социальных сетях или высоты небоскрёбов в метрах и футах.

Для проверки я решил сгенерировать свои наборы данных. Для примера взял один из рабочих проектов. Сначала посчитал все интервалы в секундах между изменениями в течение всей жизни проекта (1). Потом — сколько раз встречается каждый символ во всех файлах проекта (2). Для сравнения так же посчитал сколько раз встречается каждый символ в моих статьях (3). И вот какая частота первых значащих цифр у меня получилась в сравнении с предсказанным законом Бенфорда (оранжевый):

benford's law

24.06.2020 firtree_right Следи за руками

switcher koziavki

Умением печатать не глядя на клавиатуру я так и не овладел. Украденная у Владимира Владимировича Шахиджаняна программа «СОЛО на клавиатуре» меня не брала. Да и сам Владимир Владимирович, стоявший одно время в метро с компакт-дисками этой программы, мотивации не добавлял. Как знают все, кто не умеет печтать вслепую, это приводит к тому, что ты напечатал уже целый абзац, а раскладку переключить забыл. Потом всех, конечно, спасла волшебная программа «Пунто Свитчер». Но мне она всегда казалась с одной стороны подозрительно умной, а с другой — периодически срабатывала невпопад. Поэтому я ей не пользовался и со временем даже забыл, что она есть. Но тут субботним вечером, занимаясь практически парным практически программированием практически с незнакомцем, вспомнил. И решил написать воркфлоу для «Альфреда», который я купил и преступно мало использую. В отличие от «Пунты» времён нулевых он переключает только выделенный текст. Лихое было время, конечно, программы запросто перехватывали ввод-вывод друг у друга.

Сделан воркфлоу довольно просто. В основе вот такой скрипт:

#!/bin/zsh

query=$1

if [[ $query =~ [a-zA-Z] ]]
then
    result=$(echo $query | sed "y_@#^&qwertyuiop\[\]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?_\"№:?йцукенгшщз\х\ъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,_")
else
    result=$(echo $query | sed "y_\"№:?йцукенгшщз\х\ъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,_@#^&qwertyuiop\[\]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?_")
fi

echo -n $result

И оболочка из горячих клавиш, обрабатываемых «Альфредом», которые этот скрипт кормят и вставляют результат обратно. Alfred workfow в моём гитхабе. Со временем буду добавлять туда то, что сам использую.

30.07.2018 firtree_right Июль

Большую часть месяца на работе занимался инфраструктурой. IaaC (Infrastructure as a Code) — это то, что я открыл для себя, только переехав в Берлин. То есть, я писал, конечно, в «нек4» утилитки, чтобы управлять десятком одинаковых компов, но обычно все настройки серверов сводились к тому, что нужно открыть гайд и выполнить по очереди команды, что-то скопировать, пару раз перезагрузить и тому подобное. Также приходилось эти инструкции писать. Оказалось, что уже давно есть способы писать такие «гайды», которые исполняются как программы. И вместо того, чтобы ковыряться в админках хостинга или в терминале, можно писать код в своём текстовом редакторе, а потом запускать. И, хоп! Сервера развёрнуты, базы данных сконфигурированы, пакеты установлены, ключи лежат где надо. Это программирование не похоже ни на какое из моих предыдущих. Какое-то параллельное состояние организма. Как будто на две недели стал другим человеком. Или меня подменили.

cat

Заметил, что на вопрос, когда переедет Ира, несу всё время какую-то пургу. Похоже, как когда спрашивают про детей. Я-то знаю, как оно всё для меня. Но вопрошающий всегда находится в позиции укреплённой Вселенским Порядком. И отвечаю я как бы не ему, а всем поколениям предков, которые устои эти своими жизнями затромбовали. Хорошо бы, если в мире для любого положения дел, которое мне нравится, было бы явление с описанием и названием. Чтобы можно было сослаться, на каком основании, товарищ, нарушаем распорядок вселенной. И чтобы название было яркое, или, хотя бы, не отстойное. У геев или хиппи, скажем, гораздо прикольнее название, чем у чайлдфри. Слово «чайлдфри» — безвкусная вторичность, безотносительно представителей. Спрашивают тебя, почему яишницу без хлеба ешь, а ты такой: «А я хлыжбан!» А, ну, понятно.

cat

Дома поменялись настройки интернета. В первый раз, когда я увидел такую схему, я, конечно, хихикал. Например, когда узнал, что в польском отделении глобальной компании вся инфраструктура собрана на узлах, присланных из Америки. И на них никто не может ничего поменять. Но когда мне домой принесли новый роутер, воткнули в стену и всё заработало сразу, я хихикание пересмотрел. Есть в этой модели, всё-таки, своё очарование. Понаписав вдоволь инструкций по настройке и посмотрев, как они используются, я соглашусь, что исключение и инструкции, и её читателя из процесса — это добро!

cat

09.07.2018 firtree_right Счастливый коммит 2.0

В далёком 2010 году писал скрипт для того, чтобы определить, счастливый ли последний сделанный коммит. Это когда у хэша коммита, как и у номера билетика, сумма цифр первой половины равна сумме цифр второй. Долгое время он у меня работал. Событие не только случайное, но и редкое — от этого ещё более приятное. Потом Илья сделал нам телеграм-бота, который постил все сделанные коммиты в проектах «нек4» в телеграм-чат. В том числе и поздравлял со счастливыми.

В текущей команде сначала пришлось, конечно, объяснить смешное понятие счастливого билетика. Если пересказывать кому-то из другой культуры, становится очевидно, насколько в нашей культуре сильны суеверия. Фактически, человек доверяет себя совпавшим цифрам. Полученная исполнением ритуала удача должна не только отвести контролёра от маршрута, но и помочь где-то дальше.

lucky!

Для популяризации этой нелепой традиции я переписал скрипт на баше. Руби всё-таки неспешный. Можно почувствовать, как он спотыкается об эту проверку, особенно если ты стремительный инженер. Это не самое элегантное решение, но отдельную гордость вызывает то, что проверка работает на Маке и Убунте из коробки. Самые болезненные при переносе скриптов обычно как раз sed’ы и grep’ы. Скрипт нужно положить в .git/hooks/post-commit и сделать запускаемым.

#!/bin/bash

SHA=$(git log -1 --format=format:"%H" | tr /a-f/ /A-F/)
EQL=$(echo ${SHA:0:20}==${SHA:20:20} | sed 's/\([0-9A-F]\)/\1+/g' | sed 's/+$//' | sed 's/+=/=/' | awk '{print "obase=16; " $0}' | bc)

if [ "$EQL" == "1" ]; then
  echo
  echo '  ******************************'
  echo '  *     Yay! Lucky commit!     *'
  echo '  ******************************'
  echo
fi

Но что делать дальше, после того, как его закоммитил, я пока не придумал. Как его съесть..? :-Е

12.02.2018 firtree_right Лось квайн

Давненько я не писал чисто программерского! Есть такая прекрасная маргинальная область: бесполезная дурня. Для меня — это совершенно точно искусство, как оно есть, только для очень узкого круга людей. Более ли менее известный пример — это Simone Giertz – Королева говёных роботов. Я сам бесконечно уважаю бесполезную дурню. О некоторых штуках я даже писал ранее. Например, про лося в терминале или про JSFuck. Сегодня хочу рассказать про моё свежее улечение — квайны. И похвастаться, конечно.

Про программы, которые выводят собственный текст, я слышал уже давно. Это казалось чем-то очень навороченным и неприступным. Если нет специальной функции для этого и нельзя читать файл, то не совсем понятно, с какого бока начинать. Но тут как раз перед выходными мне прислали статью, которая подводит под это дело теоретическую базу. В силу не совсем профильного образования, мне не довелось серьёзно заниматься теорией вычислений, а это оказалась довольно прикольная область.

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

лось

В силу личного склада, это походило на зависимость. Чуть голова не разболелась. Главное в это деле — вовремя остановиться. Сейчас в репозитории есть усовершенствованная версия с гифки выше, версия, которая анимирует пробег лося по парамтерам, а так же версия в технике аски-графики. Примечательно, что не смотря на отсутсвие примеров, я пришёл к оптимальному варианту, который многие используют, когда хотят чтобы квайн, кроме своей непосредственной функции делал ещё что-то такое же бесполезное и прекрасное.

eval a = <<-'a'
# Мой код
puts "eval a = <<-'a'\n#{a}a"
a

После пошёл читать код такого же любителя странного — Юсуке Эндо (Yusuke Endoh). Он, среди прочего, написал квайн-реле, которое выводит на каждом шагу код на другом языке. И если его запустить на 128 языках 128 раз, то оно выведет обратно исходный код на первом языке. Чувак тоже относится к программированию как к искусству. Странному, гиковскому, маргинальному, нердическому, но при этом Великому и Бессмысленному Искусству. Например, он написал книгу, которая называется «The World of Obfuscated, Esoteric, Artistic Programming». Конечно же, на японском. И врядли её переведут ( ≧Д≦) Или у него есть «Квайн, устойчивый к радиации», из которого можно удалить одну любую букву и он при запуске выведет восстановленный исходный код. Ещё и в аски-графике.

Вот вам видео последней версии квайна, вдохновленное товарищем Эндо. Отлично провёл время, в общем. А у вас как дела?

Материалы для самостоятельного изучения

  1. Исходный код квайна с лосём, история и анимированная версия
  2. Статья на английском, которая неплохо раскладывает по полочкам
  3. Слайды презентации Юсуке Эндо про его странные увлечения
  4. Монументальное квайн-реле на его гитхабе

01.01.2018 firtree_right Декабрь

В детстве, в один прекрасный день я узнал, что «зонтик» по-украински будет «парасолька». Это слово сразу поразило меня в самое сердце. Сильно позже обнаружились истоки: «парасоль» — это зонтик от солнца по французски. Для дождя у них есть «параплюи». Дословно «против дождя». Как и в немецком, есть «зонненширм», а есть «регенширм». В португальском есть «гуарда-сол» и «гуарда-шюва». Слова описывают свою функцию на том же языке. Но парасолька не давала мне покоя. Как так, почему такое странное заимствование? Залез в этимологический словарь про русский зонта: оказывается, это из голландского «zonnedek». Буквально, «защита от солнца». То есть, в русском тоже парасолька, ещё и «ик» стало суффиксом. Стало интересно, а что же в английском? Полезли с Ирой в словарь. А это, оказывается, от латинского «umbra» – «тень». То есть, у англичан — и, кстати, у итальянцев — тоже парасолька! Полагаю, что заимствование всегда происходило до того, как устройство можно было применять от дождя. Когда материалы и технологии дозрели, те, кто слово заимствовал, а не сам составлял, продолжили его использовать. Однако, в английском со временем появилось другое специальное слово для зонта от солнца — «parasol». Язык один, а парасольки — две!

rain

Сейчас код, который я пишу, как правило, смотрит ещё как минимум два человека. Сам я тоже смотрю в два раза больше кода коллег, чем пишу сам. По-нашему называется «код ревью» или «просмотр кода». Друзья, это совершенно другое измерение! Возможность всё обсдуить, задать и получить вопросы полностью меняет манеру программировать. Взгляд человека, не погружённого в задачу, а значит и взгляд меня из будущего, стал частью процесса. В свете этого опыта кажется, что писать проекты в одиночку — это всё равно как глухому учиться разговаривать. Очень трудно. Выходит коряво. Усилий можно бесконечно затратить. А те, кто не понимают, только добавляют фрустрации. Теперь же, как будто новое чувство открылось. Результатами доволен.

♯♯♯

Развиртуализировал виртуальное знакомство длиной в 8 лет. Очень рад. На смену тревожному поиску совпадений контекстов приходит удовольствие от этих самых контекстов разницы. Место невротического желания понравиться постепенно занимает фокус на своих впечатлениях. Воодушевляет. Знание, что всегда есть место, где я могу укрыться и отсидеться бесконечно долго, делает меня более контактным.

♯♯♯

Недавно прочитал новость, что во Франции хотят запретить приносить в школу мобильные телефоны. Когда я приехал туда в 2001 году, в рекламах в кинотеатре все писали свой адрес Минител, наряду с телефоном. Была такая сеть до интернета там со своими устройствами для поиска информации и связи. Компьютер, байт и файл там называются «ординатёр», «октет» и «фищье». Сейчас мне это кажется бесконечно трогательным. Наличие глобальных сетей и возможность мгновенной информационной прозрачности сами по себе не приводят к синхронизации картин мира. Картины мира умеют защищаться.

♯♯♯

В моей любимой гуляшной есть русская официантка. О том, что она из России, поведал мне хозяин-венгр. Но с тех пор так и обращаюсь к ней по-английски. О чём через какое-то время поведал сдавшему её коллеге. Выяснили с ним, что не я один поддерживаю этот смешной этикет. Если спросить у человека, откуда он, и, если он ответит, сказать ему пару слов на ломаном его языке то это приятно и весело. А если услышать или узнать, как кто-то говорит на понятном языке (не английском — это важно) и обратиться на нём, то это ощущается как вторжение в личное пространство.

31.05.2017 firtree_right Май

Были в Берлине. Видели там панков за 40. Удивительное дело, когда протестные движения живут так долго. Внешний вид панка, который начинался как вызов, превратился в моду, в ещё один стиль одежды. Современные слёты панков выглядят как сборище людей в униформе. За разнообразием внешнего вида — это теперь только на косплей фестиваль. Как будто бы появился такой отдельный загончик для отдельного вида бунта. Панки стали декорацией: декоративные панки.

♯♯♯

В офисе паучок сплёл паутину ровно посередине между висящими лампами и ровно за трубой от ближайшей лампы. Потому что в темное время при включенном свете это самые тёмные места. Это одновременно суперочевидно и одновременно мегакруто: паучок нашёл угол, равноудалённый от двух ламп!

♯♯♯

Последние дни писал свои резюме и сопроводительные письма. Для меня оказался, прямо таки, опыт, меняющий восприятие. Взгляд на себя и свою жизнь глазами незнакомых занятых людей. Взрослит.

♯♯♯

Наблюдали в Берлине когнитивное искажение. Попали на поломку аппарата с билетами: деньги он проглотил, но не смог диагностировать окончание бумаги. Поэтому делал вид, что печатает билеты, а сам ничего не выдавал. Понятно, что учитывая трафик, организацию процессов и прочее, наткнуться на повторное такое поведение вероятность абсолютна одинакова для всех аппаратов. Но тело этому аналитическому заключению сопротивляется и, прямо, отказывается совать деньги именно в тот аппарат, с которым этот неприятный опыт случился. Эволюция, чёрт побери!

♯♯♯

Замечательно, что у огромного количества современных детей нет убеждения, что хвастаться или показывать свои достижения — это стыдно.

♯♯♯

Мне кажется, уже писал, что в программировании невозможно бесконечно опираться на то, что создал. Всё рано или поздно устаревает. Невозможно воздвигнуть памятник из кода. Если какой-то код существует и работает много лет, то это не потому, что он супергениальный, а по случайному стечению обстоятельств. И, конечно же, то, что он не был переписан в прошлом, не означает, что с ним этого не произойдёт в будущем. Даже владельцу вируса WannaCry пришлось что-то там на лету переписывать. И это хорошо.

♯♯♯

Берлин, как всегда, суперприятный город для жизни. Правда, после Голландии, где каждый, если не садовник, то архитектор, выглядит неприглядно.

♯♯♯

Посмотрели «Короля Артура» Гая Ричи. Совершенно какое-то отвязное пацанское кино. Гай Ричи сказал, что на любовную линию у него не хватило времени, поэтому он её опустил. Я считаю, это +10 к качеству фильма. Всё-таки важность романтической линии в историях сильно преувеличена. Также, в отличие от многих современных фильмов, очень крутой саундтрек. Я после него пересмотрел ричиевского же «Агенты Д.Я.Д.Я.», для которого тоже Даниэль Пембертон писал саундтрек, и там чувствуется, что это такой птенец артуровского саундтрека. Рекомендую, в общем.

07.09.2016 firtree_right Телеграм-бот для Яндекс.ПДД

Введение

Увлечение чат-ботами докатилась и до меня. Как это может случиться наилучшим образом, — по необходимости. А необходимость возникла в совместном использовании Яндекс почты для домена. Оказалось, что веб-интерфейс для этого совершенно не приспособлен, но есть API. Но писать целый сайт для этого кажется накладным, а чат-бот — в самый раз. И вообще, мне кажется, это один из самых продуктивных способов использования технологии: интерфейс к API.

Ссылку на полный текст бота я приложу в конце. Сам бот не содержит в себе полного функционала всего API, а имеет лишь необходимую на данный момент часть. Сейчас хотел бы поделиться парой находок, которые пригодятся всем, кто захочет писать чат-ботов для Телеграм с помощью node.js.

Chat bot

Хуки в продакшне

У ботов Телеграм есть два способа работы: когда бот сам обращается за обновлениями по определённому адресу (polling) и с помощью веб-хуков, когда сервера сами дёргают заданный хук для передачи данных боту. В продакшне, конечно, удобнее работать с хуками, а при разработке — нет, поскольку сервер запускается на локальной машине. Кроме этого я рекомендую завести другого бота для разработки, чтобы те, кто пользуются вашим ботом в продакшне, не замечали, как вы разрабатываете. Возможность сделать это я нашёл пока только в одной библиотеке: node-telegram-bot-api с помощью недокументированной функции processUpdate. Делается это довольно просто. При инициализации бота в файле lib/bot.js:

if (process.env.NODE_ENV === 'production') {
    bot = new TelegramBot(config.botToken, {polling: false});
    bot.setWebHook(config.host + config.url);
} else {
    bot = new TelegramBot(config.devBotToken, {polling: true});
}

А затем уже в серверной части, которая, хоть и запускается всегда, имеет значение только для продакшна, в файле lib/web.js:

app.post(config.url, function (req, res) {
    options.bot.processUpdate(req.body);
    res.status(200).send({}).end();
});

Весь остальной код для бота работает в обоих случаях одинаково и в изменениях не нуждается, что совершенно прекрасно!

Оповещение об остановке

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

Если вы запускаете приложения с помощью pm2, то этот менеджер использует для остановки процесса тот же сигнал SIGINT, что мы используем, когда останавливаем сервер в разработке с помощью Ctrl-C. Очень удобно! В файле index.js

process.on('SIGINT', function () {
    Promise.all(config.permitUsers.map(function (userId) {
        return bot.sendMessage(userId, 'Бот временно выключается. Только спокойствие!', {
            reply_markup: {
                hide_keyboard: true
            }
        });
    })).then(gracefulClose).catch(function (err) {
        console.log(err);
        gracefulClose();
    });
});

Таким образом, останавливая наш сервер через Ctrl-C мы видим то же, что увидит пользователь, когда перезапускается приложение на сервере.

Материалы для самостоятельного изучения

  1. Полный на текущий момент код Телеграм-бота для Яндекс.ПДД;
  2. API Яндекс.ПДД;
  3. Как установить приложение node.js на ubuntu 16.04.

23.06.2016 firtree_right Тестирование сервера Node.js

Вводная

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

Для тестирования кода на ноде я использую жасмин. Для запуска задач — галп.

Сегодня хочу рассказать о двух простых приёмах для тестирования кода сервера, которые позволяют выделять и тестировать только то, что нужно.

Staged reality

Кто запускает сервер

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

if (require.main === module) {
    app.use('/', require(path.join(__dirname, 'routes', 'main'))());
    var server = app.listen(5000, function () {
        ...
    });
} else {
    exports = module.exports = function (options) {
        app.use('/', require(path.join(__dirname, 'routes', 'main'))(options));
        return app;
    };
}

Таким образом, уже в тестовом фреймворке мы будем запускать:

app = require('index.js');
server = app(...).listen(6000, function (err) {...});

перед каждым тестом, а после каждого теста:

server.close(function (err) {...});

Очень удобно!

Имитация библиотек

Второе, что бы хотелось сделать при тестировании сервера, — имитировать используемые им библиотеки, чтобы тестировать только код сервера, а не библиотеки. Связки тоже важны, но только тогда, когда мы этого сами хотим. И тут появляется интересный момент. Если мы хотим имитировать библиотеки при тестировании, нам нужно использовать определённый паттерн при программировании. Паттерн фабрик. То есть мы не просто тестируем свой код, но устраиваем архитектуру и стиль так, чтобы его удобнее было тестировать.

В случае с паттерном фабрики мы возвращаем в качестве модуля не объект, а функцию, которая создаёт объект в соответствии с нашими параметрами:

exports = module.exports = function (options) {
    options = options || {};
    var customLib = options.customLib || require(...);

    /* GET main page. */
    router.get('/', function (req, res, next) {
        res.end('Real server text. CustomLib: ' + customLib.name);
    });

    return router;
};

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

Таким образом, получается, что при разработке через тестирование, или даже просто при использовании тестов важно не только писать тесты, но и писать код, который, во-первых, можно, а во-вторых, удобно тестировать.

Для самостоятельного изучения

Полный код примера в сборе