Здравствуйте, ylem, Вы писали:
Y>Y>...
Y>var combo = view.ActiveEditor as ComboBoxEdit;
Y>Debug.Assert(combo != null, "Column editor supposed to be a ComboBoxEdit");
Y>if (combo == null)
Y> return;
Y>...
Y>
Y>Это совсем @овнокод или нет?
Имхо да. Если пользовательский кейс валидный в релизе, то он должен быть валидным и в тесте. Иначе грош цена вашему тестированию.
Y>А если добавить логи и репорты в релизе?
Имхо если такая проблема возникает в релизе, значит вы все прошляпили на этапе тестирования.
Здравствуйте, Sinix, Вы писали:
S>1. Таки спасибо, интересный спор получился У меня появляется настойчивое подозрение: главная причина спора в том, что ты понимаешь под ассертами что-то большее, чем просто "проверка в коде". Т.е. спор в итоге чисто про терминологию.
Да, про терминологию. Поэтому надо бы отделить мух от котлет. Есть классические ассерты, которые в Плюсах и в прочем майкрософте — которые рисуют диалог с abort/retry, которые нифига толком залоггировать невозможно, которые из релизной сборки вырезаются и т.п. А есть некие нестандартные, самодельные, которые могут и не обладать всеми этими недостатками (а могут обладать другими
). Так что да, проблема не в слове "ассерт", а в наиболее распространённых реализациях.
S>·>Так ассерт не может в принципе "гарантировать, что ни одно из них не передаёт, скажем, 42". Он будет лишь что-то (не)делать, если 42 таки передалось.
S>Может-может. Достаточно покрыть тестами основные сценарии использования и можно с относительной уверенностью говорить, что критичной для нашего кода ошибки нет.
Но вот я не понимаю — почему как покрывать тестами, так "досаточно основные сценарии", а вот ассертами покрываем всё остальное? Почему тестами бы не покрыть то, что ты собрался покрыть ассертами?
S>Даже если ошибка и вылезет, скажем, у одного из клиентов, то оставленный в коде ассерт сразу её отловит и сообщит куданадо (с помошью клиента или автоматом — это уже детали реализации). В ближайшем патче ошибку исправят.
S>Сам понимаешь, при таком раскладе шанс поймать ошибку на порядки (серьёзно на порядки) выше, чем когда возможность ошибки проверяется в одном тесте из тысячи.
S>Как дополнительный бонус — у нас значительно вырастает полезность тестов, особенно интеграционных. Они проверяют не только входы-выходы, но и корректность кода в целом.
Это же можно достичь и без ассертов, а, скажем, логированием. Ассерты не являются незаменимыми в данном случае.
S>>>А зачем окошко-то? Ассерты здорового человека просто бросают исключение + дают возможность залогировать сработавшие ассерты.
S>·>А теперь, дети, посмотрите на ассерты майкрософта.
S>Угу, это тяжёлые наркотики, не надо на них смотреть. Я ж говорю — проблема в том, что каждый норовит под ассертом понимать что-то сверх "опционально отключаемая проверка в коде".
Но так это именно то что чаще всего используется, особенно новичками, ведь майкрософт ничего плохого не посоветует же...
S>·>Ну обычно ERROR уровень таки не оставляют незамеченным.
S>Юнит-тестами? Да легко. Кто в них лог проверяет?
А в юнит-тестах ассерты мало помогают. Мы ж white-box тестируем, остальное мочим, и явно видим что может случиться что не может.
S>>>·>Мда, похоже, тут спор частично терминологический. Под ассертами понимаются обычно такие проверки, которые отрубаются в проде. А если это такие проверки, которые работают всегда и везде, кидая исключение, то они ничем неотличимы от обычных проверок типа if(x) throw Exception, кроме, может быть, синтаксиса.
S>>>А, это из плюсов, наверно, в наследство досталось. Глянь тут
S>·>Так там я это и прочёл:
S>А вот не надо выборочно цитировать Выделил:
S>When a program is deployed to production, assertions are typically turned off to avoid any overhead or side effects they may have…
S>Если выделенное не является проблемой для софта — смысл отключать ассерты?
Насчёт оверхеда — согласен, есть такое. Но таких случаев не должно быть сильно много в типичном приложении. С ними можно разобраться персонально.
side effects — ассерты не должны создавть side effects, иначе это тупо баг в коде. Кстати, тоже камень в огород ассертам — они таки могут создавать side effects, а это никак не заэнфорсить, т.е. ещё один источник хитрых багов.
S>>>или тут. Везде основное свойство ассертов — "проверяет ожидания программиста", а не "не работает в релизе".
S>·>А ты сам-то читал?
S>О, снова неполная цитата. Там же дальше написано:
S>S>Normally, you don't want users to see assertion messages
S>...
S>For highly robust code, assert and then handle the error anyway.
S>Что считать robust code — это уже вопрос предпочтений, про сообщать пользователю — это чисто вопрос реализации, насильно спамить никто не заставляет.
Сообщать пользователю — конечно нельзя, только в виде краш-репорта, который он может тупо переслать службе поддержки, в лучшем случае.
S>Мы предпочитаем отслеживать ошибки даже в продакшне, а не пропускать их молча, но это от реальных требований зависит.
Ну! Это значит, что ассерт это, может быть, и хорошо, программисту может быть так нравится... но "handle the error" всё равно должен быть. Т.е. на ассерты надейся, да сам не плошай. Т.е. такой код:
assert x != 42;
use(x).asNothingHappened();
плохой. В robust code (а собственно зачем вообще писать не robust code?) должно быть:
assert x != 42;
if(x == 42) destroyTheEarth();
use(x).asNothingHappened();
Но тогда остаётся резонный вопрос — _нужны_ ли ассерты вообще в таком коде? Ответ: нет, не нужны, это личное предпочтение программиста, дело привычки, вкусовщина.
S>>>Не дешевле было просто ассерт поставить?
S>·>Лучше в DoWork вставить if(!inited) throw Exception.
S>Блин, мы по кругу ходим. Я ж уже спрашивал: чем ассерты от исключений отличаются? Кроме того, что их можно переиспользовать без копипасты и выборочно исключать в критичных для производительности местах?
Ну да, вопрос в терминах. if-throw я не видел чтобы называли ассертами.
S>·>У тебя публичный контракт с тремя методами Init/DoWork/Clear — а соответственно любой пользователь класса может не следовать этому контракту, значит его надо явно проверять. То что у тебя на данный момент в коде нет таких пользователей это тебе не даёт право надеяться на авось — такой плохой пользователь может получиться позже — из-за неудачного рефакторинга или добавления новой функиональности, а в твоём случае такой пользователь был, но был неявный, из-за рефлексии в этом сериализаторе, видимо.
S>Ну да, о чём и речь. Тут никак без ассерта/проверки не обойтись, одни тесты никак не помогут.
Тесты помогут проверить, что DoWork правильно валится при неверном состоянии инициализации объекта.
Здравствуйте, ·, Вы писали:
·>Да, про терминологию. Поэтому надо бы отделить мух от котлет. Есть классические ассерты, которые в Плюсах и в прочем майкрософте — которые рисуют диалог с abort/retry, которые нифига толком залоггировать невозможно, которые из релизной сборки вырезаются и т.п. А есть некие нестандартные, самодельные, которые могут и не обладать всеми этими недостатками (а могут обладать другими ). Так что да, проблема не в слове "ассерт", а в наиболее распространённых реализациях.
А, тогда ой. "стандартные" в топку, да. Иъ вообще никто не использует, по крайней мере в дотнете. Попадаются пару раз на проект максимум, да и то по ошибке.
В остальном в принципе тож согласен. Закругляемся
Здравствуйте, Sinix, Вы писали:
S>А, тогда ой. "стандартные" в топку, да. Иъ вообще никто не использует, по крайней мере в дотнете. Попадаются пару раз на проект максимум, да и то по ошибке.
Стоит заметить, что топикстартер именно такой и использует, видимо он не в числе этих "никто"
S>В остальном в принципе тож согласен. Закругляемся
Здравствуйте, ylem, Вы писали:
Y>Мотив проверять: в реализации "view" кто-то что-то изменить (или оно уже сейчас не всегда работает так, как я предполагаю).
Y>Мотив в релизе не кидать эксэпшн: у пользователя просто не будет работать один контрол но все остальное будет доступно и ничего не потеряется
Только так контролы и пишут. Пользовательский интерфейс — посредник между пользователем и программой, сам по себе он ничего не делает, в случае проблем (с самим собой) — молчит.
Y>А если добавить логи и репорты в релизе?
О том, что какой-то контрол сломался?
Y>Мотив в релизе не кидать эксэпшн: у пользователя просто не будет работать один контрол но все остальное будет доступно и ничего не потеряется
За годы взвешивания таких вот "за и против" пришел к выводу что в конечном итоге лучше для всех — и для разрабов и для пользователей — внятный контракт, т.е. кинуть исключение и поймать как можно раньше такое хотя бы в релизе, чем плодить в коде такие вот "graceful dead"
Здравствуйте, ylem, Вы писали:
Y>Y>...
Y>var combo = view.ActiveEditor as ComboBoxEdit;
Y>Debug.Assert(combo != null, "Column editor supposed to be a ComboBoxEdit");
Y>if (combo == null)
Y> return;
Y>...
Y>
Y>Это совсем @овнокод или нет?
Y>На всякий случай: это не в модели и не в логике, т.е. ничего и не покорруптится, и по-тихому для пользователя не сделается / не несделаеся.
Y>Мотив проверять: в реализации "view" кто-то что-то изменить (или оно уже сейчас не всегда работает так, как я предполагаю).
Y>Мотив в релизе не кидать эксэпшн: у пользователя просто не будет работать один контрол но все остальное будет доступно и ничего не потеряется
Y>А если добавить логи и репорты в релизе?
А почему не сделать invalid контрол, который подсовывать пользователю и репортить ошибку?
Здравствуйте, ylem, Вы писали:
Y>Y>...
Y>var combo = view.ActiveEditor as ComboBoxEdit;
Y>Debug.Assert(combo != null, "Column editor supposed to be a ComboBoxEdit");
Y>if (combo == null)
Y> return;
Y>...
Y>
Пока мужики по соседству напряженно спорят на тему ассертов, хочу заметить, что проблема с этим кодом глубже, чем способ проверки результата.
Зачем вы в прикладном коде используете даункасты?
Y>>Y>>...
Y>>var combo = view.ActiveEditor as ComboBoxEdit;
Y>>Debug.Assert(combo != null, "Column editor supposed to be a ComboBoxEdit");
Y>>if (combo == null)
Y>> return;
Y>>...
Y>>
SAS>Зачем вы в прикладном коде используете даункасты?
Прикладной он несколько условно, т.е. никакой "бизнесс-логики" этот даункаст не представляет.
"view" это некоторая часть дев-экспрессного грида. Когда оно мне досталось, в этом месте уже был этот "даункаст".
Кое что вокруг мне прищлось изменить. Сходу придумать ситуаций, когда даункаст не сработает, ни при старых обстоятельствах ни при новых я придумать не смог.
Память уже не та, но вроде бы это обработчик события, свзяанного с редактирование конкретной колонки, которй назначен конкретный тип едитора. И, если я правильно помню, из обработчика доступа до самой колонки/ячейки нет, поэтому ее едитор получаетяся вот таким способом.
И на всякий случай: это Windows.Forms, не WPF.