Pull to refresh
40
0
Михаил @mSnus

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

Send message
У меня есть вопрос — скажите, пожалуйста, с какой целью вы тестируете репозиторий? Причем, не реальный репозиторий — а с замокаными зависимостями ?! Какой класс ошибок вы хотите поймать своим тестом?

Дело в том, что каждая строчка тестов — на самом деле имеет цену. Цену за написание, цену за поддержку в актуальном состоянии, цену за запуск тестов при каждом билде и так далее. Соответственно, должно быть некоторое нетривиальное ПОВЕДЕНИЕ кода, которое мог бы проверить соответствующий тест. А что вы тут проверили? Как прохождение этого теста увеличивает вашу уверенность в том, что на проде боевая система будет работать как надо?

Одно дело, если репозиторий привязан к БД или ORM, и тестируется в этом комплексе. Тут вы хотя бы проверяете что везде где нужно поставили границы транзакций, аннотации и проч.

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

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

Повторю простое и понятное определение юнит-тестов, которое когда-то нашел, и с тех пор запомнил применяю: «Юнит-тест — это проверка правильности поведения компонента, в предположении, что все другие компоненты от которых он зависит — работают правильно».

Соответственно, если у компонента нет нетривиального поведения — не нужно его тестировать. Если нетривиальное поведение есть, и оно является следствием работы другого компонента (например, репозиторий критически зависит от БД) — ну так и тестируйте его в типовой конфигурации тогда. А базу данных сделайте стандартным окружением для теста. И только если другие компоненты поставляют на вход теструемого тривиальные данные, а сложность заключается в логике их обработки — ну вот тогда и пускайтесь во все тяжкие: мокайте входные зависимости (благо, они должны быть тривиальными) — и проверяйте юнит-тестом логику обработки внутри тестируемого компонента.

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

Опять же, юнитами желательно тестировать логику, от которой ожидается что она влияет на целую кучу мест (неявным образом). Например, если у вас есть компонент, который генерирует коды EAN13 (с контрольной цифрой) — то затестить через юниты правильность генерации и проверки контрольной цифры — сам бог велел. Потому что вы это будете явно и неявно сто раз переиспользовать. А компонент, который вызывается явным образом в одной юзер-стори и один раз — так и тестировать тогда интеграционным тестом по этой самой стори…

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

Попробую на примере. Вот есть у вас скажем список чего-то, и есть снизу кнопка "добавить запись". И есть кнопки "удалить" на панели каждого элемента списка. Типичный такой TODO, только ещё проще. В итоге у нас:


  1. есть презентационные компоненты: Item, List, AddButton. Они с JSX, т.е. там внутри есть XML. Они на входе попросят данные для отображения и 2 функции: для удаления и для добавления. Им "не интересно" ни откуда данные пришли, ни что это за функции. Они просто внутри своего XML пропишут onClick={this.props.add}, аналог data-bind="click: add".
  2. у нас есть state. Это древо всех данных приложения. И в нём есть тот самый список. Данные просто данные, т.е. сериализуемые. Никаких функций, хитрых геттеров и сеттеров. Нет, просто тупо данные.
  3. у нас есть action-ы (опустим для простоты actionCreator-ы). Это такие простые объекты типа { type: 'ADD_NEW_ITEM' } & { type 'DEL_ITEM', idx: 12 }. Они сами на данные не влияют. Они просто объекты. Они высказывают намерения. Или как это сказать… Это что-то вроде "эй store, держи мой ADD_NEW_ITEM. обработай его как надо". Причём о store они не знают. Это просто тупо сериализуемые объекты-намерения. Их можно подготовить, к примеру, но не использовать. Просто объекты.
  4. у нас есть reducer-ы. Это чистые функции, которые возьмут старый store, посмотрят на переданный туда action и сделают новый store, но уже с запрошенными изменениями. Вот тут как раз вся бизнес логика по изменению данных приложения. Тут не только JSX нет и в помине, тут вообще весь код… своеобразный. Иммутабельность же.
  5. у нас есть container-компоненты. Они имеют связь со store. По сути store это ko.observable. И container-компоненты на него subscribe-ны. Если store меняется, то они получают новые данные store из него. Их задача — получить данные из store, выдрать из них только то, что нужно конкретно взятому компоненту из пункта 1, и подготовить все эти add и delItem методы для него же. Эти add и delItem-ы опять же, будут просто толкать в store (в его reducer) все те action-ы из пункта 3. Т.е. и тут бизнес логики практически нуль. Подготовив все эти данные container-компонент передаёт их своему приемнику, т.е. презентационному компоненту.

Наверное сильно запутал. Ну там всё не настолько просто, чтобы в паре предложений описать. В общем суть — нет в больших React приложениях никакого нагромождения XML внутри JS, так, чтобы бизнес-логика и вьюхи были рядом. Ещё суть — если вы бросите knockout и возьмёте стандартную связку react + redux, то последнее, что станет для вас проблемой, это этот несчастный JSX. Мат трёхэтажный у вас будет стоять от огромного количества бойлерплейта (мне кажется порой раз в 15 больше суеты чем в knockout-е), и вырвиглазной (имхо) работы с immutable значениями (ну не haskell у нас, не haskell, как умеем, как могём). А когда что-нибудь начнёт тормозить, то пойдут и нормализация данных в store, и selector-ы (мемоизированные функции) и прочая чертовщина. В общем прямолинейный в knockout.js js-код будет разбросан по десяткам файлов и вообще даже близко не будет напоминать обычное словесное описание того, что вам нужно. Тут конвеерная несколькозвенная обработка изменения иммутабельного состояния. Никаких больше: this.list.add(newItem). Теперь это будет через карусель: actionCreator -> action -> reducer -> mapStateToProps -> view.


Из плюшек же: всё работает очень предсказуемо и отслеживаемо. Вот прямо до предела. Вплоть до того, что можно перезагружать страницу целиком и на экране ничего не поменяется, т.к. данные в store те же (скажем localStorage) и всё остальное лишь чистые функции по работе с ними. Тестируется опять же на раз два.


У меня бывало уходили часы работы на поиск хитрого бага в сложном knockout приложении (3-4 года работы в одно рыло, большая кодовая база, много legacy). Потому что stack-трейсы для асинхронных observable бесполезны. А если там 1 computed зависит от 2-го, а 2-й от 3-го и они ещё разных типов, то во-первых — это всё работает непредсказуемо и ну очень непонятно. Последовательность пересчёта всего этого клубка (а knockout располагает к сложным клубкам) может быть разной в зависимости от нюансов. Сами эти связи могут быть совершенно не очевидными, стоит только отвлечься и забыть контекст. Никогда нельзя сказать, что вот тут у нас сложный баг, давайте просто посмотрим что от чего зависит… потому что это может быть ну очень непросто и в каждом модуле устроено по своему. Вспоминаю сейчас и испарина на лбу.


Поработав 1 год на redux+react и 3 на knockout, я бы для больших проектов выбирал react+redux, т.к. такой проект спустя годы будет иметь меньше технических долгов и куда проще поддерживаться. А vue (вместо knockout)-а для мелких и средних проектов, чтобы не утонуть в этом бойлерплейте.


Всё вышеописанное лишь моё ИМХО. Никому свою точку зрения не навязываю )

Вот на прошлой неделе мне понадобились push-уведомления в браузере. Нагуглил несколько статей...

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

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

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

Возможно, это не плагин, а сам фаерфокс. Он по умолчанию список всех открытых вкладок сохраняет в бекап на жесткий диск. И делает это каждые несколько секунд. browser.sessionstore.interval в about:config (в миллисекундах).

UFO landed and left these words here

Вчера получил первую дозу с чипом от Pfizer. Прежде чем продолжить, надо сказать три вещи:
1) Я болел британским штаммом covid в средне-тяжёлой форме в январе, антител в итоге было и есть столько, что мне терапевт в шутку предлагала вакцинировать моей кровью людей) Болел весело, 6 дней с гонками 37-40 градусов подряд, пневмония 25% двухсторонняя, но сатурация ниже 97 не падала. В целом EPIC WIN на фоне других переболевших с такой же тяжестью.
2) Супруга и её сестра не болели, но чипировались Спутником. У супруги через 12 часов после каждой из доз начинался день с температурой как у меня при болезни, но только на день. И то во второй раз было уже попроще. У её сестры после первой дозы была только слабость, а после второй - тоже день с высокой температурой.
3) Я сейчас в Кракове, а потому видал я ваш Спутник, когда есть признаваемые ЕС вакцины)) (если что, тут надо смеяться)

Это было интро, теперь вернёмся ко мне. Я, памятуя, как дерьмово мне было в новый год и как трясло жену, основательно подготовился: купил градусник, парацетамол и ибупрофен. Встречать побочку был готов с хлебом-солью и вступлением из фильма "Кровь и бетон".

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

Вакцинируйтесь, пока не прилетело. Сейчас везде орудует дельта, там мало не покажется, а уж особенно если вы живёте в банановых постсоветских княжествах. Лично я на Спутник не смотрел по двум причинам:
- Есть мнение, что до полугода после болезни лучше не чипироваться, но проверить это мнение у меня не было возможности.
- Я знал, что перееду в Польшу, а там чипируйся - хоть тресни, на выбор Pfizer, Moderna, Johnson & Johnson и AstraZeneca. При этом Спутник ничем не поможет тут, один фиг его тут признают.

Клеточное мясо… А что, мне нравится! Звучит маркетингово привлекательно. Красивое название для… продукта… изделия… переработки… из фекальных вод сылка.

2030 год??? Будущее уже наступило: обычные бургеры не подкачали №1 №2

Чем больше масс будут питаться 'клеточным' ''мясом'' и таблетками, тем больше останется привычной еды людям.… если не начнётся движение 'еда масс тоже важна' и весёлые парады добровольного принудительного кормления.
В бастионную эпоху? Ушло уже их время. Когда есть мортиры — зачем требюше?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity