Modulo di test unità: funzioni interne

5

Sto scrivendo una semplice suite di test dell'unità whitebox per un progetto su cui sto lavorando in C. Il progetto è suddiviso in moduli (ognuno ha un file .c con un file .h associato) e tutti i moduli vengono compilati insieme in un file .so .

Ovviamente, il file .h per ogni modulo contiene prototipi di funzioni per qualsiasi funzione che deve essere visibile agli altri moduli, ma non contiene prototipi per funzioni interne o di supporto.

La mia suite di test è una raccolta di file .c in una directory separata. Ogni file .c è responsabile della verifica di un modulo specifico, oltre a un file master che esegue tutti i test. Tutti questi file sono compilati in un unico file eseguibile. Attualmente questo binario è collegato al .so binario del progetto e sto #include nei file .h del progetto nei singoli file di test del modulo, a seconda dei casi. Questo mi permette di testare tutte le funzioni "pubbliche".

Vorrei anche testare direttamente alcune delle funzioni interne e di supporto. Posso pensare ad alcuni modi per farlo.

  1. Vai avanti e imposta tutte le funzioni di un modulo definite nel file di intestazione di quel modulo. Non voglio farlo perché sembra una cattiva pratica.
  2. Crea una seconda raccolta di file .h che contengono i prototipi per tutte le funzioni interne / di supporto e includi questi nei file di test appropriati. Sono riluttante a farlo perché sembra molto lavoro da mantenere.
  3. #include del file .c del modulo direttamente. Questo sarebbe facile da mantenere, ma mi farebbe sentire così sporco dentro.

Quale (se esiste) di queste tecniche è il modo migliore per farlo?

    
posta Woodrow Barlow 02.02.2016 - 17:59
fonte

3 risposte

2

Hai considerato di inserire le funzioni nel file di intestazione del modulo, ma inserendole in un blocco condizionato compilato che è abilitato solo nelle configurazioni di build che sono state testate? Sarebbe analogo avere una classe C ++ con funzioni pubbliche e private. Tuttavia, non è una buona opzione se si spedisce il file di intestazione agli utenti e si desidera mantenere tali funzioni segrete.

Includere il file C direttamente è un'opzione molto sporca, in quanto potrebbe non essere costruita esattamente come nel codice "reale" e può anche causare problemi di build quando le funzioni nell'intestazione sono implementate multiple tempi (nella libreria e il codice di prova). Detto questo, ho fatto ricorso a cose del genere a volte. Quando le cose non sono progettate per essere testate dall'inizio, a volte devi sporcarti un po '.

    
risposta data 03.02.2016 - 19:42
fonte
5

I test di unità dovrebbero essere solo per funzioni esterne.

Tuttavia, se hai un sacco di "codice interno", dovrebbe essere testato anche giusto? Allora, come?

Crea funzioni più piccole, separate dal tuo codice (un altro .c e .h), e usa quelle funzioni come una libreria che può essere testata dall'unità. Quindi dovresti essere in grado di testare quelle funzioni che sono utilizzate da quelle interne dall'API esterna senza alcun problema. Quello che non puoi testare è come usi queste funzioni. Ma il comportamento di quelle funzioni dovrebbe causare qualcosa che può essere testato sulle funzioni esterne, altrimenti, perché sono lì?

È facile da mantenere. Un dolore da fare se hai già un sacco di codice già scritto, ma fattibile.

    
risposta data 03.02.2016 - 10:07
fonte
0

La cosa con qualsiasi forma di test è che per essere utile, quando trova dei difetti, devi correggerli. Mentre è molto semplice cambiare i test per abbinare il comportamento del buggy, ciò invalida l'intero esercizio.

In questo caso, il test ha rilevato difetti: le funzioni interne hanno percorsi non raggiungibili dai test dell'API esterna. Forse sono solo controlli null ridondanti, forse ti mancano alcuni casi di test di livello superiore, forse la logica interna implementa un'astrazione più generale di quella effettivamente utilizzata.

In ogni caso, l'approccio giusto è quello di risolverli. Le verifiche nulle che non possono essere attivate dovrebbero essere asserzioni (che dovrebbero essere escluse dalla copertura del codice), i casi di test mancanti dovrebbero essere scritti, le astrazioni interne dovrebbero essere nel loro stesso file.

    
risposta data 04.02.2016 - 13:54
fonte

Leggi altre domande sui tag