Я хочу сказать компилятору VC ++ скомпилировать весь код. Это можно сделать?

Я использую VS2005 VC ++ для неуправляемого C ++. У меня есть VSTS, и я пытаюсь использовать инструмент покрытия кода для выполнения двух задач в отношении модульных тестов:

  1. Посмотрите, какая часть моего тестируемого кода, на который я ссылаюсь, выполняется
  2. Посмотрите, сколько методов моего тестируемого кода (если есть) вообще не тестируются

Настройка инструмента покрытия кода VSTS (см. Текст ссылки ) и выполнить задачу №1 было несложно. Однако №2 оказался для меня неожиданным вызовом. Вот мой тестовый код.

class CodeCoverageTarget
{
public:
    std::string ThisMethodRuns() {
         return "Running";
    }

    std::string ThisMethodDoesNotRun() {
        return "Not Running";
    }
};



#include <iostream>
#include "CodeCoverageTarget.h"
using namespace std;
int main()

{
    CodeCoverageTarget cct; 
    cout<<cct.ThisMethodRuns()<<endl;
}

Когда оба метода определены в классе, как указано выше, компилятор автоматически удаляет ThisMethodDoesNotRun () из файла obj. Если я вынесу его определение за пределы класса, оно будет включено в файл obj, и инструмент покрытия кода покажет, что оно вообще не выполнялось. В большинстве случаев я хочу, чтобы компилятор выполнил это исключение за меня, но для инструмента покрытия кода он побеждает значительную часть значения (например, поиск непроверенных методов). Я пробовал несколько вещей, чтобы заставить компилятор перестать быть для меня умным и компилировать все, но я в тупике. Было бы неплохо, если бы инструмент покрытия кода компенсировал это (я полагаю, отсканировав источник и сопоставив его с выводом компоновщика), но я не нашел ничего, что могло бы предположить, что у него есть специальный режим, который нужно включить. Мне здесь совсем не хватает чего-то простого или это невозможно с помощью инструмента покрытия кода VC ++ + компилятор VSTS?

Заранее спасибо, КГБ


person Community    schedule 19.09.2008    source источник
comment
Я задал здесь связанный, но более общий вопрос: stackoverflow.com/questions/307478/   -  person Zach Burlingame    schedule 21.11.2008


Ответы (5)


Вы можете попробовать добавить строку кода для вызова функции, только если какое-то условие истинно, и гарантировать, что это условие никогда не будет истинным. Просто убедитесь, что компилятор не может этого понять. Например,


int main(int argc, char **argv)
{
  if(argv == NULL)  // C runtime says this won't happen
    someMethodWhichIsntReallyEverCalled();
}
person Adam Rosenfield    schedule 19.09.2008
comment
Проблема, которую я пытаюсь решить здесь, заключается в обнаружении функций / энтодов, которые уже были написаны и были полностью забыты в модульном тесте. Это должно сработать, но если я не забуду это сделать, я, вероятно, не забуду и модульное тестирование функции. Спасибо! Кевин - person ; 22.09.2008

Один из способов гарантировать, что ваши функции не будут отброшены, - это экспортировать их. Вы можете сделать это, добавив __declspec(dllexport) в свой объявления функций. Лучше всего обернуть это макросом препроцессора C, чтобы вы могли отключить его, поскольку он зависит от компилятора и вы можете не захотеть, чтобы все ваши сборки экспортировали символы. Другой способ экспорта функций - создать файл .DEF .

Если вложение является проблемой, вы также можете добиться успеха с помощью __declspec(noinline) .

Находится ли ваш код в статической библиотеке, которая затем компилируется в тестовый EXE / DLL? Компоновщик автоматически удалит объектные файлы, на которые нет ссылок, которые находятся в статических библиотеках. Пример: если статическая библиотека содержит a.obj и b.obj и EXE / DLL, которые вы связываете с символами ссылок из b.obj, но не a.obj, то содержимое a.obj не будет связано с исполняемым файлом или DLL. Однако после повторного прочтения вашего описания это не похоже на то, что здесь происходит.

person bk1e    schedule 20.09.2008

Извините, я должен был уточнить, что я создаю режим отладки с отключением встраивания и всей оптимизации. Кроме того, код удаляется еще до того, как произойдет встраивание, поскольку на него никогда не ссылаются, чтобы его можно было даже рассматривать для встраивания.

person Community    schedule 19.09.2008

Отключите встраивание функций. Самый простой способ сделать это - просто скомпилировать в режиме отладки.

Изменить: увидев ваше разъяснение, я считаю, что мой ответ ошибочен. Возможно, если бы вы переместили тело функции в другой раздел файла .h, используя ключевое слово "inline"?

person Mark Ransom    schedule 19.09.2008

Другой вариант - переключаться между встроенными и не встроенными функциями в зависимости от вашей сборки, используя файлы .inl, например:

в файле foo.inl:

inline std::string Foo::ThisMethodDoesNotRun()
{
    return "Not Running";
}

в foo.h:

#if !COVERAGE_BUILD
#include "foo.inl"
#endif

в foo.cpp:

#if COVERAGE_BUILD
#define inline
#include "foo.inl"
#endif
person Don Neufeld    schedule 19.09.2008
comment
Спасибо, Дон, у нас МНОГО устаревшего кода, поэтому попытка его модернизации будет проблемой. Кевин - person ; 22.09.2008