Удалить автоматически сгенерированный код исключения из отчета покрытия

Давайте начнем с минимального рабочего примера:
main.cpp:

#include <iostream>
#include <string>

int main() {
std::cout << "hello " + std::to_string(42);
return 0;
}

Я компилирую этот код, используя следующие флаги:

[g++/clang++] -std=c++11 -g -Og --coverage -Wall -o main main.cpp

лязг 4.0.1
gcc 4.8.5.

Я получаю только 50% покрытия кода, так как компилятор генерирует код исключения, который не выполняется, как объяснено в другом вопросе stackoverflow.

Проблема в том, что отключение исключений через -fno-exceptionsэто не вариант для меня. Код, который я пишу для модульных тестов, использует исключения, поэтому отключение всех из них не вариант.

Для создания отчета я использую gcovr, в случае clang ++ дополнительно llvm-cov gcovпреобразовать это. Но я не связан с этими инструментами, поэтому, если у вас есть другие инструменты, которые не показывают такое поведение, пожалуйста, предложите их!

По сути, мне нужен способ для компиляции / записи модульных тестов для этого кода и получения 100% ветвления / условного покрытия с включенными исключениями. Есть ли способ?

3

Решение

Ну, я полагаю, что вы намерены не тестировать этот маленький кусочек кода, а использовать концепцию в проекте …

Код, который вы ввели, выдает исключение — bad_alloc выдается, когда у вас нет памяти для хранения строки, которая будет создана с std::to_string, Чтобы быть на 100% безопасным, std::to_string должен быть окружен try-catchгде вы могли бы обработать ваше исключение.

Чтобы построить модульный тест с 100% охватом кода, вам нужно заставить исключение произойти — в этом конкретном случае почти невозможно гарантировать, так как параметр является постоянным числом. Но в вашем проекте вам, вероятно, нужно выделить некоторые данные, размер которых является переменным — в этом случае вы можете выделить в своем коде методы, которые выделяют память, чтобы протестировать их по отдельности. Затем вы передаете этим методам в тестовой функции огромное количество, которое будет выделено для оценки того, что вы поместили в свой блок catch (и проверьте, правильно ли вы его обрабатываете).

Например, этот код должен выдавать исключение, вы можете использовать его, чтобы вдохновить себя при создании ваших тестов (источник):

// bad_alloc.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
using namespace std;

int main() {
char* ptr;
try {
ptr = new char[(~unsigned int((int)0)/2) - 1];
delete[] ptr;
}
catch( bad_alloc &ba) {
cout << ba.what( ) << endl;
}
}

Однако, если вы не планируете обрабатывать все bad_alloc исключений (или абсолютно всех исключений) в вашем коде, нет никакого способа получить 100% покрытие — так как оно не будет покрыто на 100% … Хотя в большинстве случаев истинное 100% покрытие не является необходимым.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]