Информация об изменениях

Сообщение Re[7]: Совсем отстой? от 10.11.2016 15:08

Изменено 10.11.2016 15:11 Sinix

Здравствуйте, ·, Вы писали:

·>В нормальной ситуации — использовать коллекцию, которая не допускает null-элементы (кидает NRE например, при попытке добавить таковой) — чтобы обнаруживать косяк в момент его возникновения, а не потом когда-нибудь, если повезёт.


Как по мне, подход в стиле "задача не решается легко == косяк в дизайне" годится только для сферического дизайна в вакууме.

В реальной жизни
* ты ограничен существующими коллекциями и интерфейсами. Никто не будет использовать API, для которого нужно завернуть данные в свой особый тип коллекции.
* ты ограничен производительностью. Пришёл, скажем, массив и требование — без аллокаций. Выкручивайся как хочешь.
* ты ограничен ресурсами. Ну ок, задизайнили мы коллекцию, которая не принимает null-ы. И тут оппа — другая задача не принимает коллекций из пустых строк, третья — отрицательных индексов, четвёртая — timespan больше часа и вдруг выясняется, что все четыре — это атрибуты одной сущности (скажем записи из semlog-а) и все приседания с волшебной коллекцией идут лесом. Никто не даст время на такие эксперименты, задачу надо сделать и переходить к следующим.

Что печально, даже появление в шарпе аналога Units of Measure от F# делу не поможет. Куча существующего кода с типами-примитивами никуда не денется, увы.

Так вот, когда пишут код без оглядки на подобные ограничения, вечно получается абсолютно неадаптированное к реальной жизни решение. Не надо так делать


S>>Ошибки "в принципе быть не может" на текущей codebase. Как, к примеру, ловить некорректные значения, возвращённые сторонним кодом?

·>Корректно обрабатывать — кидать исключение, например.
Ну так ассерты именно это и делают. Вся разница — они позволяют переиспользовать проверки без копипасты. Ну, т.е. вернулись к началу: ассерты — фу-фу-фу, просто исключения — ок. Серьёзно?


·>Почему не вариант? Это говорит о том, что ассерт написать проще, чем ютест. А это говорит о том, что ютесты пишутся сложно. А это говорит о том, что код не самого лучшего качества.

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


S>>Или как в нашем случае — чтоб воспроизвести баг, нужно продублировать весь сценарий, т.к. итоговая ошибка вызвана мелкими логическими несостыковками в 3 независимых кусках кода. Ок, воспроизвели, починили, завели тест, всё зелёное. Какие гарантии, что эта же ошибка не воспроизведётся при другой комбинации условий и как этот момент вообще отловить?

·>Я не понял из описания issue взаимосвязь с ассертами. Можно поподробнее?
Очень просто — наш проект упал с ассертом "строка в .csv содержит неэкранированный разделитель, культура Central Kurdish, разделитель списка — ؛". Заметь, что для этого нам не пришлось писать отдельный тест для csv, перебирать все культуры (эта, к примеру, появилась в восьмёрке, пока CI-сервер был на 2012-м — фиг бы поймали), просто прогнали интеграционный тест и он нашёл штуки три похожих ошибки.

Раз такое дело — проверил соседние проекты, нашёлся аналогичный баг в BenchDotNet, в CodeJam тоже поправить надо будет, если попросят произвольные разделители.

·>И как этот код будет работать, если вдруг попадёт на какой-нибудь server side?

Никак. Поэтому все пишут свои ассерты
Re[7]: Совсем отстой?
Здравствуйте, ·, Вы писали:

·>В нормальной ситуации — использовать коллекцию, которая не допускает null-элементы (кидает NRE например, при попытке добавить таковой) — чтобы обнаруживать косяк в момент его возникновения, а не потом когда-нибудь, если повезёт.


Как по мне, подход в стиле "задача не решается легко == косяк в дизайне" годится только для сферического дизайна в вакууме.

В реальной жизни
* ты ограничен существующими коллекциями и интерфейсами. Никто не будет использовать API, для которого нужно завернуть данные в свой особый тип коллекции.
* ты ограничен производительностью. Пришёл, скажем, массив и требование — без аллокаций. Выкручивайся как хочешь.
* ты ограничен ресурсами. Ну ок, задизайнили мы коллекцию, которая не принимает null-ы. И тут оппа — другая задача не принимает коллекций из пустых строк, третья — отрицательных индексов, четвёртая — timespan больше часа и вдруг выясняется, что все четыре — это атрибуты одной сущности (скажем записи из semlog-а) и все приседания с волшебной коллекцией идут лесом. Никто не даст время на такие эксперименты, задачу надо сделать и переходить к следующим.

Что печально, даже появление в шарпе аналога Units of Measure от F# делу не поможет. Куча существующего кода с типами-примитивами никуда не денется, увы.

Так вот, когда пишут код без оглядки на подобные ограничения, вечно получается абсолютно неадаптированное к реальной жизни решение. Не надо так делать


S>>Ошибки "в принципе быть не может" на текущей codebase. Как, к примеру, ловить некорректные значения, возвращённые сторонним кодом?

·>Корректно обрабатывать — кидать исключение, например.
Ну так ассерты именно это и делают. Вся разница — они позволяют переиспользовать проверки без копипасты. Ну, т.е. вернулись к началу: ассерты — фу-фу-фу, просто исключения — ок. Серьёзно?


·>Почему не вариант? Это говорит о том, что ассерт написать проще, чем ютест. А это говорит о том, что ютесты пишутся сложно. А это говорит о том, что код не самого лучшего качества.

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


S>>Или как в нашем случае — чтоб воспроизвести баг, нужно продублировать весь сценарий, т.к. итоговая ошибка вызвана мелкими логическими несостыковками в 3 независимых кусках кода. Ок, воспроизвели, починили, завели тест, всё зелёное. Какие гарантии, что эта же ошибка не воспроизведётся при другой комбинации условий и как этот момент вообще отловить?

·>Я не понял из описания issue взаимосвязь с ассертами. Можно поподробнее?
Очень просто — наш проект упал с ассертом "строка в .csv содержит неэкранированный разделитель", текущая культура Central Kurdish, разделитель списка — ؛. Заметь, что для этого нам не пришлось писать отдельный тест для csv, перебирать все культуры (эта, к примеру, появилась в восьмёрке, пока CI-сервер был на 2012-м — фиг бы поймали), просто прогнали интеграционный тест и он нашёл штуки три похожих ошибки.

Раз такое дело — проверил соседние проекты, нашёлся аналогичный баг в BenchDotNet, в CodeJam тоже поправить надо будет, если попросят произвольные разделители.

·>И как этот код будет работать, если вдруг попадёт на какой-нибудь server side?

Никак. Поэтому все пишут свои ассерты