Здравствуйте, Кодт, Вы писали:
К>Твоими бы тестами, да медку бы хапнуть!
Я, кажется, знаю, куда эта дискуссия ведет — поскольку юнит-тесты не отлавливают расстрел памяти в сферическом случае в в вакууме, то и писать их не будем. Я такое видел 100500 раз.
К>Все эти "должны" — это прекрасно, а кто конкретно эти долги отдаёт?
По опыту, долги приходится отдавать в основном тогда, когда на тестах "сэкономили".
К>Только в том случае, если юнит-тестами покрыто абсолютно всё поведение модуля.
К>В том числе, нарушение контракта извне. То есть, у тебя есть мок, который наловчился диагностировать абсолютно все нарушения контракта, проходящие под категорией "неопределённое поведение".
"Нарушение контракта извне" aka выдача невалидных данных на вход — один из трех сценариев использования юнита. Обязательно тестируется.
К>Подчеркну: абсолютно все.
Что значит "абсолютно все"? Юнит таков, что ему можно 100500 способами нарушить контракт? Так нужно его резать на съедобные части, только и всего.
К>Да щас! "Тесты уже есть".
К>Тесты — это лишь ещё одна проекция предметной области на твоё понимание предметной области. (Первая проекция — это рабочий код).
Не предметной области, а логики работы юнита.
К>Если ты чего-то недопонял, то тупо не догадаешься написать правильные тесты.
Когда допонял — дописываешь пропущенные. А то ведь так бывает, что допонял предметную часть и понял, что все, что накодил, нужно полностью переписывать.
К>И в отладчик смотрит человек. А человеку свойственно ошибаться, и поэтому надеяться только на тесты — это заранее согласиться на ложноотрицательную диагностику.
К>Как, впрочем, и одну лишь отладку...
Вот именно, вот именно.
К>Ну давай, покажи простой и эффективный код транспонирования матрицы на месте.
Э, нет, я тут про тесты говорю, а не матирцы.
К>Если будешь рожать "с листа", то риск накосячить с адресной арифметикой достаточно велик.
Ключевое слово "
риск". Привыкший работать по TDD моментально распознает эти риски. И задает себе вопрос — как я напишу тест, который проверит, накосячил ли я в данном месте? Это не всегда можно, но чаще всего — как раз можно.
L>>Во-вторых, проверка стрельбы по памяти не входит в ответственность юнит-тестов. Я в принципе не уверен, что ее можно в общем случае обнаружить в момент собственно выстрела.
К>ВотЪ! Не всемогущи твои юнит-тесты. Настоящий, труъ баг они не распознают.
По нынешним временам стрельба по памяти — это уже не труъ багъ, а "скорее кто пустил студентов в репозиторий".
Тем не менее, гоняя юнит-тесты при каждой сборке, у тебя больше шансов узнать, что имеет место быть "упс", еще до выхода в тестирование.
L>>В-третьих, используя тот факт, что дважды транспонированная матрица равна самой себе, в случае подобных подозрений можно написать и автотест, который переберет все варианты и сделает это за O(x*y) время, что в 21 веке означает примерно "мгновенно".
К>Сколько пар (x,y) ты хочешь перебрать? В диапазоне [1..N] ты уже отхватишь O(N^4). Мгновенно...
Все же, наверное, квадрат. Вполне приемлимо для функционального теста.
Опять же, никто так не делает. Анализируют риски ошибок в реализации алгоритма, и пишут тесты, нацеленные на срабатывание именно этих рисков.