Задать вопрос
@YoungSkipper

Два набора тестов для дебажной и релизной сборки?

Есть код который хочется покрыть тестами. Особенность приложения в том что при возникновении неких не валидных ситуаций в дебажном билде (тестируется разработчиками и внутренними тестерами) — нам предпочтительней получить краш (и большей частью краш репорт уйдет разработчику с информацией достаточной для понимания проблемы).

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

В результате с одной стороны в коде есть проверки ассертами на невалидные ситуации, но с другой стороны есть проверка возвращаемых значений, проверка входных параметров, там где нужно try/catch и т.п. — т.е. в любом случае пытаемся спасти ситуацию.

Утрированный пример — вот есть функция которая возвращает указательно некоторую структуру данных из коллекции — getBotTplById(long id)

В дебажном билде в случае отсутствия такой коллекции (не загрузился файл), или в случае если такого айди в коллекции нет (в другом месте контента есть ссылка на что-то что еще не добавили в контент) — будет ассерт и игра упадет. В релизном мы просто вернем нулевой указатель, который нужно будет проверить.

Понятно, что возможны как и ситуации когда — код ассерт написали, а вот данные проверили не везде.
Так и в целом возможны ситуации когда проверки написали, а ассерт вставить забыли.

Вот хотим написать тест на данную функцию в которую мы передаем заведомо неверный айдишник и что она обработает нормально.

Как мы пишем?

#ifdef DEBUG
ASSERT_THROW(someFunc(notValidId));
ASSERT_NOT_THROW(someFunc(validId));
#else
ASSERT_EQ(someFunc(notValidId), NULL);
ASSERT_NE(someFunc(validId), NULL);
#endif

или?

ASSERT_THROW(ASSERT_EQ(someFunc(notValidId), NULL));
ASSERT_NOT_THROW(ASSERT_NE(someFunc(validId), NULL););

Если технически получиться такое сделать.

В любом случае это достаточно проблема писать два набора. Или забить, и гонять тесты только на дебажном билде? Или наоборот только на релизном?

Что скажете?
  • Вопрос задан
  • 3861 просмотр
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 4
@spiritms
Могу рассказать наш опыт. Наша тестовая система принимает на вход билд и параметр, релиз это или дебаг. Потом на этом билде выполняется какой-то сет из тестовый кейсов, при этом анализируются выходные данные, креши и логи (релиз или дебаг — это один и тот же тестовый код). Таким образом, при одинаковом коде тестовой системы, для разных билдов мы просто получаем немного разные отчёты (которые, кстати, полезно потом сравнить и сопоставить, если что-то пойдёт не так). Так же хочу заметить, что «дебажный» билд это не просто билд, который у девелоперов — это специально настроенный билд, построенный таким образом, что ассерты, эксепшены и прочая расширенная информация сбрасывается в лог, который удобно потом автоматически анализировать и формировать отчёт. Действительно, «дебажная» сборка является третим видом сборки, но она от обычной отличается только одним файлом .h с настройкой ассертов и эксепшенов. Весь этот кейс протянут через систему continious integration и проходит в автоматическом режиме. На самом деле это реализовать не так сложно, но при этом ещё проще поддерживать.
Ответ написан
Комментировать
@abby
На мой взгляд поведение программы должно быть одинаковым независимо от режима дебаг или релиз. В связи с этим считаю, что ручные проверки должны быть везде. Ассерты — на ваше усмотрение, они помогают лишь вовремя заметить неправильное состояние. Тесты тоже должны быть одинаковыми без #ifndef DEBUG, для этого можно использовать свои ассерты, assert.h как правило, специально написан так чтобы это можно было сделать.
Ответ написан
@abby
Может быть не стоит тестировать то, что приложение должно крэшиться? Для юнит-тестов заведите ассерты, которые никогда не бросают исключений, а пишут, например, в специальный лог. Понимаю, что иногда баг очень сложно воспроизвести, и записи в логе недостаточно. Для таких случаев («сложного» интеграционного тестирования со случайными данными и тестеров, которые анализируют доп. информацию в дебажной версии) можно использовать реализацию ассерта, которая крэшит приложение, чтобы девелоперы потом могли по дампу выявить причину падения.
Ответ написан
foxmuldercp
@foxmuldercp
Системный администратор, программист, фотограф
Мне кажется, что дебаг вариант от релиза должен отличаться не тестами, а генерацией логов по каждому чиху, в зависимости от его уровня, а тесты должны быть одинаковы, ну и выводить или нет «тестовый fps».
А тестам должно быть без разницы, релиз это или дебаг, и если тест валится — это кейс для разбирательства «где косяк?», и если не валится, значит всё ок. Ну и собственно, студия имеет интересную настройку — не пускать сборку в TFS, если код не компилится корректно
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы