Здравствуйте, tdiff, Вы писали:
T>Вот я по то же. black-box тестирование алгоритма может сказать только то, что он в некоторых случаях работает правильно или нет. T>Если алгоритм достаточно сложен, и мы знаем, что он неисправен, далеко не всегда тесты помогут выявить ошибку.
Если алгоритм достаточно сложен для того, чтобы по провалившимся тестам было непонятно, где именно ошибка, то этот алгоритм должен быть разбит на более мелкие части, у которых тоже должны быть свои юнит-тесты.
Re[13]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, jahr, Вы писали:
J>Здравствуйте, tdiff, Вы писали:
T>>Вот я по то же. black-box тестирование алгоритма может сказать только то, что он в некоторых случаях работает правильно или нет. T>>Если алгоритм достаточно сложен, и мы знаем, что он неисправен, далеко не всегда тесты помогут выявить ошибку.
J>Если алгоритм достаточно сложен для того, чтобы по провалившимся тестам было непонятно, где именно ошибка, то этот алгоритм должен быть разбит на более мелкие части, у которых тоже должны быть свои юнит-тесты.
ну вот очередной пример: как обнаружить юнит-тестами эту ошибку
for(uint8_t i = 10; i >= 0; --i){<...>};
?
Re[14]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, _hum_, Вы писали:
__>>ну вот очередной пример: как обнаружить юнит-тестами эту ошибку __>>
__>> for(uint8_t i = 10; i >= 0; --i){<...>};
__>>
L>Такая ошибка обрануживается на code review.
ой-ли, так просто ее обнаружить на код-ревью? (кстати, в таких случаях ревью разве не тот же "мысленный дебаггинг"? )
L>Впрочем, зависание теста тоже покажет.
это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает.
Re[16]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали: __>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает.
на конкретном примере например, транспонирования матрицы такое "зависание" цикла не пройдет ни одного теста, кроме, разве что, пустой матрицы
Re[16]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали:
L>>Такая ошибка обрануживается на code review. __>ой-ли, так просто ее обнаружить на код-ревью? (кстати, в таких случаях ревью разве не тот же "мысленный дебаггинг"? )
uint, >=0 и --, использованные в одном for, в моем моску вызывают хардверное прерывание.
L>>Впрочем, зависание теста тоже покажет. __>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает.
При покрытии всех возможных сценариев наличие зависания вылезет при первом же прогоне тестов.
Re[15]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_, Вы писали:
__>>ну вот очередной пример: как обнаружить юнит-тестами эту ошибку __>>
__>> for(uint8_t i = 10; i >= 0; --i){<...>};
__>>
__>>?
BFE>Тест не будет пройден.
и что? как понять, в чем ошибка, не пошагав по циклу и не увидев, что он делает лишние итерации?
BFE>Ну и вообще, согласно последнему постановлению ВЦСПС этот цикл должен быть записан так: C>Стандартная идиома:
C>
C>for (unsigned i = n; i --> 0 ;)
C> std::cout << i << std::endl;
C>
это плохо, потому что все равно делается декремент беззнаковой переменной в нуле (хоть и после ее использования). кстати, как там по стандарту — это UB или нет?
Re[15]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, __kot2, Вы писали:
__>Здравствуйте, _hum_, Вы писали: __>>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает. __>на конкретном примере например, транспонирования матрицы такое "зависание" цикла не пройдет ни одного теста, кроме, разве что, пустой матрицы
господа, я для себя пока принял, что тесты позволяют хорошо локализовать ошибку (чем лазить дебажить по всему коду, проще понатыкать всюду assert-ов, которые сразу же будут показывать проблемную область). попутно они же позволяют улучшить верификацию кода при его правке.
но! для того, чтобы понять, в чем именно ошибка, придется, либо писать наиподбробнейшие тесты (вплоть до тестирования присваивания uint8_t a = b; assert(a == b); ), либо положиться на дебагер. думаю, в реальности резонно выбирать золотую середину. иными словами, "не вместо, а вместе" (с)
п.с. кстати, тема данной ветки — длительность компиляции, которой, хоть с тестами, хоть без тестов, не избежать (все равно за обнаружением ошибки следует правка и перекомпиляция)
Re[17]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, _hum_, Вы писали:
L>>>Такая ошибка обрануживается на code review. __>>ой-ли, так просто ее обнаружить на код-ревью? (кстати, в таких случаях ревью разве не тот же "мысленный дебаггинг"? )
L>uint, >=0 и --, использованные в одном for, в моем моску вызывают хардверное прерывание.
согласен. выглядит ужасно.
L>>>Впрочем, зависание теста тоже покажет. __>>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает.
L>При покрытии всех возможных сценариев наличие зависания вылезет при первом же прогоне тестов.
вот-вот "всех возможных". а это возможно только для очень простых ситуаций. к тому же вы не можете доказать, что покрыли все возможные сценарии, а значит, даже если тест пройден, не факт, что все равботает правильно.
ну и сколько затрат времени и сил уходит на то, чтобы просчитать эти сценарии
Re[18]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали:
__>>>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает. L>>При покрытии всех возможных сценариев наличие зависания вылезет при первом же прогоне тестов.
__>вот-вот "всех возможных". а это возможно только для очень простых ситуаций.
А код и должен сводить эти ситуации к простым.
__>к тому же вы не можете доказать, что покрыли все возможные сценарии, а значит, даже если тест пройден, не факт, что все равботает правильно.
Доказать? Гхм, я этот код написал, я знаю, какие сценарии мне нужно покрыть.
__>ну и сколько затрат времени и сил уходит на то, чтобы просчитать эти сценарии
Нисколько, это происходит автоматически.
Re[19]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, _hum_, Вы писали:
__>>>>это если есть зависание, а если внутри цикла стоит брейк, то будем долго и упорно ревьювить, где ж у нас что не так работает. L>>>При покрытии всех возможных сценариев наличие зависания вылезет при первом же прогоне тестов.
__>>вот-вот "всех возможных". а это возможно только для очень простых ситуаций.
L>А код и должен сводить эти ситуации к простым.
всегда ли это возможно... вот в чем вопрос
__>>к тому же вы не можете доказать, что покрыли все возможные сценарии, а значит, даже если тест пройден, не факт, что все равботает правильно.
L>Доказать? Гхм, я этот код написал, я знаю, какие сценарии мне нужно покрыть.
вы не поняли. я говорил о том, что вы используете методологию, когда если что-то работает не так, то смотрим, какой тест не пройден, и там ищем проблему.
но на деле может быть так, что ошибка появилась совсем в другом куске и проскользнула через другие тесты, так как вы не охватили все сценарии. а вы будете сидеть и чесать репу, что ж не так.
в этом случае спасет только пошаговое выполнение и сравнение на каждом шаге состояния — какое должно быть, и какое есть.
а вот если бы вы могли доказать, что все сценарии учли, то такая ситуация бы была невозможна.
__>>ну и сколько затрат времени и сил уходит на то, чтобы просчитать эти сценарии
L>Нисколько, это происходит автоматически.
это неправда. создание тестов — алгоритмически неразрешимая задача.
Re[18]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали: __>но! для того, чтобы понять, в чем именно ошибка, придется, либо писать наиподбробнейшие тесты (вплоть до тестирования присваивания uint8_t a = b; assert(a == b); ), либо положиться на дебагер. думаю, в реальности резонно выбирать золотую середину. иными словами, "не вместо, а вместе" (с)
дебагер это как бы такая скрипучая телега со старой лошадью. да, иногда можно выгнать ее из стойла, смахнуть пыль и даже куда-то поехать, но это просто несерьезно. дебагер хорош только если вы вообще никуда не торопитесь и вам просто нравится копаться в коде. если у вас в реальной жизни дошло дело до дебагера, значит, вы делаете что-то очень и очень неправильно.
то есть транспортная компания конечно может держать резервную лошадь с телегой в стойле и даже целую конюшню, но я бы лично не стал не хотел бы работать с тем, кто будет на этом настаивать и рассказывать о всех преимуществах лошади над машинами и дронами
вообще, я иногда пишу код без тестов, оосбенно если это прототип. но когда он начинает выдавать неожиданные результаты, или я просто хочу убедиться в корректности результата, я не лажу в дебагере на конкретных примерах. это глупо. это просто трата своего времени впустую. я беру пишу минимальные тестовые примеры и тесты. то же самое, что кто-то другой будет делать руками, я сделаю автоматом. при этом так как я знаю, как писать код для тестов, мне не понадобится для этого ничего особо переписывать, код сразу готов в ним.
Re[16]: Долгая компиляция на с++ - смерть для больших проект
C>>for (unsigned i = n; i --> 0 ;)
C>> std::cout << i << std::endl;
C>>
__>это плохо, потому что все равно делается декремент беззнаковой переменной в нуле (хоть и после ее использования). кстати, как там по стандарту — это UB или нет?
По стандарту всё корректно: ни переполнения, ни UB. Для беззнаковых, после нуля следует максимальное для данного типа число.
И каждый день — без права на ошибку...
Re[20]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали:
L>>А код и должен сводить эти ситуации к простым. __>всегда ли это возможно... вот в чем вопрос
Ээээ, всегда.
__>>>к тому же вы не можете доказать, что покрыли все возможные сценарии, а значит, даже если тест пройден, не факт, что все равботает правильно.
L>>Доказать? Гхм, я этот код написал, я знаю, какие сценарии мне нужно покрыть.
__>вы не поняли. я говорил о том, что вы используете методологию, когда если что-то работает не так, то смотрим, какой тест не пройден, и там ищем проблему. __>но на деле может быть так, что ошибка появилась совсем в другом куске и проскользнула через другие тесты, так как вы не охватили все сценарии. а вы будете сидеть и чесать репу, что ж не так.
Ничего никто чесать не будет. Сценарии покрыты на 100% — значит проблема в другом месте. Разматываем клубок, находим виновника.
В этом-то и соль юнит-тестов — отдаешь код джуну, он что-то меняет, что ломает юнит-тест в другом модуле. Обнаруживается это сразу и исправляется тоже сразу.
Не говоря уже о том, что юнит-тесты здорового человека изолированы, и дятел, набедокуривший в одном модуле, не рушит остальные 100500, а лишь получает указание все переписать сделать так, чтобы его юнит-тесты проходили.
__>в этом случае спасет только пошаговое выполнение и сравнение на каждом шаге состояния — какое должно быть, и какое есть.
Не надо никакого пошагового выполнения.
__>>>ну и сколько затрат времени и сил уходит на то, чтобы просчитать эти сценарии L>>Нисколько, это происходит автоматически. __>это неправда. создание тестов — алгоритмически неразрешимая задача.
Еще раз напомню — с вопросами веры в другой форум.
Тестирование юнитов — это общепринятая инженерная методология, которая в разработке ПО почему-то до сих пор применяется со скрипом.
Re[17]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_ C>>>Стандартная идиома:
C>>>
C>>>for (unsigned i = n; i --> 0 ;)
C>>> std::cout << i << std::endl;
C>>>
__>>это плохо, потому что все равно делается декремент беззнаковой переменной в нуле (хоть и после ее использования). кстати, как там по стандарту — это UB или нет?
BFE>По стандарту всё корректно: ни переполнения, ни UB. Для беззнаковых, после нуля следует максимальное для данного типа число.
ну тогда приму к сведению, спасибо.
Re[21]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, _hum_, Вы писали:
L>>>А код и должен сводить эти ситуации к простым. __>>всегда ли это возможно... вот в чем вопрос
L>Ээээ, всегда.
__>>>>к тому же вы не можете доказать, что покрыли все возможные сценарии, а значит, даже если тест пройден, не факт, что все равботает правильно.
L>>>Доказать? Гхм, я этот код написал, я знаю, какие сценарии мне нужно покрыть.
__>>вы не поняли. я говорил о том, что вы используете методологию, когда если что-то работает не так, то смотрим, какой тест не пройден, и там ищем проблему. __>>но на деле может быть так, что ошибка появилась совсем в другом куске и проскользнула через другие тесты, так как вы не охватили все сценарии. а вы будете сидеть и чесать репу, что ж не так.
L>Ничего никто чесать не будет. Сценарии покрыты на 100% — значит проблема в другом месте.
"Сценарии покрыты на 100%"
это примерно как заявить — код написан на 100% без ошибок. "ваши доказательства?"
L>В этом-то и соль юнит-тестов — отдаешь код джуну, он что-то меняет, что ломает юнит-тест в другом модуле. Обнаруживается это сразу и исправляется тоже сразу.
я ж говорю — не всегда, потому что невозможно все варианты ошибок покрыть (ну, или, докажите обратное)
__>>>>ну и сколько затрат времени и сил уходит на то, чтобы просчитать эти сценарии L>>>Нисколько, это происходит автоматически. __>>это неправда. создание тестов — алгоритмически неразрешимая задача.
L>Еще раз напомню — с вопросами веры в другой форум.
при чем тут вера, если это чисто математический факт: из теоремы райса вытекает, что не существует даже алгоритма, позволяющего проверить, покрывают ваши тесты 100% сценариев ошибок или нет, не говоря уже об автоматической генерации таких тестов.
Re[22]: Долгая компиляция на с++ - смерть для больших проект
Здравствуйте, _hum_, Вы писали: __> "Сценарии покрыты на 100%" __>это примерно как заявить — код написан на 100% без ошибок. "ваши доказательства?"
ну кодом же вы как-то покрываете сценарии исполнения?
__>при чем тут вера, если это чисто математический факт: из теоремы райса вытекает, что не существует даже алгоритма, позволяющего проверить, покрывают ваши тесты 100% сценариев ошибок или нет, не говоря уже об автоматической генерации таких тестов.
вот есть Вася и Петя. и дали им задачу — написать автоисправление русского текста. задачи хитрая и четкого решения не имеющая.
Вася что-то написал, приносит код, мы открываем папочку с тестами и видим
чяща -> чаща
жыр -> жир
несделал -> не сделал
думаем, какой Вася молодец. вот мы сразу поняли, что кодом поддерживается, нам даже лезть в него не надо
Петя отдает код и говорит "ну и задачку же вы мне подсунули". короче, говорит, я там что-то написал, я проверил у себя на компе там, я ему тест создал, просто опечаток понараскидал, он нашел 70%. улучшить можно, но пока не знаю как.
вы можете выбрать какой код развивать. и какой будете — Васин, который понятно что делает или Петин, который вообще непонятно что делает?
при этом, понимаете, Вася создал огромную ценность в виде минимальных некорректных примеров разных классов, а Петя просто проторчал в дебагере, выискивая какие-то опечатки, по всей видимости, еще и не все найденные. есть желание заниматься поиском его опечаток?