Pull to refresh
31
Антон Куранов@Throwable

Пользователь

13
Subscribers
Send message

Что я понял, когда написал много тестов

Извините, если, написав много тестов, следуя хрестоматийным TDD-шным истинам, в вас не закралось зерно сомнения по поводу правильности данного подхода, то вы пока еще ничего не поняли.

Тесты — это документация

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

Но если вам легко написать на код тест, скорее всего, он легко читается и у него простая логика.

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

Другая вещь, которую вы не упомянули -- это мокирование. Оно как правило занимает 90% времени написания теста и его отладки. А самое смешное, что в подавляющем большинстве случаев поведение мокированного кода -- это поведение сферического коня в вакууме, которое слабо соотносится с реальными кейсами. Особенно все, что касается стейта и базы данных. Поэтому народ сейчас все более склонен поднимать в контейнере реальную базу с тестовым набором данных, чтобы тестировать все как есть. А юниты все чаще заменяются "сценарными" тестами, которые тестируют именно бизнес спецификацию, а не внутренний дизайн.

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

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

Давайте немного улучшим наш код. Перенесем логику в сервис

Это по-вашему улучшение? Вы нагрузили сервис доступа к данным инородной логикой обработки и визуализации ошибки, закамуфлировав ее ввиде "пустого" результата для компонента.

Тесты — это инвестиции в светлое будущее

Тесты -- это мусор в проекте, необходимый лишь для повышения качества service delivery, и требуют значительных затрат на написание и поддержку. Чем больше глупых тестов в проекте с многократным покрытием одних и тех же фрагментов, тем сложнее становится выкатывание новых фич. Поэтому держать нужно лишь необходимый минимум.

  1. Тесты -- это тоже код, поэтому они также могут содержать баги. Кто же тестирует тесты? Основной код? Круговая порука получается.

Однозначно. Продюсер льет в topic строго последовательно, используя одно соединение. Ack подтверждения служат для гарантии доставки при выходе из строя основной partition, а не для упорядочения. Все остальное фантазии автора.

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

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

Пара моментов:

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

  2. Темная тема фокусирует внимание на яркие объекты типа текста, тогда как фон остаётся неконтрастным и поэтому незаметным. Проблема в том, что это делает практически невидимыми оконные элементы интерфейса, которые-таки несут смысловую нагрузку.

По поводу лимита файловых дескрипторов: практически во всех дистрибутивах он установлен в 1024.

В JVM процессах ещё есть такая неприятная вещь, как non-heap memory, которая выходит за рамки лимита по Xmx и собственно вообще ничем не лимитируется. Его любят использовать всякие вещи, IO подсистемы и т.д. В итоге возможна ситуация, когда процесс убивается ОС, хотя в куче полно места, и OOM с дампом не сгенерированны. Особенно актуально, когда выставлены лимиты cgroups на контейнер.

Ещё неплохая практика выставлять Xms равным Xmx, таким образом жёстко резервируя память для java процесса.

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

С другой стороны, системный функционал, который способствует уменьшению шаблонного кода в бизнес логике, всегда должен приветствоваться. Этим собственно и должны заниматься сеньоры -- сделать разработку бизнес функционала простой и понятной.

TCP гарантирует, что данные не будут повреждены, утеряны,

Если быть точным, то TCP никак не гарантирует доставку данных, а лишь то, что принятые данные всегда корректны.

Еще скажите, что у вас монолит, и вас сразу закидают гнилыми помидорами :)

Именно по этой причине в тренд входит serverless и лямбды :)

То, что тесты отдельных частей кода зеленые отнюдь не гарантирует, что весь бизнес кейс работает корректно. Кроме того, тестирование по частям накладывает дополнительные расходы на мокирование и фейкирование зависимостей, а это не тривиальная задача. Например, как тестировать по-частям монорепозиторный фронт с зависимостями от 100 микросервисов?

В те времена для того, чтобы запустить программу, надо было принести ее в вычислительный центр. Помещение, размером с современный дата центр

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

К сожалению, опыт и грабли.

Ещё один способ - постоянное запугивание и сравнивание с конкурентами :)

Вообще любой успешный проект проходит как минимум 4 стадии легаси, при котором необходимо полное или частичное переписывание:

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

  • Когда выбранный дизайн уже не позволяет эффективно реализовать скопившиеся требования.

  • Когда одна команда уже не справляется с потоком требований и требуется распределить разработку.

  • Когда количество клиентов и нагрузка резко возросли, и требуется менять существующую архитектуру решения.

То есть в обоих случаях сначала дампим и копируем все данные с основного сервера на реплику, а затем слушаем изменения. Не совсем понятно можно ли это делать online, и что будет происходить в промежутке между копированием реплики и началом подписки, ведь данные на мастере постоянно изменяются. Или для поднятия реплики нужно мастер тоже останавливать?

P.S. вроде как были автоматические решения для HA типа PgPool.

В свое время, помню, Oracle CBO часто ошибался при объединении двух таблиц с where. Выборка по первой таблице была огромной, а по второй - давала лишь несколько строчек. По какой-то причине в определенный момент он предпочитал сначала делать выборку именно по первой таблице, что увеличивало время запроса с 0.1 сек до 5-6. Не помогали ни переписывания запросов (Oracle индифферентен к форме запроса), ни прогоны анализатора статистики. Лечилось только явными хинтами, поставленными в запросе. Не знаю, баг ли это был или что-то ещё, но факт в том, что CBO не гарантирует оптимальное выполнение.

Можно оптимизировать, как делают многие JPA: сделайте SQL sequence сразу с шагом 10, и кешируйте промежуточные значения. Однако, в этом случае могут появляться "дырки" и будет нарушен порядок по Id в случае нескольких инстансов.

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

А это как раз очень натурально получается. Всегда есть некий баланс между качеством и скоростью. Оптимальное решение всегда рождается, когда времени на реализацию достаточно: можно хорошо подумать, исследовать, отрефакторить и протестить.

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

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

module.exports = leftpad;
function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
  }
  return str;
}

2016: left-pad npm package

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

Information

Rating
6,918-th
Location
Madrid, Испания
Registered
Activity