Возможно ли выполнить модульное тестирование кода, изначально не предназначенного для тестирования, без изменения какого-либо кода? - PullRequest
3 голосов
/ 27 октября 2010

Общепринято, что вы не можете тестировать код, если он не настроен для тестирования?

Гипотетический бит кода:

public void QueueOrder(SalesOrder order)
{
   if (order.Date < DateTime.Now-20)
      throw new Exception("Order is too old to be processed");
   ...  
}

Некоторые рассмотрели бы рефакторинг этого в:

protected DateTime MinOrderAge;
{
   return DateTime.Now-20;
}

public void QueueOrder(SalesOrder order)
{
   if (order.Date < MinOrderAge)
      throw new Exception("Order is too old to be processed");
   ...
}

Примечание: Вы можете предложить еще более сложные решения; с использованием интерфейса IClock и фабрики. Это не влияет на мой вопрос.

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

Если я не желаю / не могу вносить изменения: это делает меня неспособным проводить тестирование?

Примечание: Приведенный выше псевдокод может выглядеть как C #, но это только для того, чтобы его можно было прочитать. Вопрос не зависит от языка.

Примечание: Гипотетический фрагмент кода, проблема, необходимость рефакторинга и рефакторинг являются гипотетическими. Вы можете вставить свой собственный пример гипотетического кода, если вы обижаетесь с моим.

Примечание: Вышеприведенный гипотетический код является гипотетическим. Любое отношение к любому коду, живому или мертвому, является чисто случайным.

Примечание: Код является гипотетическим, но никаких ответов нет. Вопрос не субъективен: поскольку я верю, что есть ответ.


Обновление: Проблема здесь, конечно, в том, что я не могу гарантировать, что изменение в приведенном выше примере ничего не сломало. Конечно, я переделал один кусок кода в отдельный метод, и этот код логически идентичен.

Но я не могу гарантировать, что добавление нового защищенного метода не сместило таблицу виртуальных методов объекта , и если этот класс находится в DLL, то я только что ввел нарушение доступа.

Ответы [ 7 ]

4 голосов
/ 27 октября 2010

Ответ - да, необходимо изменить код, чтобы сделать его тестируемым.

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

1 голос
/ 27 октября 2010

Вы можете модульно протестировать свой оригинальный пример, используя объектную среду Mock. В этом случае я бы несколько раз издевался над объектом SalesOrder, каждый раз настраивая другое значение Date, и проводил тестирование. Это позволяет избежать изменения любого поставляемого кода и позволяет проверить алгоритм, о котором идет речь, что дата заказа не слишком далека в прошлом.

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

1 голос
/ 27 октября 2010

Если ваш код не предназначен для тестирования, то его сложнее протестировать. В вашем примере вам придется переопределить метод DateTime.Now, который, вероятно, не простая задача.

Если вы считаете, что добавление тестов в ваш код добавляет мало пользы, или изменение существующего кода не допускается, тогда вам не следует этого делать.

Однако, если вы верите в TDD, вам следует написать новый код с тестами.

1 голос
/ 27 октября 2010

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

В своем гипотетическом коде вы можете протестировать оригинальный код, создав SalesOrder сдата далеко в прошлом, или вы могли бы издеваться над DateTime.Now.Реорганизовать код, как вы показали, удобнее для тестирования, но это не является абсолютно необходимым.

0 голосов
/ 29 октября 2010

Mockito + PowerMock для Mockito.

Вы сможете протестировать практически все без существенного изменения кода.Но некоторые сеттеры будут необходимы для введения макетов.

0 голосов
/ 27 октября 2010

Проблема с такого рода кодом всегда заключается в том, что он создает и зависит от множества статических классов, типов фреймворков и т. Д. И т. Д. ...

Очень хорошее решение для «внедрения» подделокдля всех этих объектов есть Typemock Isolator (который является коммерческим, но стоит каждого пенни).Так что да, вы, конечно, можете тестировать устаревший код, который был написан без учета тестируемости.Я сделал это в большом проекте с Typemock и получил очень хорошие результаты.

В качестве альтернативы Typemock, вы можете использовать бесплатную среду MS Moles, которая в основном делает то же самое.Просто у него довольно неинтуитивный API, и его гораздо сложнее освоить и использовать.

HTH.Томас

0 голосов
/ 27 октября 2010

Это легко сделать в некоторых динамических языках. Например, я могу подключиться к операторам import / using и заменить фактическую зависимость на заглушку, даже если SUT (тестируемая система) использует ее как неявную зависимость. Или я могу переопределить эти символы (классы, методы, функции и т. Д.). Я не говорю, что это путь. Вещи должны быть реорганизованы, но легче написать некоторые тесты для определения характеристик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...