Как мне написать тестовый код в производственном коде, используя #ifdef на C ?

#c #testing #preprocessor #compiler-directives

#c #тестирование #препроцессор #директивы компилятора

Вопрос:

ПРИМЕЧАНИЕ: я думаю, что это довольно просто, пожалуйста, укажите мне правильное направление, если на это уже дан ответ. Я посмотрел онлайн, но, к удивлению, не смог найти ответ, возможно, я использовал неправильные слова для поиска.

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

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

 //In Foo.hpp
class Foo
{
   public:
      Foo()
      ~Foo()
      ...
}

//In Foo.cpp
Foo::Foo()
{
   #ifdef THIS_IS_TEST_MODE
      BarTest();
   #else
      Bar();
   #elseif
}
  

Цель: в конструкторе Foo() я хочу, чтобы BarTest() запускался только тогда, когда в тестовом коде создается экземпляр Foo.

Контекст: я использую BOOST, поэтому я в основном использую макросы BOOST_AUTO_TEST_SUITE и BOOST_FIXTURE_TEST_CASE в тестовом коде. Существует файл .props, который в настоящее время включен во все файлы prod и test project .

Что я уже пробовал: добавил еще один файл .props с директивой препроцессора TEST и включил этот файл .props только в тестовый проект. В то время как ТЕСТ #ifdef оценивается как true в тестовом проекте, в производственном коде он оценивается как false . Я думаю, это происходит потому, что конфигурация new .props применяется только к тестовому проекту.

Альтернативы: я думаю, я могу добавить параметр, скажем, bool test в ctor Foo и по умолчанию присвоить ему значение false, чтобы оно было истинным только из тестового кода. Однако я чувствую, что это может привести к ошибкам в будущем.

Комментарии:

1. Не существует универсального правила или закона о том, как это сделать. Наборы тестов сильно зависят от конкретного приложения, и для каждого приложения потребуется свой индивидуальный подход к написанию наборов тестов.

2. Спасибо, Сэм 🙂 Может быть, я ищу способ определить директиву, которая применяется глобально, но только при создании тестового проекта.

3. Если вы хотите, чтобы макрос работал так, как вы описываете, тогда он явно должен быть определен одинаково в каждом модуле компиляции при компиляции. Вы не можете создать свой «тестовый код» с THIS_IS_TEST_MODE помощью defined, а свой «производственный код» с THIS_IS_TEST_MODE помощью undefined и ожидать, что они будут вести себя согласованно. Макросы расширяются на ранней стадии компиляции, и определение THIS_IS_TEST_MODE в одном модуле компиляции волшебным образом не приводит к тому, что код в другом модуле компиляции будет иметь вид, как если бы он был определен.

4. Спасибо, Питер. Я думаю, что мне действительно нужно, чтобы THIS_IS_TEST_MODE определялся только при создании тестового проекта. Я понимаю, что когда он будет определен, это будет так как для тестового, так и для производственного кода 🙂