Как издеваться над константной переменной для модульного теста в C? - PullRequest
0 голосов
/ 07 августа 2020

Есть ли способ модульного тестирования кода, который зависит от констант?

Например:

/*production code*/
const int my_const = 10; // value might be 0 or 10 
int variable = 5; //"reset value"
    
//Tested Function
int foo(){
  if(my_const == 10){
    variable = 2*my_const;
  }
  else{
    variable = 0;
  }
}
    
int main(void){
  foo();
  return 0;
}

Я хотел бы знать, можно ли запустить тестовый пример для my_const = 0 и для my_const = 10 в одном тесте, без необходимости запускать более одного.

Ответы [ 3 ]

0 голосов
/ 07 августа 2020

Есть ли способ модульного тестирования кода, который зависит от констант?

Рассматриваемая здесь константа на самом деле 0 или 10. const int my_const не является константой C.

если возможно запустить тестовый пример для my_const = 0 и my_const = 10 в одном и том же тесте. без необходимости запускать более одного (?)

Я бы сказал нет - не для хорошего теста.

Представьте себе компилятор, который берет my_const = 0 и помещает этот объект в том же глобальном месте, что и все другие объекты с нулевой инициализацией по умолчанию. Тот же компилятор может с помощью my_const = 10 поместить объект в другой раздел глобальных объектов, требующих ненулевой инициализации. Простое изменение константы 0 на 10 может значительно повлиять на адрес объекта по сравнению с другими, не говоря уже о его значении. Интересно Унаследованный код может зависеть от последовательности адресов, значений или других эффектов пульсации, которые трудно различить.

Я бы сделал что-то вроде ниже и передал компилятору определение для TEN_OR_ZERO, возможно с дефолтом. Затем скомпилируйте / запустите, скомпилируйте / запустите.

#ifndef TEN_OR_ZERO
#define TEN_OR_ZERO 0
#endif
const int my_const = TEN_OR_ZERO; 
0 голосов
/ 07 августа 2020

Как вы, наверное, уже заметили, ваша проблема в том, что у вас есть состояние за пределами метода, который вы хотите протестировать. Если вы хотите иметь возможность писать правильные модульные тесты, вам придется начать писать тестируемый код.

в вашем случае тестируемый код может выглядеть так:

int my_const = 10; // value might be 0 or 10 
int variable = 5; // maybe you don't need this.

//Tested Function
int foo(AWellNamedVariable){

  if(AWellNamedVariable== 10){
    return 2*AWellNamedVariable;
  }
  else{
    return 0;
  }
}

int main(void){
  variable = foo(my_const); // an example how you set something outide of the function without introducing state all over the place.
  return 0;
}

Это это пример того, как может выглядеть код. Другие версии тоже могут работать. Думайте о своих входах, думайте о своих выходах

0 голосов
/ 07 августа 2020

Приходится гадать, что вам на самом деле нужно.

  • Поскольку вы не объявляли переменную const , вы можете просто изменить ее: foo(); my_const = 3; foo();. Вы также можете выбрать значения из аргументов командной строки, чтобы упростить запуск различных тестов.
  • int const my_const = 10; должно вызывать фатальные ошибки компиляции при попытках изменить my_const . Все, что проникает внутрь, специфичны для реализации c и могут работать, запутывая вашу программу, прерывая ее во время выполнения или что-то еще. Ваши тесты могут подтвердить, что происходит ошибка компиляции, но не должны проверять, что происходит во время и после попыток изменения, которые незаметны для компилятора.
  • int volatile const my_const = 10; запускается почти так же, как и раньше, но значение может быть изменено внешними агентствами. В вашем случае отдельная функция в отдельной компиляции с extern int volatile my_const может изменить ее.
    • Обычно volatile используется для значений, измененных самим оборудованием в ядре, драйверах или другом скрытом коде. Его также можно использовать для значений, измененных обработчиками сигналов.
    • Это флаг «остерегайтесь» как для компилятора, так и для людей, что значение не заслуживает доверия и может измениться в любой непредсказуемый момент времени.
    • У тестов не будет ограничений.
    • volatile не для причинного использования, и я упоминаю об этом больше, чем о чем-либо другом. Эти тесты не имеют ограничений.
    • Если используется для переменной в стеке, вы должны быть очень осторожны, она не может быть изменена после того, как функция вернется к повреждению, независимо от того, для чего следующий вызов теперь использует это пространство в стеке.
...