Qualcuno sta facendo un TDD "reale" con Visual-C ++ e, in caso affermativo, come lo fanno? [chiuso]

10

Test Driven Development implica scrivere il test prima del codice e in seguito a < a href="http://en.wikipedia.org/wiki/Test-driven_development#Test-driven_development_cycle"> ciclo certo :

  • Scrivi test
  • Verifica test (eseguito)
  • Scrivi codice di produzione
  • Verifica test (eseguito)
  • Pulisci codice produzione
  • Verifica test (eseguito)

Per quanto mi riguarda, questo è possibile solo se la tua soluzione di sviluppo ti consente di passare molto rapidamente tra il codice di produzione e di prova e di eseguire il test per una parte di codice di produzione in modo estremamente rapido.

Ora, sebbene esista un gran numero di quadri di test unitario per C ++ (sto usando Bost.Test atm.) sembra che non esistano realmente decenti (per nativo C ++ ) Soluzione Visual Studio (Plugin) che rende sopportabile il ciclo TDD indipendentemente dal framework utilizzato.

"Bearable" significa che è un'azione con un clic per eseguire un test per un determinato file cpp senza dover impostare manualmente un progetto di test separato, ecc. "Bearable" significa anche che inizia un semplice test (collegamento!) e funziona molto rapidamente.

Quindi quali strumenti (plugin) e tecniche sono disponibili per rendere possibile il ciclo TDD per lo sviluppo nativo in C ++ con Visual Studio?

Nota: sto bene con strumenti gratuiti o "commerciali".

Si prega di : No suggerimenti del framework. (A meno che il framework non abbia un plug-in dedicato di Visual Studio e tu voglia consigliare il plugin.)

Modifica Nota : le risposte finora hanno fornito collegamenti su come integrare un framework di test delle unità in Visual Studio. Le risorse più o meno descrivono come ottenere la struttura UT per compilare e ottenere i primi test in esecuzione. Questo è non di cosa tratta questa domanda. Sono dell'opinione che funzioni davvero in modo produttivo, avendo i Test delle unità in un manuale mantenuto (!), separato da vcproj le vostre lezioni di produzione aggiungeranno così tanto spese generali che TDD "non è possibile". Per quanto ne so, non si non si aggiungono "progetti" aggiuntivi a una cosa Java o C # per abilitare Test unitari e TDD, e per una buona ragione. Questo dovrebbe essere possibile con C ++ dato gli strumenti giusti, ma sembra (questa domanda riguarda) che ci sono pochissimi strumenti per TDD / C ++ / VS.

Cercando su google, ho trovato uno strumento, VisualAssert , che sembra mirare nella giusta direzione. Tuttavia, a dire il vero, non sembra essere molto diffuso (rispetto a CppUnit, Boost.Test ecc.).

Modifica: vorrei aggiungere un commento al contesto per questa domanda. Penso che faccia un buon riassunto del problema (parte del problema) (commento di Billy ONeal )

Visual Studio does not use "build scripts" that are reasonably editable by the user. One project produces one binary. Moreover, Java has the property that Java never builds a complete binary -- the binary you build is just a ZIP of the class files. Therefore it's possible to compile separately then JAR together manually (using e.g. 7z). C++ and C# both actually link their binaries, so generally speaking you can't write a script like that. The closest you can get is to compile everything separately and then do two linkings (one for production, one for testing).

    
posta Martin Ba 05.09.2011 - 15:08
fonte

9 risposte

4

Ho scritto una serie di blog in 5 parti sul fare TDD con C ++ e Visual Studio: parte 1 , parte 2 , parte 3 , parte 4 , part 5 .

Non sono sicuro del perché tu dica di non realizzare progetti extra in C # per fare TDD, perché è quello che ho sempre fatto con NUnit e sembra tipico di quello che fanno gli altri con NUnit. Il motivo è semplice: tenere sempre il codice di prova separato dal codice di produzione. Per C ++ con Visual Studio, questo significa progetti separati proprio come fa per C # e NUnit. Da quello che so del mondo Java, questo è anche comune lì.

Ovviamente, ognuno ha idee diverse su ciò che è "sopportabile" per fare TDD. Ho praticato il metodo che ho descritto nel mio post sul blog per anni gravi e lo trovo molto sopportabile. Il linguaggio C ++ è compilato e la compilazione può essere lenta quando il sistema sottoposto a test è altamente accoppiato. Semplicemente non c'è da allontanarsi da quello senza rifattorizzare un design più liberamente abbinato.

La mia "azione con un clic" è "Build Solution". Se si sta costruendo troppo, puoi sempre scaricare progetti irrilevanti mentre lavori e quindi Build Solution creerà solo il sottoinsieme minimo di progetti necessario per essere aggiornato a seguito delle tue modifiche.

Certo, la natura del tempo di compilazione del C ++ fa sì che ci voglia un po 'più di tempo in ogni ciclo del processo TDD rispetto a NUnit e C #, ma la sicurezza che ottengo dal mio codice C ++ ben testato vale la pena. Altrimenti passerò molto più tempo nel debugger. Vorrei essere prudente nell'usare gmock in quanto può aggiungere sostanzialmente per testare il tempo di compilazione. Finora mi sono allontanato per lo più con oggetti "finti" leggeri e raramente ho bisogno della funzionalità completa dei mock. I framework di simulazione per C ++ sono strongmente basati su template e questo può aumentare significativamente il tempo di compilazione, quindi dovrebbero essere riservati a dove hai veramente bisogno di un finto e un falso non funzionerà.

Ho preso in considerazione la creazione di un wizard del progetto di test dell'unità Boost.Test per automatizzare parte della natura della piastra della caldaia nel creare il progetto di test per il codice di produzione, ma dopo averlo fatto un paio di volte non è poi così difficile farlo manualmente .

Per quanto riguarda le soluzioni con molti (150?) progetti, ci sono modi per far fronte anche a questo. Uno ovvio è trovare gruppi di progetti correlati e raggrupparli insieme e iniziare a consumarli / pubblicarli come un'unità. Se hai veramente bisogno di ricostruire / toccare tutti i 150 progetti per piccole modifiche che stai facendo durante un ciclo TDD, allora il tuo codice è talmente accoppiato che i test unitari non faranno molta differenza.

Guardando il link IDE netbeans, trovo che eye candy di avere qualcosa che analizza il test output e mostra una piccola riga di test in una finestra con un simbolo verde o rosso accanto ad essa qualcosa che pensavo mi sarebbe mancato venendo da NUnit, ma in realtà non mi mancava. Ho trovato più utile per la compilazione semplicemente fallire e quindi ho potuto fare doppio clic nella finestra degli errori per posizionare il cursore nella posizione della dichiarazione fallita.

    
risposta data 15.11.2011 - 23:54
fonte
2

Non sto usando Visual-C ++, ma sto eseguendo TDD con C ++, usando googletest e googlemock, con QtCreator come IDE. Anni fa avevo un setup simile con Visual-C ++ ma usando un diverso framework di test delle unità.

Ciò che ho trovato utile è separare il progetto in alcuni sottoprogetti.

  1. Una libreria statica o dinamica che contiene il 99% del codice sorgente del progetto attuale.
  2. Un progetto costituito principalmente da un metodo main () per eseguire il programma normale.
  3. Un progetto di test che contiene un main () per eseguire il mio framework di test e molti file contenenti test e oggetti fittizi.

Con questa configurazione, il mio IDE si occupa di aggiungere file a vari progetti e se le dipendenze vengono determinate correttamente, posso eseguire tutti i miei test di unità con una ricostruzione parziale. Ho persino installato il programma per eseguire tutti i miei test subito dopo la creazione. Jenkins, l'IC che sto attualmente utilizzando, esegue anche e fornisce risultati di test e dati di copertura.

Potrebbe essere possibile aggiungere un launcher personalizzato nel tuo IDE per un file per eseguire i test unitari per il file Foo.cpp se ti è capitato di dare un nome a tutti i test unitari per Foo sotto l'apparecchio di prova TestFoo. Come impostarlo precisamente per Visual-C ++ non sono sicuro, ma penso che sia possibile.

    
risposta data 13.10.2011 - 20:33
fonte
2

Uso MSTest per testare il codice C ++ nativo.
Ecco l'ottimo post sul blog in questo modo: link

Sì, ci saranno almeno due progetti, uno per l'applicazione stessa, uno per i test.
Invece di creare un terzo progetto con la libreria statica, aggiungo semplicemente l'origine dell'applicazione per testare il progetto, quindi la soluzione ha questo aspetto:

[-] Solution 'Foo'      Foo\Foo.sln
 |-[-] Foo              Foo\Foo\Foo.vcproj
 |  |-[-] include
 |  |  |- foo.h         Foo\Foo\foo.h
 |  |  |- bar.h         Foo\Foo\bar.h
 |  |
 |  |-[-] source
 |     |- foo.cpp       Foo\Foo\foo.cpp
 |
 |-[-] Foo.Tests        Foo\Foo.Tests\Foo.Tests.vcproj
    |                        (Additional include directory: "..\Foo")
    |-[-] include
    |  |- FakeBar.h     Foo\Foo.Tests\FakeBar.h
    |
    |-[-] source
       |-[-] app
       |  |- foo.cpp    Foo\Foo\foo.cpp    -- not in Foo.Tests\
       |
       |-[-] unit-tests
          |- foo_Tests.cpp   Foo\Foo.Tests\foo_Tests.cpp
          |- bar_Tests.cpp   Foo\Foo.Tests\bar_Tests.cpp
    
risposta data 16.11.2011 - 14:02
fonte
2

Forse un po 'tardi, ma se ho letto correttamente la tua domanda, stai cercando tecniche per migliorare il ciclo TDD? Non è stato menzionato qui, ma hai guardato gli eventi post-build in VS?

Le nostre soluzioni sono generalmente organizzate (con le dipendenze di progetto mostrate) ...

MAIN-APP > LIB1, LIB2, UNIT-TEST-APP
UNIT-TEST-LIB1 > LIB1
UNIT-TEST-LIB2 > LIB2
UNIT-TEST-APP > UNIT-TEST-LIB1, UNIT-TEST-LIB2

L'evento post-build di MAIN-APP eseguirà UNIT-TEST-APP

L'evento post-build di UNIT-TEST-APP funzionerà da solo (basta mettere '$ (TargetPath)' come comando da eseguire nell'evento post-build).

(Ciò significa che quando si costruisce MAIN-APP, i test unitari possono essere eseguiti due volte, ma nel nostro caso non è stato un problema!)

Come già detto, sì, c'è un bit di impegno nella configurazione di questa struttura, ma una volta lì, aggiungere test è semplice.

Quindi tutto ciò che devi fare è costruire l'app principale ei test delle unità verranno eseguiti automaticamente!

    
risposta data 28.02.2014 - 17:14
fonte
1

Bene, non so se questo aiuta, ma ci sono alcuni grandi video su TDD di Brett L. Schuchert. Sfortunatamente, non mostra la combinazione "C ++" e "VS", ma

TDD con C # e VS: link

TDD con C ++ ed Eclipse: link

Forse puoi risolverlo da quei due.

EDIT: il video C ++ riguarda l'utilizzo del framwork di test CppUTest con Eclipse, ovviamente. Quando l'ho postato ho pensato che dovrebbe essere facilmente adottato per l'utilizzo in VS. Così ho cercato su Google un po 'e ho trovato questo:

link

che fornisce informazioni su come utilizzare CppTest in Visual Studio.

    
risposta data 05.09.2011 - 16:36
fonte
1

Googletest
Come integrare con vc ++

Non hai bisogno di un plugin, il test è solo un altro obiettivo. Non ci sono plugin per generare test con c ++, evne se potessi testare cose inutili come i compiti

    
risposta data 05.09.2011 - 19:09
fonte
1

Non posso commentare gli strumenti C ++ come non ho toccato in circa 20 anni (.NET dev in questi giorni) e credo che la maggior parte degli strumenti in questi giorni sono per il codice gestito ma per quanto riguarda le tecniche ...

Come altri hanno già menzionato, il codice di prova è sempre in un progetto / assieme completamente diverso dal codice di produzione e sì di solito devi mantenere quel progetto da solo, anche se sicuramente nell'IDE VS questo non è un grosso problema come spesso hai diversi progetti come parte della tua soluzione comunque.

Il codice di produzione è e deve essere scritto un po 'diverso per TDD. Come si scrivono i test prima si finisce per dover progettare il codice per essere testabile. Questo è un altro argomento in sé, ma può richiedere del tempo e sembrare molto frustrante all'inizio, specialmente se i tuoi IDE / strumenti non ti danno un feedback rapido, il bombardamento per eseguire strumenti da riga di comando per eseguire i test è solo distruttivo.

Esistono molte tecniche specifiche per rendere testabile il codice, ma la maggior parte di esse si divide in oggetti di piccole dimensioni che non fanno molto in modo da poterli testare isolatamente ed essere in grado di iniettare una versione di prova di qualche comportamento in a oggetti più complessi. I framework IOC possono aiutare molto qui.

Un libro che potresti trovare utile è; Michael Feathers, lavorando efficacemente con il codice legacy. Questo utilizza più lingue nei suoi esempi e può aiutare a identificare approcci specifici per adattare in modo sicuro codice / tecniche che non erano originariamente progettati per essere testabili.

Piccolo avvertimento: ho bevuto da Agile Kool-Aid anni fa: D

    
risposta data 12.09.2011 - 22:16
fonte
0

Maven non è ampiamente utilizzato in C ++ (tuttavia, è utilizzato principalmente per Java ma è indipendente dal linguaggio) ma è uno strumento molto potente e consente di mantenere tutto in un progetto (inclusi test, in effetti, che è l'approccio consigliato con Maven). Lo suggerisco solo ora poiché dalle risposte finora sembra che un'alternativa con un plug-in VS potrebbe non esistere.

Ricerca di plug-in che ho trovato:

link

ma non sembra ancora molto maturo. Con l'installazione di Maven tutto ciò che devi fare per eseguire i test è eseguire mvn test nella riga di comando.

Se sei interessato, puoi informarlo qui e (uno di) i plugin di supporto C ++ qui (Maven ha un'architettura plugin quindi tutto è un plugin).

    
risposta data 13.09.2011 - 23:07
fonte
0

Raccomandazione del framework: nel nostro ufficio utilizziamo TestDriven.NET che si integra con Visual Studio. Le classi unittest sono scritte in C ++ / CLI, che possono quindi chiamare per esercitare qualsiasi codice nativo che è necessario testare. Sì, le classi C ++ / CLI vanno nel proprio assembly, quindi un progetto di "testing" aggiunto alle soluzioni.

    
risposta data 16.11.2011 - 19:14
fonte

Leggi altre domande sui tag