2013-08-02 17 views
6

Per quanto ho capito, posso semplicemente inserire catch.hpp nella mia directory di progetto, aggiungerlo al progetto e quindi iniziare a scrivere test. Ho riscontrato alcuni errori di linker, o 11 per essere precisi, una volta provato a utilizzare alcuni dei macro delineati in tutorial.CATCH Unit Testing Suite con Visual Studio 2010

#include "catch.hpp" 

unsigned int Factorial(unsigned int number) { 
    return number <= 1 ? number : Factorial(number-1)*number; 
} 

TEST_CASE("Factorials are computed", "[factorial]") { 
    REQUIRE(Factorial(1) == 1); 
    REQUIRE(Factorial(2) == 2); 
    REQUIRE(Factorial(3) == 6); 
    REQUIRE(Factorial(10) == 3628800); 
} 

sono in grado di creare un singolo file fuori il primo esempio e compilarlo con g ++, ma quando ho semplicemente incollare lo stesso codice nel mio progetto VS2010 e quindi provare a eseguirlo, mi imbatto nella errori del linker. Purtroppo non sono abbastanza familiare con il C++ a questo punto per decifrare me stesso gli errori, e dopo aver dato un'occhiata al singolo file here, non sono stato in grado di discernere il problema.

Error 1 error LNK2019: unresolved external symbol "public: __thiscall Catch::AutoReg::AutoReg(void (__cdecl*)(void),struct Catch::SourceLineInfo const &,struct Catch::NameAndDesc const &)" ([email protected]@@[email protected]@[email protected]@[email protected]@Z) referenced in function "void __cdecl `anonymous namespace'::`dynamic initializer for 'autoRegistrar27''(void)" ([email protected][email protected]@YAXXZ) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Catch::ExpressionResultBuilder::ExpressionResultBuilder(enum Catch::ResultWas::OfType)" ([email protected]@@[email protected]@[email protected]@@Z) referenced in function [email protected]@YAXXZ$0 C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 3 error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl Catch::translateActiveException(void)" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@XZ) referenced in function [email protected]@YAXXZ$0 C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 4 error LNK2019: unresolved external symbol "public: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionResultBuilder::endExpression(enum Catch::ResultDisposition::Flags)" ([email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____27(void)" ([email protected]@YAXXZ) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 5 error LNK2019: unresolved external symbol "public: __thiscall Catch::AssertionInfo::AssertionInfo(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,struct Catch::SourceLineInfo const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,enum Catch::ResultDisposition::Flags)" ([email protected]@@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____27(void)" ([email protected]@YAXXZ) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 6 error LNK2019: unresolved external symbol "struct Catch::IContext & __cdecl Catch::getCurrentContext(void)" ([email protected]@@[email protected]@XZ) referenced in function "struct Catch::IResultCapture & __cdecl Catch::getResultCapture(void)" ([email protected]@@[email protected]@XZ) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 7 error LNK2019: unresolved external symbol "public: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionResultBuilder::setOp(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" ([email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "private: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionLhs<int const &>::captureExpression<0,int>(int const &)" ([email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 8 error LNK2019: unresolved external symbol "public: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionResultBuilder::setRhs(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" ([email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "private: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionLhs<int const &>::captureExpression<0,int>(int const &)" ([email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 9 error LNK2019: unresolved external symbol "public: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionResultBuilder::setLhs(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" ([email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "private: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionLhs<int const &>::captureExpression<0,int>(int const &)" ([email protected][email protected]@?$ExpressionL[email protected]@[email protected]@[email protected]@[email protected]) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 10 error LNK2019: unresolved external symbol "public: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionResultBuilder::setResultType(bool)" ([email protected]@[email protected]@[email protected][email protected]) referenced in function "private: class Catch::ExpressionResultBuilder & __thiscall Catch::ExpressionLhs<int const &>::captureExpression<0,int>(int const &)" ([email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 11 error LNK2019: unresolved external symbol "public: __thiscall Catch::AutoReg::~AutoReg(void)" ([email protected]@@[email protected]) referenced in function "void __cdecl `anonymous namespace'::`dynamic atexit destructor for 'autoRegistrar27''(void)" ([email protected][email protected]@YAXXZ) C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\FirstCPPApplication\FirstCPPApplication.obj 1 1 FirstCPPApplication 
Error 12 error LNK1120: 11 unresolved externals C:\Users\Mark\documents\visual studio 2010\Projects\FirstCPPApplication\Debug\FirstCPPApplication.exe FirstCPPApplication 

risposta

6

Basta la scansione attraverso i link forniti, penso che potrebbe essere necessario aggiungere questa riga nella parte superiore del file.

#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file 

Sembra che le funzioni che si sta tentando di collegamento sono raggiungibili #if defined CATCH_CONFIG_MAIN .... #endif direttive del preprocessore.

+0

Grazie, questa era la soluzione. Nella mia inesperienza, ho pensato che non avessi bisogno di un nuovo progetto per scrivere i miei test unitari, quindi ho assunto erroneamente che potevo inserire 'catch.hpp' ovunque nel mio progetto, quindi creando un nuovo progetto e aggiungendo il linee nell'OP e la tua singola linea funziona. Ora ho bisogno di ordinare come aggiungere il codice che voglio testare dal progetto principale nel progetto di test. – TankorSmash

+0

Scratch che, ho avuto un percorso relativo per un'importazione nel progetto principale che avrebbe fallito nel progetto di test perché stavo usando diverse impostazioni di progetto per ciascuno. Immagino di non essere collegato ai file giusti o qualcosa del genere. – TankorSmash

6

long story short: dividi la tua singola soluzione di progetto in 3, usa un .lib del vecchio exe, aggiungi i progetti ai percorsi appropriati, aggiorna il linker e sei a posto.

AE Drew's answer ha aiutato a risolvere il mio problema, ma voglio mettere un soluzione più completa per il titolo della domanda, nel caso qualcuno proviene da Google, soprattutto se sono alla ricerca di una semplice ripartizione da punto di vista di un principiante.

Se tu avessi un solo progetto nella soluzione che ha costruito un .exe per voi, CATCH non avrebbe funzionato: la soluzione ha bisogno di 3 progetti (per quanto ne so) per essere in grado di testare il codice.

  • Source_project, il progetto base di codice principale (in cui il codice sorgente per l'applicazione risiede)

  • Test_project, Il progetto suite di test (in cui i test REQUIRES appaiono come indicato nella domanda di cui sopra)

  • Main_project, Il progetto in cui si chiama e si esegue effettivamente il codice dalla base di codice sorgente .

Per convertire la vostra soluzione originale-progetto in qualcosa che è possibile utilizzare in entrambe le prove e per funzionare correttamente, è necessario costruire un .lib o un .dll in modo che altri progetti (tra cui progetti di altre persone) possono utilizzare lo stesso codice . Alterare this answer, tutto quello che serve è quello di

tasto destro del mouse sul progetto in Esplora soluzioni e selezionare> Proprietà .... In Proprietà di configurazione -> Generale c'è un> un'opzione chiamato tipo di configurazione. Se lo si cambia in [Libreria statica> (.lib)], il tuo progetto genererà un [.lib] al momento della sua creazione.

E poi nel 3 ° progetto, main_project, dove si dispone di una configurazione barebone da un'applicazione Win32 console che contiene solo un file che sembra qualcosa simile:

#include "stdafx.h" 
#include "HEADER_FROM_FIRST_PROJECT.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    METHOD_FROM_FIRST_PROJECT(); 
    return 0; 
} 

in cui si importa un colpo di testa file da Source_project, il primo progetto che abbiamo creato (quello che era un exe, ma che ora sta creando un lib). Ma che non sta andando a correre ancora, è necessario aggiungere directory s il Source_project' a questo progetto directory aggiuntive, facendo clic destro del progetto nella Esplora soluzioni, in Proprietà> Proprietà di configurazione> C/C++> Generale> aggiuntive Includi directory, aggiungi la cartella source_project all'elenco. Questo consente alle linee #include di cercare automaticamente tale directory per i file appropriati, evitando di dover scrivere ../source_project/HEADER_FROM_FIRST_PROJECT.h.

Infine, l'ultimo passaggio consiste nell'assicurarsi che il linker sia in grado di individuare effettivamente gli oggetti che si sta tentando di includere in . E poiché stiamo creando uno .lib, siamo in grado di farlo piuttosto semplicemente. Nella stessa finestra di dialogo impostazioni come prima, la finestra di dialogo Proprietà Progetti, dovremo navigare invece di configurazione Proprietà> Linker> Input> Dipendenze aggiuntive e aggiungere il percorso relativo al file source_project.lib, che sarebbe simile ../Debug/source_project.lib.

Si noti che se avete .dll s che si trovano nel vecchio exe del progetto, che sarà bisogno di essere trasferiti nella nuova main_project.

Si noti inoltre che questo è tutto molto nuovo per me e alcuni termini e informazioni sono destinati ad essere errati.