Как улучшить покрытие веток в C++

У меня довольно большой набор тестов для библиотеки C++ с почти 100% охватом линий, но только 55,3% охватом ветвей. Просматривая результаты lcovПохоже, что большинство пропущенных веток можно объяснить многими способами C++. std::bad_allocНапример, всякий раз, когда std::string построен

Я спрашивал себя, как улучшить охват филиалов в этой ситуации, и подумал, что было бы неплохо иметь new оператор, который можно настроить, чтобы бросить std::bad_alloc после стольких выделений, необходимых для попадания в каждую ветку, пропущенную в моем наборе тестов.

Я (наивно) пытался определить глобальный void* operator new (std::size_t) функция, которая считает глобальный int allowed_allocs и бросает std::bad_alloc всякий раз, когда 0 достигнуто

Это имеет несколько проблем, хотя:

  • Трудно получить количество new звонки до "первого" желаемого throw, Я могу выполнить пробный прогон, чтобы рассчитать требуемые вызовы для успешного выполнения, но это не помогает, если несколько вызовов могут потерпеть неудачу в одной строке, например, что-то вроде std::to_string(some_int) + std::to_string(another_int) где каждый std::to_stringконкатенация через operator+ а также первоначальное распределение может быть неудачным.
  • Что еще хуже, мой набор тестов (я использую Catch) использует много new сам вызовы, так что даже если бы я знал, сколько вызовов требует мой код, трудно догадаться, сколько дополнительных вызовов из набора тестов необходимо. (Что еще хуже, у Catch есть несколько "подробных" режимов, которые создают много выходов, которые снова нуждаются в памяти...)

У вас есть идеи, как улучшить покрытие филиала?

Обновление 2017-10-07

Тем временем я нашел /questions/9074867/pokryitie-vetok-lcovgcov-s-proizvodstvom-vetok-c-povsyudu/9074881#9074881 со ссылкой на скрипт Python для фильтрации некоторых ветвей, созданных исключениями из вывода lcov. Это привело к тому, что охват моей ветки составил 71,5%, но оставшиеся небрежные ветки все еще очень странные. Например, у меня есть несколько операторов if, как это:

если заявление с unhit ответвлением

с четырьмя (?) ветвями, из которых одна осталасьreference_token это std::string).

У кого-нибудь есть идея, что означают эти ветви и как их можно ударить?

2 ответа

Я был успешным в этом некоторое время назад. У меня не было набора тестов, я просто запустил приложение, но обнаружил следующее.

Некоторая форма изоляции тестируемой вещи была важна. У меня были векторы и карты, которые в основном прерывали тестирование, когда они были также склонны.

Я думаю, что мне это удалось, когда у меня был IPC между инъекцией ошибки и точкой отказа. Это позволило вводить код неисправности инжектора и удалять независимо от тестируемого объекта.

Я также преуспел с подобными вещами, когда находился в одном и том же двоичном файле, но имел два независимых пути выделения - пользовательский распределитель для кода внедрения ошибки - который гарантирует, что в него не будут вмешиваться.

Моя успешная система взяла стек вызовов malloc и отправила его через IPC в другую программу. Он решил, видел ли он стек ранее, и если нет, то не удался. Затем программа может произойти сбой и произойдет сбой (дамп памяти был захвачен), после чего тестовая система будет перезапущена. Это значительно улучшило качество кода, который я разрабатывал.

Чей код вы хотите протестировать - ваш или Стандартная библиотека? Меня поражает, что в вашем отчете о покрытии говорится о ветвях в std::string, а не о вашем коде.

Можете ли вы настроить 'lcov', чтобы игнорировать библиотеку std и просто сосредоточиться на своем коде?

Другие вопросы по тегам