2016-07-30 23 views
2

Wie können Bibliotheken wie GTest ein einzelnes Makro G_TEST(...) verwenden, um die Funktion zu definieren und sie als Testfunktion zu registrieren? Ich suche nach einer Möglichkeit, das Gleiche für mein C99-Projekt zu tun.C, wie kann ein Makro einen Unittest zur Ausführung registrieren?

Beispiel

#include <stdio.h> 
#include "my_test_header_that_doesnt_exist.h" 

TEST_MACRO(mytest) 
{ 
    printf("Hello, world\n"); 
    return 0; 
} 
TEST_MACRO(mytest2) 
{ 
    printf("Hello, world 2\n"); 
    return 2; 
} 

int main(int argc, char** argv) 
{ 
    RUN_TESTS(); 
    return 0; 
} 

nicht herausfinden, wie die Tests zu registrieren, so dass sie von RUN_TESTS()

+0

Blick auf http://stackoverflow.com/questions/4880966/calling-some-functions- before-main-in-c, um zu sehen, wie die Funktion in C sichergestellt wird, wird vor main() ausgeführt. Dann können Sie diesen Trick in Ihren Makros verwenden. Die Antwort von Byteventurer erklärt richtig, wie es in C++, aber GTest gemacht wird - aber Sie können nicht diesen C++ spezifischen Trick verwenden ... – PiotrNycz

Antwort

2

Indem eine -E Option g++ bekannt sind Sie den Code nach der Vorverarbeitung inspizieren können. Beispielcode die Gtest Bibliothek:

#include <gtest/gtest.h> 

TEST(testcase, mytest) { 
    // Code 
} 

int main() { 
    return RUN_ALL_TESTS(); 
} 

Und Kompilieren mit:

g++ -E -Igtest_include_path example.cpp -oexample_preprocessed.cpp 

Der Test Makro erweitert:

class testcase_mytest_Test : public ::testing::Test { 
public: 
    testcase_mytest_Test() {} 
private: 
    virtual void TestBody(); 
    static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); 
    testcase_mytest_Test(testcase_mytest_Test const &); 
    void operator=(testcase_mytest_Test const &); 
}; 

::testing::TestInfo* const testcase_mytest_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo("testcase", "mytest", __null, __null, ::testing::internal::CodeLocation("cpp_test.c", 3), (::testing::internal::GetTestTypeId()), ::testing::Test::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing::internal::TestFactoryImpl< testcase_mytest_Test>); 

void testcase_mytest_Test::TestBody() { 
    // Code 
} 

Und RUN_ALL_TESTS() ist kein Makro:

inline int RUN_ALL_TESTS() { 
    return ::testing::UnitTest::GetInstance()->Run(); 
} 

So ist es in der Tat eine komplizierte Kette von Präprozessor-Makros, die aus Ihrem Testfall eine Klasse bilden und alle möglichen Dinge tun, um sie mit den Maschinen zu verbinden, die sie ausführen.

Offensichtlich werden Sie nicht in der Lage sein, dies in einem C99-Projekt zu tun, da GTest eine C++ - Bibliothek ist und für diese Aufgabe auf C++ - Funktionen angewiesen ist.

Wenn Sie verstehen wollen, wie es funktioniert vollständig, sollten Sie den Gtest Code in seinem Repository finden Sie unter: https://github.com/google/googletest