2014-01-16 3 views
1

При проектировании функций внутри класса C++ я часто помню об испытаниях. Поэтому, когда я заканчиваю всех функционалистов класса, очень часто в класс добавляются несколько функций, которые используются только для целей тестирования. Рассмотрим следующий пример:Эффект избыточных функций тестирования внутри класса C++

class SimpleClass 
{ 
public: 
    int a; 
    int b; 
    void fun1(); 
    void fun2(); 
    void testIntermediateResult(); 
private: 
    void _fun1(); 
    void _fun2(); 

}; 

В этой функции testIntermediateResult необходим только для целей тестирования. Это хорошая практика, просто оставить функцию внутри класса, или я должен сделать что-то вроде этого:

class SimpleClass 
    { 
    public: 
     int a; 
     int b; 
     void fun1(); 
     void fun2(); 
#ifdef TESTING 
     void testIntermediateResult(); 
#endif 
    private: 
     void _fun1(); 
     void _fun2(); 

    }; 

Философия здесь, когда этот класс был закончен тестирование и будет предоставлена ​​клиентам то ИСПЫТАНИЯ будут определены и эта функция не будет внутри класса. Поэтому мой вопрос: действительно ли нужно удалить функцию тестирования, когда класс предоставляется клиенту? Предположим, что клиент не будет использовать функцию тестирования, каков эффект добавления нескольких избыточных функций тестирования внутри класса? Благодарю.

+0

Я бы назвал его 'TESTED'. '#ifndef TESTING' звучит как« если мы не тестируем его », что является противоположностью того, что вы описали ... – starsplusplus

+3

Лучше всего разрабатывать классы, которые не делают слишком много, t должны включать в себя произвольные функции тестирования. – juanchopanza

+1

Это отличная практика, если вам нравится неопределенное поведение. Если вы скомпилируете один источник с помощью 'TESTING', а другой - без него, вы получите неопределенное поведение. (Конечно, все равно это сработает. Но вы никогда не знаете, если бы я писал компилятор, это не скомпилировалось.) –

ответ

3

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

  • Не нужно - это не их задача проверить его.
  • Они могут решить попробовать использовать его - кто знает, что тогда произойдет?

Это просто проще, если они этого не видят. Что касается использования препроцессора, это может быть сопряжено с проблемами, особенно если у вас есть атрибуты, которые необходимо охранять одинаково. Если какой-либо из них пропущен или ваш макрос переопределен в процессе сборки клиентом, тогда вы можете получить сбои во время выполнения из-за несоответствий по размеру классов и т. Д.

Я бы предпочел, чтобы один-на-один внешний класс для проверки ваших доступных классов. Что-то вроде TestSimpleClass, который выполняет тестирование. Существует целый ряд преимуществ для этого подхода:

  1. Он полностью отделен от вашего кода и не встроен в него, поэтому вы не являетесь причиной раздувания кода или вызываете какие-либо потенциальные проблемы с ним.
  2. Он будет тестировать ваш интерфейс класса так, как его видит клиент (т. Е. Тестирование черного ящика)
  3. Потому что это отдельный, вам не нужно давать его своему клиенту - им никогда не нужно об этом знать.

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

Смежные вопросы