Ajout de tests unitaires à un projet hérité, en clair C

12

Le titre dit tout. Mon entreprise réutilise un projet de micrologiciel hérité pour un dispositif de microcontrôleur, écrit complètement en clair C.

Il y a des parties qui sont manifestement erronées et doivent être modifiées, et venant d'un arrière-plan C # / TDD, je n'aime pas l'idée de refactoriser au hasard des trucs sans tests pour nous assurer que la fonctionnalité reste inchangée. De plus, j'ai vu que des bogues difficiles à trouver ont été introduits à de nombreuses reprises par le biais de moindres changements (ce qui, je pense, serait corrigé si des tests de régression étaient utilisés). Beaucoup de précautions doivent être prises pour éviter ces erreurs: il est difficile de suivre un tas de globaux autour du code.

Résumer:

  • Comment ajouter des tests unitaires au code étroitement couplé existant avant de le refactoriser?
  • Quels outils recommandez-vous? (moins important, mais toujours agréable à savoir)

Je ne suis pas directement impliqué dans l'écriture de ce code (ma responsabilité est une application qui interagira avec l'appareil de diverses manières), mais ce serait mauvais si de bons principes de programmation étaient laissés pour compte s'il y avait une chance qu'ils puissent être utilisés.

Groo
la source

Réponses:

7

Prenez une copie de Working Effective With Legacy Code de Michael Feathers. Il est destiné à faire face à de telles situations. Même s'il se concentre davantage sur les langages OO tels que C ++ et Java, je pense qu'il peut encore vous aider beaucoup.

On dirait qu'une partie de celui-ci (ou un premier projet d'article) est même disponible gratuitement ici .

Péter Török
la source
+1, merci. Mais, je crois que je suis assez bon pour refactoriser le code OO avec plus de code OO. Ce que je ne sais pas, c'est comment tester le code procédural et refactoriser le code procédural avec du code procédural moins couplé.
Groo
@Groo, le livre n'est pas une refactorisation en soi. Il s'agit de savoir comment transformer un tas de code spaghetti sans tests unitaires en un tas de code (un peu moins spaghetti) bien couvert de tests unitaires. Un tel code est difficile à tester, vous devez donc refactoriser d'abord afin de le rendre testable; Cependant, comme vous l'avez également mentionné, la refactorisation sans tests unitaires est risquée, il s'agit donc d'une situation de capture 22. Le livre vous explique comment apporter les modifications les plus petites et les plus sûres au code, ce qui vous permet de le couvrir de tests unitaires, et donc de commencer à le refactoriser sérieusement.
Péter Török
Ce livre est une bonne suggestion et il couvre C avec les langages OO.
ThomasW
7

Pour les techniques, le livre de Michael Feathers dans la réponse de Péter Török sera probablement assez complet. Si vous ne voulez pas aller au livre, je suggère un processus en trois étapes:

  1. examinez le code non testable et dupliquez de petites parties de la fonctionnalité de ce code en fonctions testables. Il est important que les nouvelles fonctions aient un comportement qui est évidemment équivalent à la fonction que vous essayez de dupliquer - je ne préconise pas en fait d'écrire des tests unitaires autour du code hérité, vous devez donc être très prudent et limiter votre portée, dans afin de maintenir la confiance dans le refactoring.
  2. écrire des tests unitaires autour de ces nouvelles fonctions.
  3. modifier le code d'origine pour appeler les nouvelles fonctions.

Répétez ce processus plusieurs fois et vous devriez constater que la qualité de la base de code héritée a considérablement augmenté.

En ce qui concerne les outils, notez que C ++ peut appeler en C, donc tout framework de test unitaire C ++ peut être utilisé pour tester le code C. Par exemple, nous utilisons CPPUnit pour tester à l'unité un tas de code C dans notre projet.

Aidan Cully
la source
+1 merci pour les conseils et le lien CPPUnit .
Groo