До сих пор я использовал импровизированную процедуру модульного тестирования - в основном, целую загрузку программ модульного тестирования, автоматически запускаемых пакетным файлом.Хотя многие из них явно проверяют свои результаты, гораздо больше читов - они выгружают результаты в текстовые файлы, которые имеют версии.Любое изменение в результатах теста помечается Subversion, и я легко могу определить, что это было за изменение.Многие тесты выводят точечные файлы или какую-либо другую форму, которая позволяет мне получить визуальное представление вывода.
Проблема в том, что я переключаюсь на использование cmake.Переход к потоку cmake означает использование сборок вне источника, что означает, что удобство выгрузки результатов в общую папку «источник / сборка» и их управление версиями вместе с исходным кодом на самом деле не работает.
Какзамена, что я хотел бы сделать, это сообщить инструменту модульного тестирования, где найти файлы ожидаемых результатов (в дереве исходных текстов) и заставить его выполнить сравнение.В случае неудачи он должен предоставлять фактические результаты и списки различий.
Возможно ли это, или я должен использовать совершенно другой подход?
Очевидно, я мог бы игнорировать ctestи просто адаптировать то, что я всегда делал, к сборкам вне исходного кода.Например, я мог бы создать версию своей папки «где все они собраны» (конечно, с либеральным использованием «игнор»).Это нормально?Вероятно, нет, так как каждая сборка будет заканчиваться отдельной копией ожидаемых результатов.
Кроме того, любые рекомендации по рекомендуемому способу выполнения модульного тестирования с помощью cmake / ctest были получены с благодарностью.Я потратил немало времени на cmake, не потому что это плохо, а потому, что я не понимал, как лучше с ним работать.
РЕДАКТИРОВАТЬ
ВВ конце концов, я решил, что сторона модульного тестирования cmake / ctest должна быть максимально простой.Чтобы проверить фактические результаты в сравнении с ожидаемыми, я нашел дом для следующей функции в моей библиотеке ...
bool Check_Results (std::ostream &p_Stream ,
const char *p_Title ,
const char **p_Expected,
const std::ostringstream &p_Actual )
{
std::ostringstream l_Expected_Stream;
while (*p_Expected != 0)
{
l_Expected_Stream << (*p_Expected) << std::endl;
p_Expected++;
}
std::string l_Expected (l_Expected_Stream.str ());
std::string l_Actual (p_Actual.str ());
bool l_Pass = (l_Actual == l_Expected);
p_Stream << "Test: " << p_Title << " : ";
if (l_Pass)
{
p_Stream << "Pass" << std::endl;
}
else
{
p_Stream << "*** FAIL ***" << std::endl;
p_Stream << "===============================================================================" << std::endl;
p_Stream << "Expected Results For: " << p_Title << std::endl;
p_Stream << "-------------------------------------------------------------------------------" << std::endl;
p_Stream << l_Expected;
p_Stream << "===============================================================================" << std::endl;
p_Stream << "Actual Results For: " << p_Title << std::endl;
p_Stream << "-------------------------------------------------------------------------------" << std::endl;
p_Stream << l_Actual;
p_Stream << "===============================================================================" << std::endl;
}
return l_Pass;
}
Типичный модульный тест теперь выглядит примерно так ...
bool Test0001 ()
{
std::ostringstream l_Actual;
const char* l_Expected [] =
{
"Some",
"Expected",
"Results",
0
};
l_Actual << "Some" << std::endl
<< "Actual" << std::endl
<< "Results" << std::endl;
return Check_Results (std::cout, "0001 - not a sane test", l_Expected, l_Actual);
}
Там, где мне нужна повторно используемая функция дампа данных, она принимает параметр типа std::ostream&
, поэтому она может выполнять дамп в поток фактических результатов.