Следующим этапом будет подключение этого реестра в цепочку ci\cd, чтобы сборки сами сохраняли в него артефакты и оттуда же их брали для тестирования. А потом можно будет оттуда же и деплоиться :) Тогда мало того что у вас локально у всей команды будут одни и те же образы (которые регулярно обновляются в реестре), так у вас еще и на проде будут те же самые образы, что даст вам еще больше уверенности при отладке — если что-то идет не так, вы просто выкачиваете из реестра образ и дебажите конкретный образ, это супер-удобно
Технические метрики для микросервисов мы собираем глобально двух типов — инфраструктурные (la приложения, базы, состояние подов k8) и данные из работающего приложения (например длину очереди задач, внутренние счетчики ошибок\событий). Для бизнес метрик используем в основном данные из приложения — как пример мы чаще всего смотрим сколько времени занимают те или иные задачи в микросервисе (нам важны такие SLA, т.к. есть вполне конкретные юридические ограничения на время проведения некоторых финансовых операций).
В проектах, написанных на PHP, помощью lamoda/metrics мы формируем отчеты либо в режиме on demand (т.е. пересчитываем каждый раз, когда скрейпер приходит забирать отчет), либо в фоновом режиме (тогда отдаем последний отчет скрейперу каждый раз).
Отчеты формируем в родном формате prometheus (раньше использовали telegraf httpjson, поэтому в либе есть и этот формат).
Дальше уже просто работаем с прометеусом как с источником данных в различных системах (grafana, icinga).
Параллельно с этим используем (особенно для метрик связанных с фактами вида «что-то произошло») обычное логгирование
Для меня есть один валидный повод тестить с использованием рефлексии — это если тестируемый код работает с использованием рефлексии. Например какие-нибудь хитрые дата-мапперы или десериалайзеры, которые устанавливают значения напрямую в проперти. В этом случае вполне валидно подсмотреть рефлексией, что там установлено
Если вам важно именно проверить, что сущности сохранились в БД, то никакие моки не нужно использовать по определению, только «живую» БД. Если вам важно проверить, что вызывается метод сохранения, то в целом неважно, у какого замоканного интерфейса она вызывается — у EM или доменного репозитория.
Тесты как уже написали выше, бывают разными, и ничего не мешает иметь несколько видов тестов сразу.
Рискну предположить, что в терминах грамматик под КС подразумевалась группа контекстно-свободных грамматик (то, что идет у вас под перечислением LL/LR/LALR/SLR)
Вы часом не запускаете шторм из toolbox app? В таком случае перезапустить надо еще и его, т.к. по факту родительский процесс получается он (выявлено экспериментальным путем, могу ошибаться в сути объяснения)
Для примера наша команда сидит в уголке на 8 посадочных мест. Размер оного на глаз где-то 6х8м. Сидим по периметру в центре уголка зона, в которой без проблем вся команда размещается на стендап
Неочевидно. Конструктор не является частью контракта Sorter. Я могу использовать другой сортер с другим конструктором. Могу без него. Контракт стабилен.
public function __construct() {
$this->logger = AmbientContext.get(LoggerToken);
}
Вот за такие вещи я и не люблю фреймворки типа Yii. Это же откровенная лапша в коде. Если в контексте не будет этого токена, то весь код, особенно клиентские библиотеки, которые еще не обновились и почему то тоже его хотят — просто развалится. IoC с DI контейнером как раз таки позволяют вам вертеть зависимостями как вам угодно.
Ну да, ну да, один файл с одним классом с 10 методами, нужными лишь одному из них, разбить на десять файлов с десятью классами по методу в каждом — архитектура офигеть как улучшится
Ну, можно вообще отказаться от классов и сложить все функции в один файл с общей областью видимости памятью. Где-то я уже это видел, кажется это используется в процедурном программировании.
Если вашим методы можно разложить по отдельным классам и эти классы не будут друг с другом связаны ничем, кроме аргументов конструктора (которые были в оригинальном классе), то да, архитектура улучшится сильно. Как минимум это говорит о том, что не было никакого комбинаторного взрыва и есть вполне конкретные 10 юзкейсов из всего взрыва, которые надо было обрабатывать.
Я бы лучше послушал про случаи, когда всем потребителям нужен один и тот же интерфейс
Либо вы предлагаете мне показать вам GodObject, либо я не понял вашего вопроса.
В результате контракт «сортировщика» внезапно начинает требовать на вход не только массив, но и «логгер»
Не очень понимаю, откуда, например, в такой иерархии
interface Sorter { public function sort(array $array): array }
class MegaSorter implements Sorter
{
public function __construct(LoggerInterface $logger) {...}
public function sort(array $array): array {...}
}
появился в контракте логгер. В тестах вещей, зависящих от SorterInterface я этого никогда не увижу, потому что контракт остался простым.
Ну вот представьте, у вас есть один публичный метод и 10 приватных. Через «публичный» интерфейс тестировать — комбинаторный взрыв.
Если у вас до 10 приватных методов можно добраться разными комбинациями через комбинаторный взрыв, то это немножечко пахнет нарушением SRP
Через REST — одно, прикладному коду — другое, сериализатору — третее, менеджеру памяти — четвёртое, тестам — пятое, соседним классам в пакете — шестое, соседним пакетам в скоупе — седьмое
Ну тут можно подумать насчет того, что есть ISP. Но вообще опять попахивает нарушением SRP. На примере того же сортировщика можете продемонстрировать, когда такое нужно?
Как вы протестируете, что, например, реализовали qsort правильно
Ключевым вопросом будет постановка термина «реализовали правильно». Приватной функции может и не быть вообще, как вы в таком случае проведете ваш тест?
В общем случае выглядит так, что поддерживать такие тесты дорого и сложность их эквивалентна сложности тестируемого кода.
А что не так с третьим пунктом, конкретно с нежеланием тестировать приватные методы? Ваши тесты не должны меняться, если вы приватную функцию отрефакторите в две (и соответствующим образом модифицируете вызовы), в этом как бы суть сокрытия этой логи, на то она и приватная
Так это не проблема формы, это проблема моделей у которых есть сеттеры. Если у модели есть сеттеры — ей по определению (задумке, факту, хз) можно вертеть как угодно, что и используется в формах по умолчанию, т.к. это самый распространенный (к сожалению) кейс.
Если убрать у сущности сеттеры, то выглядеть уже будет корректно, в этом случае форма сама будет выступать как DTO + трансформер, который правильным образом переложит данные (вызвав нужные методы в нужном порядке) в модель
С другой стороны Symfony Forms не оперируют чистыми полями сущности, она работает через публичные методы, а это значит, что имея корректную DDD сущность без сеттеров (а с бизнес-логичными методами) вы не сможете привести ее в невалидное состояние формой и проблема исчезает. Но там становится сильно сложней конфигурация самой формы в таком случае, надо навешивать на нее дата мапперы, события и прочие радости жизни
В проектах, написанных на PHP, помощью lamoda/metrics мы формируем отчеты либо в режиме on demand (т.е. пересчитываем каждый раз, когда скрейпер приходит забирать отчет), либо в фоновом режиме (тогда отдаем последний отчет скрейперу каждый раз).
Отчеты формируем в родном формате prometheus (раньше использовали telegraf httpjson, поэтому в либе есть и этот формат).
Дальше уже просто работаем с прометеусом как с источником данных в различных системах (grafana, icinga).
Параллельно с этим используем (особенно для метрик связанных с фактами вида «что-то произошло») обычное логгирование
Тесты как уже написали выше, бывают разными, и ничего не мешает иметь несколько видов тестов сразу.
Для примера наша команда сидит в уголке на 8 посадочных мест. Размер оного на глаз где-то 6х8м. Сидим по периметру в центре уголка зона, в которой без проблем вся команда размещается на стендап
Неочевидно. Конструктор не является частью контракта Sorter. Я могу использовать другой сортер с другим конструктором. Могу без него. Контракт стабилен.
Вот за такие вещи я и не люблю фреймворки типа Yii. Это же откровенная лапша в коде. Если в контексте не будет этого токена, то весь код, особенно клиентские библиотеки, которые еще не обновились и почему то тоже его хотят — просто развалится. IoC с DI контейнером как раз таки позволяют вам вертеть зависимостями как вам угодно.
Ну, можно вообще отказаться от классов и сложить все функции в один файл с общей
областью видимостипамятью. Где-то я уже это видел, кажется это используется в процедурном программировании.Если вашим методы можно разложить по отдельным классам и эти классы не будут друг с другом связаны ничем, кроме аргументов конструктора (которые были в оригинальном классе), то да, архитектура улучшится сильно. Как минимум это говорит о том, что не было никакого комбинаторного взрыва и есть вполне конкретные 10 юзкейсов из всего взрыва, которые надо было обрабатывать.
Либо вы предлагаете мне показать вам GodObject, либо я не понял вашего вопроса.
Не очень понимаю, откуда, например, в такой иерархии
появился в контракте логгер. В тестах вещей, зависящих от SorterInterface я этого никогда не увижу, потому что контракт остался простым.
Если у вас до 10 приватных методов можно добраться разными комбинациями через комбинаторный взрыв, то это немножечко пахнет нарушением SRP
Ну тут можно подумать насчет того, что есть ISP. Но вообще опять попахивает нарушением SRP. На примере того же сортировщика можете продемонстрировать, когда такое нужно?
Никогда не следовали, но вот начали? У них же свой семвер был, где первая цифра была маркетинговой
habr.com/post/349408/#comment_10676970
Ключевым вопросом будет постановка термина «реализовали правильно». Приватной функции может и не быть вообще, как вы в таком случае проведете ваш тест?
В общем случае выглядит так, что поддерживать такие тесты дорого и сложность их эквивалентна сложности тестируемого кода.
github.com/symfony/symfony-docs/issues/8893
Хотя в действительности это не так обязательно, можно поменять дата маппер. Тянет на issue и PR
Если убрать у сущности сеттеры, то выглядеть уже будет корректно, в этом случае форма сама будет выступать как DTO + трансформер, который правильным образом переложит данные (вызвав нужные методы в нужном порядке) в модель
В частности вот слайды (возможно надо поскроллить анимацию)
ocramius.github.io/doctrine-best-practices/#/51
ocramius.github.io/doctrine-best-practices/#/56
С другой стороны Symfony Forms не оперируют чистыми полями сущности, она работает через публичные методы, а это значит, что имея корректную DDD сущность без сеттеров (а с бизнес-логичными методами) вы не сможете привести ее в невалидное состояние формой и проблема исчезает. Но там становится сильно сложней конфигурация самой формы в таком случае, надо навешивать на нее дата мапперы, события и прочие радости жизни
Вот пример, как работать с VO через формы
webmozart.io/blog/2015/09/09/value-objects-in-symfony-forms
symfony.com/doc/current/routing/custom_route_loader.html