Agregar pruebas unitarias a un proyecto de C simple heredado

12

El título lo dice todo. Mi compañía está reutilizando un proyecto de firmware heredado para un dispositivo de microcontrolador, escrito completamente en letra C.

Hay partes que obviamente están mal y que necesitan ser cambiadas, y que provienen de un fondo C # / TDD. No me gusta la idea de refactorizar aleatoriamente cosas sin pruebas para asegurarnos que la funcionalidad permanezca sin cambios. Además, he visto que los errores difíciles de encontrar se introdujeron en muchas ocasiones a través de cambios mínimos (que es algo que creo que se solucionaría si se usaran pruebas de regresión). Se debe tener mucho cuidado para evitar estos errores: es difícil rastrear un montón de globales alrededor del código.

Para resumir:

  • ¿Cómo agrega pruebas unitarias al código existente estrechamente acoplado antes de refactorizar?
  • ¿Qué herramientas me recomiendan? (menos importante, pero aún así es bueno saberlo)

No estoy directamente involucrado en escribir este código (mi responsabilidad es una aplicación que interactuará con el dispositivo de varias maneras), pero sería malo si se dejaran atrás los buenos principios de programación si existiera la posibilidad de que pudieran usarse.

Groo
fuente

Respuestas:

7

Obtenga una copia de Trabajar eficazmente con código heredado de Michael Feathers. Está destinado a hacer frente a tales situaciones. Aunque se centra más en lenguajes OO como C ++ y Java, creo que aún puede ayudarte mucho.

Parece que parte de él (o un borrador preliminar del artículo) está incluso disponible de forma gratuita aquí .

Péter Török
fuente
+1, gracias. Pero, creo que soy bastante bueno refactorizando el código OO con más código OO. Lo que no sé es cómo probar el código de procedimiento y refactorizar el código de procedimiento con un código de procedimiento menos acoplado.
Groo
@Groo, el libro no se trata de refactorizar per se. Se trata de cómo transformar un montón de código de espagueti sin pruebas unitarias en un montón de código (algo menos de espagueti) bien cubierto con pruebas unitarias. Este código es difícil de probar, por lo que debe refactorizar primero para que sea comprobable; sin embargo, como usted también mencionó, la refactorización sin pruebas unitarias es arriesgada, por lo que es una situación difícil. El libro lo guía sobre cómo realizar los cambios más pequeños y seguros en el código que le permiten cubrirlo con pruebas unitarias, y luego comenzar a refactorizarlo en serio.
Péter Török
Ese libro es una buena sugerencia y cubre C junto con los lenguajes OO.
ThomasW
7

Para las técnicas, probablemente el libro de Michael Feathers en la respuesta de Péter Török será bastante completo. Si no quieres ir al libro, te sugiero un proceso de tres pasos:

  1. examine el código no comprobable y duplique pequeñas partes de la funcionalidad de ese código en funciones comprobables. Es importante que las nuevas funciones tengan un comportamiento que obviamente es equivalente a la función que está intentando duplicar: en realidad no estoy abogando por escribir pruebas unitarias en torno al código heredado, por lo que debe tener mucho cuidado y limitar su alcance, en Para mantener la confianza en la refactorización.
  2. escribir pruebas unitarias en torno a esas nuevas funciones.
  3. modifique el código original para llamar a las nuevas funciones.

Repita este proceso varias veces, y debería encontrar que la calidad de la base de código heredada ha aumentado significativamente.

En cuanto a las herramientas, tenga en cuenta que C ++ puede llamar a C, por lo que cualquier marco de pruebas unitarias de C ++ se puede utilizar para probar el código C. Por ejemplo, estamos usando CPPUnit para probar un montón de código C en nuestro proyecto.

Aidan Cully
fuente
+1 gracias por los consejos y el enlace CPPUnit .
Groo