Отличный пример багов, маскирующих друг друга! Пожалуй, можно записать в сторону идеи «не смешивать мутации».
Конечно, полное покрытие бессмысленно/невозможно/дорого. Есть подозрение, что десятилетия процессорного времени на «автоматически мутационный брутфорс» не окупятся при такой критичности багов – проще/быстрее/дешевле нанять специально обученных хороших тестеров, которые приложат свои биологические нейронные сети для поиска (-: Но нужно считать, конечно.
Вопрос в воздух: интересно, используют ли такое в авиационном или космическом софте?
> надо ли пробовать пермутацию мутаций
Не нужно, т.к. не имеет смысла – комбинация мутаций провалит те же самые тесты, что и отдельные мутации сами по себе, – они уже помогают резко улучшить качество тестов и приносят профит за копейки (оставить проект проверяться на обед/ночь – не сложно).
Комбинация может найти баги только если если покрытие кода не плотное или невнимательное.
Не понял вопрос про единичные вхождения – поясните? Интересно.
Так как мутация изменяет код, который находится где-то внутри функции, то и unit-тесты (хотя бы один) должны упасть. Если не упали – значит, нет ни одного «внимательного» теста. В любом случае, решение «отрефакторить или нет» всегда точно определено в данном контексте. Или нет?
> замена одного вызова метода класса на другой с похожей сигнатурой
(o.0) Это… заменить `array_map` на `array_filter`? Зачем?
> приходит мутатор и дописывает в конец self.delete_all
А в `cleanup` уже есть `delete_all`? Это ведь уже имеет смысл только в контексте приложения (не языка), а, значит, подобные мутаторы нужно писать самому. Но есть ли в том смысл и резон?
ps: пользуюсь humbug в нескольких проектах, использовать сложные мутации типа «дописать метод» не вижу смысла – время и поддержка тестов не окупятся никогда (имхо).
Бекенд это не только «вью-интерфейс между базой и клиентом». Ради безопасности и избежания дублирования (когда клиентов много), внутри бекенда хранится вся доменная логика, разграничение прав и т.п.
Для проектов, где достаточно crud-like логики и апи есть смысл сделать анемичным – тут GQL выигрывает во всём. Но когда у вас добавляются пользовательские настройки, десяток ролей с разными уровнями доступа, фильтры по всему подряд и какая-нибудь god-like-табличка у пользователя с хитрыми формулами расчёта и тому подобным – любой endpoint, способный возвращать что угодно клиенту становится самым узким местом как в логике, так и в производительности.
Упомянутые выше RESTful + JsonData отлично справляются с задачами «не дублировать данные» и «дать свободу клиенту выбирать какие связанные данные нужны в ответе, а какие нет», при этом не ограничивая бекенд-разработчика и позволяя ему, например, оптимизировать дорогой запрос руками.
В случае же оптимизации GQL приходится с клиентами устанавливать негласные соглашения об ограничениях запросов в духе «да, ты можешь делать так, но это будет на порядок дольше чем вот так», – что, даже в случае наличия документации, не очевидно и не поддерживаемо.
Я, как бекендер, с удовольствием перейду на GQL когда (если!) появится вменяемая реализация, позволяющая решить проблемы выше (доступ, оптимизация). Для PHP я ни одной такой пока не нашёл, например.
Спасибо за подробный ответ! И за ссылки – пойду искать аналоги для моих платформ (:
Если я правильно понял автора, он предлагает расширить применение метрик до ещё одного слоя тестирования доменной логики и поиска ошибок, которые не найдены тестами. Обычно такие метрики сложнее простого счётчика из одной цифры (Яндекс/Гугл-Метрика на фронте, например) и зависят от кучи параметров многих моделей бизнес-логики одновременно.
Вот об этом было бы интересно почитать, как это организуют более опытные команды ибо я недавно осознал что начал изобретать что-то похожее на DomainEvents с кастомным логированием именно для этих целей.
Перевод не хорош, но «прорекламировал» статью и я её прочитал в оригинале. За то и спасибо.
Но вопроса это таки не отменяет. В статье пример с открытием/закрытием [десктопного?] приложения.
Так как я этим методом со счётчиками никогда не пользовался, то было бы интересно посмотреть как его используют в веб-разработке на серверных частях.
Примеры типа «давайте напишем юнит-тесты на привет-мир или калькулятор» не помогают пониманию.
Спасибо за перевод!
Кто-нибудь может поподробнее пояснить раздел «Оснащение и журналирование»? Какие-то статьи на тему, примеры или ключевые слова для запроса в поиск?
Звучит, вроде, логично, но всё ещё не понятно как это работает.
Описанная в статье сложность дублирования решается (на примере Symfony) расширением:
В `config.yml` можно указать значения по умолчанию, а в более конкретных `config_*.yml` импортировать глобальный конфиг (`imports: [resource: config.yml]`) и только переопределять его значения.
Выходит более читабельно и компактно, чем то что в статье.
> А чтобы написать код, нужен или человек, или ИИ.
В идеальном случае, достаточно интерфейса/контрактов. Пример из мира PHP – puli/discovery/httplug, «который сам находит адаптеры» – достаточно сделать composer require. Это позволит использовать человека только на этапе написания кода поставщика сервиса.
Но тогда нужно стандартизировать интерфейсы для каждой «категории» апи, что мне не кажется реальным (см. картинку xkcd) для всего подряд.
Для чего вообще может быть нужно держать в паблик-директории сервера весь проект и иметь извне доступ к чему-либо кроме public/web/...?
В моём опыте этого не нужно было никогда делать, но, судя по посту, такое иногда делают (пусть даже закрыв git/svn). В каких случаях?
Я, например, жду и буду настойчиво рад когда в языке всё-таки будет определён этот сахар. Многие вещи проще сделать через анонимные функции (лениво впилить ленивость, например).
И дело не в том, что писать на сколько-то символов больше (автокомплит IDE нивелирует), а в том, что текущий синтаксис сильно «шумит» – у меня бывает, что «накладные символы» по длине такие же как полезное действие в функции, – такое сложно распарсить глазами и понять.
Да и IDE обычно фолдит такие вещи – приходится кликать в однострочники чтобы посмотреть что они делают что-то похожее на array_column, только для объектов или считают среднее арифметическое по аттрибуту из коллекции. С коротким синтаксисом это распознаётся глазом гораздо быстрее. По крайней мере, лично моим – точно быстрее.
Позволю себе смело заявить, что у вас зелёная зона указана неверно – нижний правый угол должен быть указан как недостижимый в той же степени что и верхний-левый.
Соответсвенно, если надо повысить достижимость одной рукой, то панель надо переместить не вниз, а вправо. Причём, внизу – информационная часть (крошки или заголовок), а сверху – интерактивная (бургер, поиск).
И это только для типичных невысоких правшей. 5+ дюймовые телефоны мне уже неудобно держать и тянуться в панель на любой стороне дисплея.
> Внезапно я обнаружил, что на новом сайте, который у меня сейчас в разработке на локалхосте, дублируются INSERT запросы к БД. Отправляю один комментарий через форму, а в базу вставляются два.
Реквестирую подробности рассказа о том как комментарии в базу вставляются по GET-запросу да ещё и без дополнительных данных.
А вообще, нагрузку увеличить Хром и правда может не только как тут в комментах уже писали о user-friendly 404, но и при наборе в адресной строке конкретного адреса: prefetch-логика шлёт два GET-запроса, что дважды загружает страницу, инкрементирует дважды счётчики, даже может сбросить выделение непрочитанных данных в некоторых случаях.
Конкретное соглашение? Автор писал про гайды по комментам в гите (в т.ч. по эмодзи, вот тут https://github.com/atom/atom/blob/master/CONTRIBUTING.md#git-commit-messages) – тогда цепочка сокращается до «картинка –> понятно о чём коммит –> не читать текст пока не нужны детали». Как аналог текстовых тегов "[DOC] Update docs about adding new customer", только легкофильтруемые визуально без чтения. Или выделять только определённые чтобы глаз цеплялся – например, при внесении broken changes.
Интересно как у большинства разработчиков софт это будет поддерживать. Мой iTerm2, например, может и картинки в консоли показывать.
Конечно, полное покрытие бессмысленно/невозможно/дорого. Есть подозрение, что десятилетия процессорного времени на «автоматически мутационный брутфорс» не окупятся при такой критичности багов – проще/быстрее/дешевле нанять специально обученных хороших тестеров, которые приложат свои биологические нейронные сети для поиска (-: Но нужно считать, конечно.
Вопрос в воздух: интересно, используют ли такое в авиационном или космическом софте?
> надо ли пробовать пермутацию мутаций
Не нужно, т.к. не имеет смысла – комбинация мутаций провалит те же самые тесты, что и отдельные мутации сами по себе, – они уже помогают резко улучшить качество тестов и приносят профит за копейки (оставить проект проверяться на обед/ночь – не сложно).
Комбинация может найти баги только если если покрытие кода не плотное или невнимательное.
Так как мутация изменяет код, который находится где-то внутри функции, то и unit-тесты (хотя бы один) должны упасть. Если не упали – значит, нет ни одного «внимательного» теста. В любом случае, решение «отрефакторить или нет» всегда точно определено в данном контексте. Или нет?
> замена одного вызова метода класса на другой с похожей сигнатурой
(o.0) Это… заменить `array_map` на `array_filter`? Зачем?
> приходит мутатор и дописывает в конец self.delete_all
А в `cleanup` уже есть `delete_all`? Это ведь уже имеет смысл только в контексте приложения (не языка), а, значит, подобные мутаторы нужно писать самому. Но есть ли в том смысл и резон?
ps: пользуюсь humbug в нескольких проектах, использовать сложные мутации типа «дописать метод» не вижу смысла – время и поддержка тестов не окупятся никогда (имхо).
Для проектов, где достаточно crud-like логики и апи есть смысл сделать анемичным – тут GQL выигрывает во всём. Но когда у вас добавляются пользовательские настройки, десяток ролей с разными уровнями доступа, фильтры по всему подряд и какая-нибудь god-like-табличка у пользователя с хитрыми формулами расчёта и тому подобным – любой endpoint, способный возвращать что угодно клиенту становится самым узким местом как в логике, так и в производительности.
Упомянутые выше RESTful + JsonData отлично справляются с задачами «не дублировать данные» и «дать свободу клиенту выбирать какие связанные данные нужны в ответе, а какие нет», при этом не ограничивая бекенд-разработчика и позволяя ему, например, оптимизировать дорогой запрос руками.
В случае же оптимизации GQL приходится с клиентами устанавливать негласные соглашения об ограничениях запросов в духе «да, ты можешь делать так, но это будет на порядок дольше чем вот так», – что, даже в случае наличия документации, не очевидно и не поддерживаемо.
Я, как бекендер, с удовольствием перейду на GQL когда (если!) появится вменяемая реализация, позволяющая решить проблемы выше (доступ, оптимизация). Для PHP я ни одной такой пока не нашёл, например.
А есть что-то «про PHP и рядом» в Питере?
Если я правильно понял автора, он предлагает расширить применение метрик до ещё одного слоя тестирования доменной логики и поиска ошибок, которые не найдены тестами. Обычно такие метрики сложнее простого счётчика из одной цифры (Яндекс/Гугл-Метрика на фронте, например) и зависят от кучи параметров многих моделей бизнес-логики одновременно.
Вот об этом было бы интересно почитать, как это организуют более опытные команды ибо я недавно осознал что начал изобретать что-то похожее на DomainEvents с кастомным логированием именно для этих целей.
Но вопроса это таки не отменяет. В статье пример с открытием/закрытием [десктопного?] приложения.
Так как я этим методом со счётчиками никогда не пользовался, то было бы интересно посмотреть как его используют в веб-разработке на серверных частях.
Примеры типа «давайте напишем юнит-тесты на привет-мир или калькулятор» не помогают пониманию.
Кто-нибудь может поподробнее пояснить раздел «Оснащение и журналирование»? Какие-то статьи на тему, примеры или ключевые слова для запроса в поиск?
Звучит, вроде, логично, но всё ещё не понятно как это работает.
Ваш список
database.global.php
development.php
global.php
production.php
services.global.php
читать глазами гораздо сложнее, чем
config.yml
config_dev.yml
config_prod.yml
config_test.yml
Описанная в статье сложность дублирования решается (на примере Symfony) расширением:
В `config.yml` можно указать значения по умолчанию, а в более конкретных `config_*.yml` импортировать глобальный конфиг (`imports: [resource: config.yml]`) и только переопределять его значения.
Выходит более читабельно и компактно, чем то что в статье.
Пример: https://github.com/symfony/symfony-standard/blob/master/app/config/config_dev.yml
В идеальном случае, достаточно интерфейса/контрактов. Пример из мира PHP – puli/discovery/httplug, «который сам находит адаптеры» – достаточно сделать composer require. Это позволит использовать человека только на этапе написания кода поставщика сервиса.
Но тогда нужно стандартизировать интерфейсы для каждой «категории» апи, что мне не кажется реальным (см. картинку xkcd) для всего подряд.
В моём опыте этого не нужно было никогда делать, но, судя по посту, такое иногда делают (пусть даже закрыв git/svn). В каких случаях?
И дело не в том, что писать на сколько-то символов больше (автокомплит IDE нивелирует), а в том, что текущий синтаксис сильно «шумит» – у меня бывает, что «накладные символы» по длине такие же как полезное действие в функции, – такое сложно распарсить глазами и понять.
Да и IDE обычно фолдит такие вещи – приходится кликать в однострочники чтобы посмотреть что они делают что-то похожее на array_column, только для объектов или считают среднее арифметическое по аттрибуту из коллекции. С коротким синтаксисом это распознаётся глазом гораздо быстрее. По крайней мере, лично моим – точно быстрее.
Соответсвенно, если надо повысить достижимость одной рукой, то панель надо переместить не вниз, а вправо. Причём, внизу – информационная часть (крошки или заголовок), а сверху – интерактивная (бургер, поиск).
И это только для типичных невысоких правшей. 5+ дюймовые телефоны мне уже неудобно держать и тянуться в панель на любой стороне дисплея.
Реквестирую подробности рассказа о том как комментарии в базу вставляются по GET-запросу да ещё и без дополнительных данных.
А вообще, нагрузку увеличить Хром и правда может не только как тут в комментах уже писали о user-friendly 404, но и при наборе в адресной строке конкретного адреса: prefetch-логика шлёт два GET-запроса, что дважды загружает страницу, инкрементирует дважды счётчики, даже может сбросить выделение непрочитанных данных в некоторых случаях.
Интересно как у большинства разработчиков софт это будет поддерживать. Мой iTerm2, например, может и картинки в консоли показывать.