2015-02-23 33 views
6

Ho scritto una classe Matrix e ho controllato che non consentiva la moltiplicazione di matrici di dimensioni incompatibili utilizzando eccezioni C++. Ho scritto test unitari per verificare il comportamento, e si aspettano che venga lanciata un'eccezione.Test di unità per errori di compilazione con C++

Ora sto cambiando la dimensione di Matrix da variabile di runtime a parametro di modello. Se riuscirò a farlo correttamente, il codice che tenterà di moltiplicare le matrici di dimensioni errate non verrà nemmeno compilato.

Sembrerebbe che ora questi test unitari siano ridondanti. Tuttavia, poiché non so come cambierò il mio codice in futuro, e cosa si romperà, voglio ancora implementare dei test per questo. Se prima mi aspettavo che i miei test generassero eccezioni specifiche in punti specifici, ora voglio che il mio test generi errori specifici di compilazione in punti specifici.

Qual è il modo migliore per farlo? Immagino una specie di meccanismo basato su Makefile e script di shell che aspetterebbe un codice di errore specifico - o dovrei provare qualcos'altro? Questa idea è una pratica comune o completa follia?

Modifica: Certamente, "Test di unità" non è un nome appropriato per questo tipo di meccanismo, lo so, ma per ora non riesco a pensare a un modo migliore. Ci sono già tre autori di commenti che hanno dedicato il loro prezioso tempo e impegno a spiegarmi quali sono i test unitari e quali no. Sfortunatamente, pur essendo tecnicamente vero, questo non aiuta a risolvere un problema reale qui a portata di mano.

Edit 2: Questo è BDD scenario che voglio per verificare:

  • Dato due matrici di dimensioni 2x2 e 3x3
  • Quando l'utente tenta di moltiplicarle
  • Quindi ottiene un errore

Prima, che l'errore era un errore di runtime e il test per esso era banale. Ma ora sono diventato un errore in fase di compilazione, e non vedo come posso continuare a testare automaticamente questo scenario e confermare, su ogni commit (ho dei test unitari nei miei git hook) che mi dà ancora un errore.

+4

test unitari sono per il rilevamento di errori di esecuzione. I compilatori sono per rilevare errori di compilazione del tempo. – RPGillespie

+0

I test di unità non rilevano errori di runtime. I test unitari verificano che gli errori di runtime previsti vengano rilevati dal programma stesso o dal suo runtime. Lo strumento che sto cercando (hai ragione, unit test non è il nome migliore per esso) non rileva gli errori di compilazione, ma controlla che il compilatore li rilevi. –

+2

I test unitari devono testare le funzioni della scatola nera le cui implementazioni internamente possono essere modificate, in modo da poter verificare che la modifica degli interni non abbia compromesso la sua funzionalità. Suggerirei di creare API indipendenti dall'implementazione per le vostre matrici. Una funzione come 'bool canMultiply (Matrix & a, Matrix & b)' può usare tutto ciò che vuole internamente ed è verificabile con il test dell'unità. – RPGillespie

risposta

1

È innocuo mantenere il test di "unità", anche se il nuovo stile di codice template rende "impossibile" la mancata corrispondenza della matrice in fase di esecuzione. Potresti ancora avere un bug che arriva fino al tempo di esecuzione e, come dici tu, il codice potrebbe cambiare di nuovo.

Se si utilizza gcc, gcc utilizza DejaGnu per testare se stesso. Dovrebbe essere abbastanza robusto da rilevare errori di compilazione gcc.

+0

Ma se lo tengo così com'è, l'errore di runtime diventa errore di compilazione, e non riesco a eseguire i miei test di unità, perché non vengono compilati. Mentre l'errore di compilazione è il risultato desiderato, che voglio verificare, voglio verificarlo pur avendo la possibilità di eseguire tutti gli altri test delle mie unità. Come posso ottenerlo? –

+0

Sposta i tuoi test di unità in scriope che si aspettano errori di compilazione. Usa Python o make/bash –

+0

Aspettarsi errori di compilazione C++ è piuttosto difficile - potresti conoscere qualche framework per implementare alcuni test? –

0

Non ho ancora un rappresentante sufficiente per commentare la risposta di @Paul Evans quindi, per favore, dimmi se non dovrei aver appena risposto.

@Paul Evans raccomanda che DejaGnu e io supportiamo questa scelta. Tuttavia, se si desidera produrre errori di compilazione più comprensibili (gli errori di compilazione del modello tendono a diventare disordinati) è possibile utilizzare static_asserts.

Sono standard dal C++ 11 (anche se dovresti controllare se il compilatore può usarli) e sono simili alle asserzioni tradizionali, solo che vengono controllati in fase di compilazione e possono visualizzare un messaggio di errore personalizzato.

Ecco la documentazione, se si desidera controllare fuori: http://en.cppreference.com/w/cpp/language/static_assert