Test unitario per codice C ++ – Strumenti e metodologia

Sto lavorando su un grande sistema c ++ che è stato in sviluppo da qualche anno. Come parte di uno sforzo per migliorare la qualità del codice esistente, ci siamo impegnati in un grande progetto di refactoring a lungo termine.

Conoscete un buon strumento che può aiutarmi a scrivere test unitari in C ++? Forse qualcosa di simile a Junit o Nunit?

Qualcuno può dare qualche buon consiglio sulla metodologia di scrivere unit test per moduli che sono stati scritti senza test unitari in mente?

Applicare i test unitari al codice legacy è stata la vera ragione per cui è stato scritto Working Effectively con Legacy Code . Michael Feathers è l’autore – come menzionato in altre risposte, è stato coinvolto nella creazione di CppUnit e CppUnitLite .

testo alternativo http://sofit.miximages.com/refactoring/51RCXGPXQ8L._SL160_AA115_.jpg

Google ha recentemente rilasciato la propria libreria per le app C ++ di testing unitario, chiamata Google Test.

Progetto su Google Code

Dai un’occhiata a un eccellente confronto tra diverse suite disponibili. L’autore dell’articolo in seguito ha sviluppato UnitTest ++ .

Ciò che mi piace particolarmente (a parte il fatto che gestisce eccezioni, ecc. Bene) è che c’è una quantità molto limitata di “amministrazione” attorno ai casi di test e alla definizione dei dispositivi di prova.

Boost ha una libreria di test che contiene il supporto per il test delle unità. Potrebbe valere la pena di provarlo.

Noel Llopis di Games From Within è l’autore di Exploring the C ++ Unit Testing Framework Jungle , una valutazione completa (ma ora datata) dei vari framework di test dell’unità C ++, oltre a un libro sulla programmazione dei giochi.

Ha usato CppUnitLite per un po ‘di tempo, sistemando varie cose, ma alla fine ha unito le forze con un altro autore di librerie di test di unità e ha prodotto UnitTest ++ . Usiamo UnitTest ++ qui, e mi piace molto, finora. Ha (per me) il giusto equilibrio di potenza con un ingombro ridotto.

Ho usato soluzioni homegrown, CxxTest (che richiede Perl) e boost :: test. Quando ho implementato i test unitari qui al mio attuale lavoro, è arrivato a UnitTest ++ vs boost :: test.

Mi piace molto la maggior parte delle librerie di boost che ho usato, ma IMHO, boost :: test è un po ‘troppo pesante. In particolare, non mi piace che sia necessario (AFAIK) implementare il programma principale del cablaggio di test usando una macro boost :: test. So che non è TDD “puro”, ma a volte abbiamo bisogno di un modo per eseguire test da un’applicazione GUI, ad esempio quando viene passato un flag di test speciale nella riga di comando, e boost :: test non supporta questo tipo di scenario.

UnitTest ++ è stato il framework di test più semplice da configurare e utilizzare che ho incontrato nella mia (limitata) esperienza.

Sto usando l’eccellente libreria Boost.Test in combinazione con una libreria di tartarughe meno conosciuta ma davvero eccezionale: una biblioteca di oggetti finti basata su boost.

Come un esempio di codice parla meglio delle parole, immagina che ti piacerebbe testare un object calculator che funziona su un’interfaccia view (che è l’esempio introduttivo di Turtle):

 // declares a 'mock_view' class implementing 'view' MOCK_BASE_CLASS( mock_view, view ) { // implements the 'display' method from 'view' (taking 1 argument) MOCK_METHOD( display, 1 ) }; BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) { mock_view v; calculator c( v ); // expects the 'display' method to be called once with a parameter value equal to 0 MOCK_EXPECT( v, display ).once().with( 0 ); c.add( 0, 0 ); } 

Vedi quanto è facile e verboso dichiarare le aspettative sull’object finto? Ovviamente, il test fallisce se le aspettative non vengono soddisfatte.

Ho appena spinto la mia struttura, CATCH , là fuori. È ancora in fase di sviluppo, ma credo che superi già molti altri framework. Persone diverse hanno criteri diversi, ma ho cercato di coprire la maggior parte del terreno senza troppi compromessi. Dai un’occhiata al mio post di blog collegato per un assaggiatore. Le mie cinque funzioni principali sono:

  • Solo intestazione
  • Registrazione automatica di test basati su funzioni e metodi
  • Decomprime le espressioni C ++ standard in LHS e RHS (quindi non hai bisogno di un’intera famiglia di macro assert).
  • Supporto per sezioni nidificate all’interno di un dispositivo basato su funzioni
  • Assegna un nome ai test utilizzando il linguaggio naturale – vengono generati nomi di funzioni / metodi

Ha anche associazioni Objective-C.

CxxTest è un framework JUnit / CppUnit / xUnit-like leggero, facile da usare e multipiattaforma per C ++.

UnitTest ++ , piccolo e semplice.

Attualmente sto cercando un unit test e un framework finto che possa essere utilizzato nella nostra azienda per una lunga base di codice. Come sapete, l’ elenco dei framework di test unitari per c ++ è lungo, quindi ho applicato alcuni filtri per ridurlo a una mano piena che può essere esaminata più da vicino. Il primo criterio di filtro era che doveva essere gratuito. Il secondo criterio era l’attività del progetto. Ho anche cercato delle strutture di derisione perché ne hai bisogno se vuoi scrivere dei test unitari.

Ho trovato il seguente elenco (approssimativamente) ordinato per attività, l’attività più alta in alto:

  • GoogleTest / GoogleMock: molti contributori e utilizzati da Google stessa. Questo probabilmente sarà qui per un po ‘di tempo e riceverà aggiornamenti. Per il mio codice base privato passerò a questa combinazione nella speranza di saltare sul treno più veloce.

  • BoostTest + Turtle: non aggiornato spesso, ma il framework di testing è una parte di boost, quindi dovrebbe essere mantenuto. La tartaruga d’altra parte è mantenuta principalmente da un ragazzo, ma ha risentito l’attività quindi non è morto. Ho fatto quasi tutta la mia esperienza di test con questa combinazione perché abbiamo già utilizzato la libreria boost al mio precedente lavoro e attualmente la uso per il mio codice privato.

  • CUTUTest: fornisce test e mocking . Questo progetto è stato attivo dal 2008 al 2015 e ha un’attività molto recente. Questa scoperta è stata una piccola sorpresa perché molti progetti con un’attività significativamente inferiore si verificano più spesso durante la ricerca sul Web (come CppUnit che ha avuto l’ultimo aggiornamento nel 2013). Non ho guardato più in profondità in questo modo, quindi non posso dire nulla sui dettagli. Edit (16.12.2015): Recentemente l’ho provato e ho trovato questo framework un po ‘goffo e “C-stylish”, specialmente quando si usano le classi di simulazione. Inoltre sembrava avere una più piccola varietà di asserzioni, quindi altri quadri. Penso che il suo principale punto di forza sia che può essere utilizzato con progetti C puri.

  • QTest: la libreria di test fornita con il framework Qt. La manutenzione dovrebbe essere garantita per un po ‘di tempo, ma io la uso piuttosto come libreria di supporto, perché la registrazione dei test è IMO più maldestra che in altri framework. Per quanto ho capito, ti costringe ad avere un test-exe per test-fixture. Ma le funzioni di test helper possono essere utili quando si testano il codice Qt-Gui. Non ha derisioni.

  • Catch: ha attività recenti ma è sviluppato principalmente da un ragazzo. La cosa bella di questo framework è l’approccio di fixture alternativo che ti permette di scrivere codice di dispositivo riutilizzabile nel test stesso. Ti permette anche di impostare i nomi dei test come stringhe, il che è bello quando tendi a scrivere frasi intere come nomi di test. Vorrei che questo stile venisse strappato e inserito in googleTest 😉

Framework mock

Il numero di framework di simulazione è molto più piccolo rispetto al numero di framework di test, ma quelli che ho trovato hanno attività recenti.

  • Hippomock : attivo dal 2008 unitl ora ma solo con bassa intensità.

  • FakeIt : attivo dal 2013 unitl ora ma più o meno sviluppato da un ragazzo.

Conclusione

Se la tua base di codice è triggers a lungo termine, scegli tra BoostTest + Turtle e GoogleTest + GoogleMock . Penso che quei due avranno una manutenzione a lungo termine. Se hai solo un codice base di breve durata puoi provare Catch che ha una bella syntax. Allora avresti bisogno di scegliere anche una struttura di derisione. Se lavori con Visual Studio, puoi scaricare gli adattatori per run-test per BoostTest e GoogleTest, che ti permetteranno di eseguire i test con la GUI del test runner integrato in VS.

Vedi anche le risposte alla domanda strettamente correlata “scegliere uno strumento / framework di test dell’unità c ++”, qui

C’è anche TUT , Template-Unit-Test, un framework basato su template. La sua syntax è imbarazzante (alcuni lo chiamano abuso di template), ma il suo vantaggio principale è che è tutto contenuto in un singolo file di intestazione .

Qui troverai un esempio di test unitario scritto con TUT .

Ho provato CPPunit e non è molto facile da usare.

L’unica alternativa che conosco è l’uso di C ++. NET per avvolgere le tue classi C ++ e i test di unità di scrittura con uno dei framework di test delle unità .NET (NUnit, MBUnit ecc.)

CppUTest è una struttura eccellente e leggera per i test unitari C e C ++.

Michael Feathers of ObjectMentor è stato determinante nello sviluppo di CppUnit e CppUnitLite.

Ora raccomanda CppUnitLite

Dai un’occhiata a CUnitWin32 . È scritto per MS Visual C. Include un esempio.

Date un’occhiata a cfix ( http://www.cfix-testing.org ), è specializzato nello sviluppo di Windows C / C ++ e supporta sia la modalità utente che il test dell’unità in modalità kernel.

Se si utilizza Visual Studio 2008 SP1, si consiglia vivamente di utilizzare MSTest per scrivere i test delle unità. Quindi uso Google mock per scrivere i mock. L’integrazione con l’IDE è ideale e consente e non porta il sovraccarico di CPPunit in termini di modifica di tre posizioni per l’aggiunta di un test.

Penso che VisualAssert stia facendo un ottimo lavoro nell’integrazione VS. Permette di eseguire ed eseguire il debug dei test da VS e non è necessario creare un eseguibile per eseguire i test.

Controlla il fruttosio: http://sourceforge.net/projects/fructose/

È un framework molto semplice, contenente solo file di intestazione e quindi facile da trasportare.

Sto usando MS Test con Typemock Isolator ++ . Provaci!