Aggiunta di unit test a un progetto C legacy e semplice


12

Il titolo dice tutto. La mia azienda sta riutilizzando un progetto firmware legacy per un dispositivo microcontrollore, scritto completamente in semplice C.

Ci sono parti che sono ovviamente sbagliate e devono essere cambiate, e che provengono da un background C # / TDD Non mi piace l'idea di eseguire il refactoring casuale di elementi senza test per assicurarci che la funzionalità rimanga invariata. Inoltre, ho visto che i bug difficili da trovare sono stati introdotti in molte occasioni attraverso i minimi cambiamenti (il che è qualcosa che credo sarebbe stato risolto se fosse stato utilizzato il test di regressione). Bisogna fare molta attenzione per evitare questi errori: è difficile rintracciare un sacco di globali attorno al codice.

Riassumere:

  • Come si aggiungono i test unitari al codice strettamente accoppiato esistente prima del refactoring?
  • Quali strumenti mi consigliate? (meno importante, ma comunque bello da sapere)

Non sono direttamente coinvolto nella stesura di questo codice (la mia responsabilità è un'app che interagirà con il dispositivo in vari modi), ma sarebbe male se si lasciassero buoni principi di programmazione se ci fosse la possibilità che possano essere usati.

Risposte:


7

Prendi una copia di Working Effectively With Legacy Code di Michael Feathers. Ha lo scopo di affrontare tali situazioni. Anche se si concentra maggiormente su linguaggi OO come C ++ e Java, credo che potrebbe ancora aiutarti molto.

Sembra che parte di esso (o una prima bozza di articolo) sia persino disponibile gratuitamente qui .


+1, grazie. Ma credo di essere abbastanza bravo nel refactoring del codice OO con più codice OO. Quello che non so è come testare il codice procedurale e il refactoring codice procedurale con un codice procedurale meno accoppiato.
Groo,

@Groo, il libro non parla di refactoring di per sé. Si tratta di come trasformare un gruppo di codice spaghetti senza alcun test unitario in un gruppo di codice (un po 'meno spaghetti) ben coperto da test unitari. Tale codice è difficile da testare, quindi è necessario prima effettuare il refactoring per renderlo testabile; tuttavia, come hai già detto, il refactoring senza unit test è rischioso, quindi è una situazione di cattura 22. Il libro ti guida su come apportare le modifiche più piccole e sicure al codice che ti consentono di coprirlo con test unitari, quindi successivamente inizia a refactoring sul serio.
Péter Török,

Quel libro è un buon suggerimento e copre C insieme alle lingue OO.
ThomasW l'

7

Per quanto riguarda le tecniche, probabilmente il libro di Michael Feathers nella risposta di Péter Török sarà piuttosto completo. Se non vuoi andare al libro, ti suggerisco una procedura in tre passaggi:

  1. esaminare il codice non testabile e duplicare piccole parti della funzionalità di quel codice in funzioni verificabili. È importante che le nuove funzioni abbiano un comportamento che è ovviamente equivalente alla funzione che stai cercando di duplicare: in realtà non sto sostenendo la scrittura di unit test intorno al codice legacy, quindi devi essere molto attento e limitare il tuo ambito, in per mantenere la fiducia nel refactoring.
  2. scrivere test unitari attorno a queste nuove funzioni.
  3. modificare il codice originale per chiamare le nuove funzioni.

Ripeti questo processo alcune volte e dovresti scoprire che la qualità della base di codice legacy è aumentata in modo significativo.

Per quanto riguarda gli strumenti, nota che C ++ può chiamare in C, quindi qualsiasi framework di test di unità C ++ può essere usato per testare il codice C. Ad esempio, stiamo usando CPPUnit per testare un gruppo di codice C nel nostro progetto.


+1 grazie per i suggerimenti e il link CPPUnit .
Groo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.