Добавление модульных тестов в устаревший простой C-проект

12

Название говорит само за себя. Моя компания повторно использует устаревший проект прошивки для устройства с микроконтроллером, полностью написанный на простом C.

Есть части, которые явно не соответствуют действительности и нуждаются в изменении, и исходят из опыта C # / TDD. Мне не нравится идея случайного рефакторинга без тестов, чтобы гарантировать, что функциональность останется неизменной. Кроме того, я видел, что трудно найти ошибки, которые были внесены во многих случаях из-за малейших изменений (что, я считаю, было бы исправлено, если бы использовалось регрессионное тестирование). Чтобы избежать этих ошибок, нужно быть очень осторожным: трудно отследить кучу глобальных переменных вокруг кода.

Подвести итоги:

  • Как добавить модульные тесты в существующий тесно связанный код перед рефакторингом?
  • Какие инструменты вы рекомендуете? (менее важно, но все же приятно знать)

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

Гру
источник

Ответы:

7

Возьмите копию « Работать эффективно с устаревшим кодом » Майкла Фезерса. Он предназначен для решения таких ситуаций. Несмотря на то, что он больше ориентирован на ОО-языки, такие как C ++ и Java, я считаю, что он все еще может вам сильно помочь.

Похоже, что часть этого (или ранняя черновик статьи) даже доступна бесплатно здесь .

Петер Тёрёк
источник
+1, спасибо. Но я считаю, что я достаточно хорош в рефакторинге ОО-кода с использованием большего ОО-кода. Чего я не знаю, так это как тестировать процедурный код и реорганизовать процедурный код с менее связанным процедурным кодом.
Groo
@ Гроу, книга не о рефакторинге как таковом. Речь идет о том, как преобразовать кучу спагетти-кода без каких-либо модульных тестов в кучу (несколько менее спагетти) кода, хорошо покрытого модульными тестами. Такой код сложно протестировать, поэтому сначала нужно провести рефакторинг, чтобы сделать его тестируемым; однако, как вы также упомянули, рефакторинг без юнит-тестов опасен, так что это сложная ситуация. В этой книге вы узнаете, как внести в код самые маленькие, самые безопасные изменения, которые позволят вам выполнить его с помощью модульных тестов, а затем приступить к его рефакторингу.
Петер Тёрёк
Эта книга является хорошим предложением, и она охватывает С наряду с ОО-языками.
ThomasW
7

Для техники, вероятно, Майкл Перья бронирование в ответ Петера Török в будет довольно исчерпывающим. Если вы не хотите идти в книгу, я предлагаю трехэтапный процесс:

  1. исследовать не тестируемый код и дублировать небольшие части функциональности этого кода в тестируемые функции. Важно, чтобы у новых функций было поведение, которое, очевидно, эквивалентно функции, которую вы пытаетесь продублировать - я на самом деле не сторонник написания юнит-тестов вокруг унаследованного кода, поэтому вам нужно быть очень осторожным и ограничивать свои возможности, Чтобы сохранить уверенность в рефакторинге.
  2. написать модульные тесты вокруг этих новых функций.
  3. измените исходный код для вызова новых функций.

Повторите этот процесс несколько раз, и вы обнаружите, что качество устаревшей базы кода значительно возросло.

Что касается инструментов, обратите внимание, что C ++ может вызывать C, поэтому любая среда модульного тестирования C ++ может использоваться для тестирования кода C. Например, мы используем CPPUnit для модульного тестирования группы кода C в нашем проекте.

Эйдан Калли
источник
+1 спасибо за советы и ссылку CPPUnit .
Groo