Эффективен ли процедурный код модульного тестирования?

13

В текущем проекте силы, которые хотят включить модульное тестирование, включены в наш цикл разработки, чтобы избежать постоянного количества ошибок, которые, похоже, проникают в наш код. Проблема в том, что код спагетти на 95% процентов процедурный, с которым я никогда не проводил модульное тестирование (весь мой опыт с модульным тестированием был с кодом ООП)

Итак, мой вопрос в двух словах: было бы разумно продолжить модульное тестирование с нашей текущей кодовой базой или предложить отложить его до тех пор, пока приложение не будет перенесено в надлежащую структуру ООП?

PS: хотя я пытался оформить этот вопрос как независимый от языка, я чувствую, что указание рассматриваемого приложения использует PHP, а javascript поможет дать более конкретные ответы, которые могли бы ответить на этот вопрос, так как по опыту это происходит чаще всего с такими приложениями.

canadiancreed
источник
13
Модульное тестирование не предотвращает появление новых ошибок, оно предотвращает регрессию.
Дейнит
2
возможные дубликаты Помогли ли вам генераторы модульных тестов при работе с устаревшим кодом? и еще десяток вопросов. Ищите «устаревший юнит-тест»
mattnz
4
Ваша проблема в том, что код - это спагетти / Big Ball Of Mud, а не то, что он «процедурный» (хороший процедурный код хорошо тестируется - BTDTGTTS). Ваши потенциальные полномочия скорее привлекут (больше) тестировщиков и организуют тщательную профессиональную проверку качества проекта, если они действительно хотят «избежать постоянного количества ошибок».
комнат
@ l0b0 да, я сделал. Мои извинения, буду обновлять тест, чтобы быть более ясным
canadiancreed
@mattnz Я искал процедурный юнит-тест, но не устаревший. Подумал, что это процедурно! = Наследие, поскольку в этом формате все еще создается новый код
canadiancreed

Ответы:

14

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

При этом ничто не запрещает проводить модульное тестирование на процедурной кодовой базе . В ООП большинство модульных тестов являются методами тестирования, передавая им некоторые параметры и ожидая либо результата, либо исключения определенного типа. Это также можно сделать с помощью процедурного кода; просто вместо методов тестирования вы будете тестировать функции .

Обратите внимание, что вам придется:

  • Выделите функции, которые вы должны проверить, и те, которые вам не нужны. В ООП это легко: частные методы не нужно тестировать, потому что вызывающие никогда не смогут получить к ним прямой доступ. Скорее всего, в вашем процедурном коде некоторые функции похожи на это и не нуждаются в тестах.

  • Подумайте о глобальном масштабе . Проблема существует и в ООП, но если вы скажете, что вам нужно тестировать код спагетти, есть вероятность, что у людей, которые написали этот код, есть вредные привычки, такие как слишком частое использование глобальной области видимости и выполнение некоторых безумных вещей, таких как изменение $_GETили $_POSTсоздание массивов внутри функции.

  • Разобраться с кодом вне функций. Это более сложный случай, но все же возможно. Либо вы require_onceна странице, чтобы посмотреть, что происходит, и перехватить вывод через ob_start/ob_get_clean , либо вы делаете HTTP-запрос из набора тестов и анализируете ответ, анализируя HTML. На самом деле это не тестирование пользовательского интерфейса: здесь вас не волнует, появляется ли кнопка на странице слева или справа, или если ссылка написана большими красными заглавными буквами или маленькими синими. Вам нужно найти некоторые элементы HTML через DOM и сравнить их содержимое с ожидаемым.

  • Проверьте коды ответов . require_onceс выходной буферизацией хорошо, но вы также должны проверить, как веб-приложение справляется с ошибками. Например, если ожидаемый результат теста 404 Not Found, необходимо выполнить HTTP-запрос, чтобы узнать ответ.

Арсений Мурзенко
источник
5

предложить отложить до тех пор, пока приложение не будет перенесено в надлежащую структуру ООП

Установите некоторые автоматические тесты до перехода на другую платформу, а не после. Добавляйте дополнительные тесты во время миграции, а не после. Если эти тесты являются «интеграционными тестами» или модульными тестами, вы должны решить сами, но обычно вы можете использовать свою любимую тестовую среду xUnit для обоих видов.

Док Браун
источник
5

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

Как эти тесты будут реализованы, будет отличаться между парадигмами и языками. Самое большое, что повлияет на вашу способность выполнять модульное тестирование, - это качество кода; меньше, чем парадигма используется. Помните, что модульное тестирование - это тестирование «кода» кода изолированно. Все, что влияет на вашу способность изолировать «блоки» кода, усложнит тестирование.

  • использование глобалов
  • побочные эффекты
  • тесно связанный код
  • плохо связанный код
  • большое количество условных
  • плохо спроектированные "единицы"

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

dietbuddha
источник
4

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

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

jmoreno
источник
-4

Я не думаю, что можно проводить настоящие модульные тесты с процедурным кодом. Основная проблема заключается в том, что каждая процедура, скорее всего, будет иметь много зависимостей, которые невозможно устранить. В лучшем случае тесты будут интеграционными. Я сделал то же самое много месяцев назад с модулями VB6 и модулями VBA в MS Access.

Тем не менее, если вы можете поставить испытательные леса вокруг методов, вызывающих наибольшую боль, это должно иметь ценность, верно?

Роб Грей
источник
5
-1: проблема в плохом дизайне и реализации, а не в процедурном коде. Так же, как вы можете написать ужасный ОП, вы можете написать отличный процедурный код.
Mattnz
@mattnz - я не уверен, как ваш комментарий относится к тому, что я сказал о том, чтобы быть или не в состоянии, к модульному тестированию процедурного кода.
Роб Грей
7
Процедурный код не равен спагетти. Весьма возможно написать правильно разработанный, модульный, четко разделенный, код с высокой когезией / низкой связью процедурным способом.
Марьян Венема
2
Хороший дизайн добавляет юнит-тестабильность в любой код, процедурный или нет.
Док Браун