Pull to refresh
0
0
Alexznadr @Alexznadr

User

Send message
Да. Всё верно.
Но просто дело в том что в вашем случае это не ЮНИТ-тесты.
Плохо спроектированные системы не поддаются модульному тестированию. Автотесты которые при определённых усилиях можно для таких систем написать — как правило большие, сложные (сложность часто сравнима с тестируемой подсистемой) и очень хрупкие. Они долго пишутся, часто исправляются.
Это может называться функциональными или интеграционными тестами в зависимости от масштаба бедствия. но никак не модульными.
юнит-тест является автотестом. обратное верно не всегда. И распространение материалов в которых автотесты «вообще» названы модульными — формирует неправильное представление у наших с вами коллег вообще (и связаных с php в частности) и в конечном итоге способствует увеличению числа проектов вроде того в котором оказались вы.

Кстати — не думали о смене места работы?
Учиться новому и перенимать лучше практики — луче же чем исправлять чужие ошибки. Тем более что такая работа часто бывает невидна и непонятна «обычным людям» (читай представителям бизнеса)
Вот так вот и плодятся массовые заблуждения относительно юнитетестов, из которых потом вырастает убежденность что модульное тестирование это «долго и дорого».

Контролллер -> Фасад -> микс из доменных объектов и сервисов -> Репозиторий/ДАО ->реляционнаясубд/key-value хранилище/in-memory/ file/etc

Так вот юниттест пишется Для! интерфейса! вашего хранилища/dao. Он независим от вашей реализации и работает всегда одинаково. (И когда вы смените реализацию — поможет убедиться что ничего не поменялось) Почти все тесты для него пишут так же как в младших классах нас учили проверять результаты вычислений: результат умножения проверяется делением, сложения — вычитанием. Ну или чуть более формально: f^-1(f(A))==A

Для тестирования «другой» стороны — используются разного рода «пустышки».
И всё. Никаких БД. (если конечно это МОДУЛЬНОЕ тестирование)
Стекло конечно хорошо, но я с нетерпением жду краску которая может менять свой «цвет».
Как здорово — окрасил ей квартиру и можно менять «рисунок» обоев хоть каждую неделю (женщины порадуются).
Лак для ногтей
декор автомобиля (всякие там тигры-драконыстрииитрейсеры-волки)
и ещё 1001 идея для райского потреблядства

ну а то что показано — большей частью технологически было достижимо уже значительное время — и главный вопрос — был вопрос массовости и наличия инфраструктуры.
+Есть шанс что в кейсе «вывести бабушку на поверхность холодильника и разговаривать с холодильником» неявным образом заключен фейл кейса прародителя: «использование телефонов для видеозвонков» технологически возможность есть уже значительное время, но по каким-то социально-психологическим причинам явление не стало массовым (видеозвонки в skype это немного другой контекст) вопреки фантастам и футуристическим роликам.
«Кроме того, этот подход (вертикальное масштабирование) не требует никаких доработок приложения.»
Строго говоря это не всегда так. Хорошо вертикально масштабируются только или компоненты в которых нет конкурентного доступа к разделяемым ресурсам (типа нитей выполнения php/perl/вашлюбимыйсерверныйязык) либо достаточно простые вещи.
Сложные части вроде СУБД могут плохо масштабироваться вертикально. Особенно если преобладает write-нагрузка. Увеличение количества ядер и памяти сервера с некоторого момента не оказывает влияния.
И гораздо разумней этот многоядерный многогигабайтный сервер нарезать на виртуальные машинки по 2-4 ядра (в зависимости от того что туда хотите ставить) и делать необходимые доработки в архитектуре для переходя к горизонтальному масштабированию (пусть и внутри пока одного физического сервера)

Ещё в копилку ключевых слов:
Механизм с поднятием нескольких экземпляров одной базы на разных серверах, master/slave репликацией и распределением операций записи на master, чтений на slave'ы — называется read/write split — и работает опять же только если у нас преобладает read-нагрузка. И имеет очевидное ограничение до которого так можно масштабироваться — количество запросов на изменение данных которое может переварить 1 сервер.
Стремление внедрять шаблоны это хорошо, главное понимать их правильно ( не как большинство понимает MVC).
Так вот:
«Возможен еще вариант обработки и последующей передачи. „
Это не “возможен» — это главный мотив использовать этот шаблон. Если у вас нет необходимости совместной обработки несколькими обработчиками приходящего сообщения — то его применение проигрывает простому Map [Тип сообщения] -> [Экземпляр класса с интерфейсом обработчика] как по понятности/количеству кода, так и по скорости работы (обычно не так важно)

Дисклеймер:
1)я не видел ни одного серьезного проекта где было бы использована разработка по контракту.
2)мне неизвестно об исследованиях в которых бы говорилось, что «мы внедрили „контракты“ и количество ошибок выходящих в продакшен уменьшилось на столько-то (много), а время разрботки увеличилось на мало/уменьшилось». Если у кого-то есть такая информация — это очень интересно.
Всё написанное лишь мысли на заданную тему, опирающиеся на прочитанные мной статьи на эту тему.

насколько я понимаю контракт класса помогает обнаруживать, что кто-то из клиентских классов его не соблюдает, при этом не кодируя бесконечные одинаковые if. Очевидно что такое знание полезно на этапе разработки, так как облегчает локализацию нарушения контракта и практически бесполезно в продакшене: если один из компонентов нарушает контракт, значит он работает неправильно. Даже если выбросить исключение — возможность восстановления после него выглядит сомнительной и бессмысленной. Поэтому, в частности, assert'ы в Java можно включать и выключать.
Так же — теоретически может существовать возможность автоматической трансляции ограничений записанных например на языке OCL (причём как прмитивных вроде что фамилия человека не может быть null, так и высокоуровневых бизнес-ограничений вроде того, что гражданина нельзя призвать в армию, если он проходил службу в вооруженных силах иностранного государства) в моделях UML.

Но есть во всей это теории скользкий момент.
Если контракт dev-time only то что делать когда в продакшен утечет компонент нарушающий контракт — очевидно что приведёт к нарушению согласованности/целостности данных. Значит всё-равно приходится кодировать проверки самому. Лишний труд + Дублирование знаний.Ничего не выиграли.
Если контракт и production-time, то возникает другой вопрос — чем он лучше чем запись условий и инвариантов в коде? Да иногда бывает меньше символов, но у записи контрактов в виде разного рода аннотаций есть тот недостаток что все параметры-строки. Значит нет автокомплита, нет поддержки рефаткоринга. IDE ==> блокнот. Так что тоже — сомнительный выигрыш.

Чашу весов в сторону контрактов могла бы склонить автогенерация и какая-то автообработка — но как я писал — я о таком не слышал.

Возможно поэтому программирование по контракту, появившись ещё во времена оны пока не стало популярной практикой.

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

Например есть у вас вебприложение которое, якобы, построено в соответсвии с модным ныне buzz-word MVC.
У вас есть контроллер, который который подготавливает данные пользователя, передаёт эти данные Модели (сервису) в качесвте аргумента/тов. Внутри Модели происходят некоторые действия в соответсвии с бизнесс-логикой, результаты которых «обычно» сохранянются (DAO/Repository).
Так вот — в этой схеме использование «программирования по контракту» и автосредств проверки соглашений позволит не писать в каждом слое тривиальные проверки вроде «Фамилия != null», а вынести их все например в контроллер а дальше считать, что если данные переданы — то они соответсвуют соглашениям. Соответсвенно если есть этап тестирования и кто-то где-то забыл проверить данные и передаёт обработку дальше данные анрушающие контракт — это всё тут же проявится. Причём в том месте где произошёл нарушающий контракт вызов, а не как обычно — на 20-30 уровней глубже гдето выпадает NullPointerException.

Всё это имеет смысл только в разработке. В продакшене толку от контрактов немного — если в системе появились данные нарушающие контракт — возможность восттановления после такой ошибки вызывает сильные сомнения.

Другой вариант — описывать с помощью контрактов бизнесс-ограничения. Тогда ограничения становятся одной из составляющих кода (должны быть и в продакшене). В этом случае использование аннотаций имеет смысл только если есть возможность автоматически генерировать их например из выражений OCL на UML диаграмме (я не исключаю такой возможности, но незнаю/не слышал о таком). Если же автогенерации нет — то мы ничего не выгрываем по сравнению с написанием кода методов выполняющего те же проверки.
Хм… по тексту у меня сложилось ощущение что классы сущностей отображаются на интерфейсы и обратно без изменений? (Person IPerson)
Если это так — то возможнбудет удобней Person Implements IPerson? тогда можно использовать extract interface/superclass + pull up methods. Пустячек а удобно. + шажок к ортодоксальному ООП)

И ещё — почему вы всёже не остановились на DTO(как упоминалось выше подмножество полей сущности/сущностей в зависимости от задачи)? Ведь если в Person есть связь многие- ко-многим — то прямая проекция создаст дополнительную (возможно значительную) нагрузках даже на простых операциях. Хотя с другой стороны прямая проекция + прокси может быть просто «частным случаем» традиционной кухни с DTO.
Отличные новости. Глядишь — к следующему хайлоаду всё и выложите.
Похоже TDD становится новой мантрой разработки. Как например MVC до этого. Толпы людей повторяют MVC как заклинание, продолжая псиать огромные тонны логики в контроллере. Это не мешает им рассуждать о многослойной архитектуре и дискутировать на тему необходимости скорейшего введения примесей в php/java/etc

Тоже самое, похоже, начинает происходить с TDD.
Сам TDD — это не панацея ниразу. Люди которые писали толстые контролллеры — начнут писать к этим контроллерам тесты (которые почему-то будут называть «юниттестами»). Тесты будут такими же толстыми и сложными как сами контроллеры. Для работы тестов понадобится сложное окружение. В итоге — огромные потери времени. Которые чаще всего заканчиваются тем, что принимается решение отказаться от автотестов.

Тесты (покрытие тестами) — это хорошо, но на мой взгляд, гораздо важней чтобы архитектура проекта была пригодной для тестирования.
Зачастую это означает широкое использование DI, по возможности минимизация использования синглтонов. Так же бывает полезным разумное использование закона Деметра. Благодаря этому связность компонент падает. Сами компаненты становятся проще и можно легко и безболезненной писать простые и короткие тесты (юниттесты). (Дополнительный бонус — если проводить хотья бы немного упреждающее проектирование в интерфейсах — это позволит более эффективно распределять работу в том числе и на новых/временных участников команды).
Вобщем: если тесты пишутся тяжело и на них тратится много времени — верный знак того что в архитектуре у нас всё очень плохо.

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

P.S. Замечание о том что команды которые практиковали TDD быстрей адаптировались к изменениям, чем команды которые его не использовали — слабый аргумент в пользу фанатичного следования TDD. Адаптивность стала результатом, того что у команды с TDD была архитектура которая допускала юниттесты (см выше). Но — архитектура пригодная для юнитестирвоания может быть и вообще без юниттестов. Так что думаю TDD не является причиной адаптивности. Напротив — успешное использование TDD как и адаптивность к изменениям требований — являются следствием заложенной архитектуры.

P.P.S Фанатичное следование чему-либо — плохо)
Понимаю, что вопрос скорей всего в пустоту (вряд ли этот пост будет просматривать человек который является специалистом и в java и в python), но всё же: за счёт чего stackless python может выиграть в производительности у sun/oracle JVM ну и я зыка JAVA?
Событийная работа с сокетами? есть NIO + библиотеки поверх них типа netty/MINA
Тасклеты и однопоточный планировщик, который который переключает тасклеты при блокировки? Ну так и в JVM — зеленые потоки и планировщик. нить заблокирована — управление передано другой нити. Так что на однопроцессорной однаядернйо машине — выполняется только один поток.
на многоядерной — можно привязать к определённому ядру. Чтобы ибежать кеша потока на общих данных использовать volitile.
Где выигрыш?
Не могли бы вы объяснить чем решение Varnish+Nginx+Apache + mod_php лучше чем Nginx+fast_cgi php

LoadImpact.com ломится «незарегистрированными» пользователями. Сайт на друпале благодаря всей описанной выше кухне с помощью кеширования выраждается в раздачу статики. Зачем тогда городить огород — nginx прекрасно сам закеширует ответ fastcgi и будет на раздаче этого кеша показывать отличное время.

Складывается ощущение, что вы просто услышали где-то, что «Varnish это оч круто», поставили его и он показал какие-то результаты, которыми вы и поспешили поделиться со всеми. Но есть ли прирост по сравнению с правильной (не тонкой, просто «правильной») настройкой nginx. Я, если честно, сильно сомневаюсь.
самопеар такой самопеар

пост ниочём.
Если у Вас 10 человек справляются с работой (именно с работой а не с болтавнёй с налетом креативности) хуже чем 8, то c большой вероятностью:
1)Команда раздута. Людей больше чем работы. Начинается размазывание г… манной каши по тарелке, часто с лишней придумыванием работы (лишь бы всем хватило)
и/или
2)Руководитель не правильно сделал декомпозицию задачи и спланировал работы в следствии чего люди «мешают» друг другу
поделитесь ссылкой)
не переживайте так) если вы проследите «историю» — вы придёте к выводу что это пустой пеар. Косвенно это подтверждается в том числе и содержимым подкаста.
Очень похоже на 100% копипаст www.whitsoftdev.com/opentracker/ с немного расширенным переводом комментариев из кода…
12 ...
13

Information

Rating
Does not participate
Registered
Activity