Rozpoczęcie pracy z CppUTest
Ptak
14 maj 2017
1 min read

Kluczowe Wnioski
CppUTest to lekki, aktywnie utrzymywany framework testowy w stylu xUnit dla C/C++, z warstwą integracji C, która działa bezproblemowo nawet w kodzie z przewagą C.
Możesz go zainstalować za pomocą menedżerów pakietów (dystrybucje Linuxa, Homebrew) lub sklonować repozytorium GitHub.
Minimalna konfiguracja składa się z:
katalogu produkcyjnego
src/,katalogu testowego
t/,uruchamiania testów (
CommandLineTestRunner), orazmodułów testowych używających bloków
TEST_GROUPiTEST().
CppUTest zapewnia pomocniczy MakefileWorker.mk, który upraszcza budowanie testów, łączenie bibliotek i obsługę flag.
Wykrywanie wycieków pamięci jest domyślnie włączone przez nadpisywanie malloc/free, co pozwala na wychwycenie wycieków w testowanym kodzie źródłowym.
Pokrycie kodu za pomocą gcov łatwo się integruje przez włączenie
CPPUTEST_USE_GCOV=Y, co skutkuje pełnymi raportami pokrycia i podsumowaniami HTML.Framework obejmuje zaawansowane funkcje: mocking, pluginy, skrypty pomocnicze oraz bezpośrednią interoperacyjność z C — przydatne w złożonych korporacyjnych bazach kodu.
Q&A Highlights
Co to jest CppUTest i dlaczego z niego korzystać?
To solidne, xUnit-style framework testowania dla C/C++ z czystym API, wbudowanymi makrami assert, wykrywaniem wycieków i aktywnym rozwojem — idealne dla systemów legacy lub nowoczesnych.
Jak skonstruować podstawowy projekt za pomocą CppUTest?
Jak uruchomić wszystkie testy?
Tester używa:
Jak tworzyć testy bez ręcznej konfiguracji opcji kompilatora?
Użyj
MakefileWorker.mkz CppUTest, który automatycznie obsługuje flagi, linkowanie i wykonanie testów.Czy CppUTest może automatycznie wykrywać wycieki pamięci?
Tak. Nadpisuje malloc/free podczas budowy testów, raportując:
który test wyciekł,
gdzie to się wydarzyło,
rozmiar wycieku i zawartość pamięci.
Przykład błędnego wyniku:
Jak wygenerować code coverage?
Włącz:
CPPUTEST_USE_GCOV=YUpewnij się, że
filterGcov.shjest dostępny w$(CPPUTEST_HOME)/scripts/.Uruchom: make
gcovTo generuje pliki
.gcov, podsumowania tekstowe i raporty pokrycia HTML.
Co jeszcze może zrobić CppUTest poza podstawowym testowaniem?
framework do symulacji
system wtyczek
skrypty automatyzacji pomocniczej
natywna integracja C
rozległe makra asercji
Dla kogo CppUTest jest najbardziej odpowiedni?
Zespoły pracujące z systemami wbudowanymi, platformami C, usługami C++ lub dowolnym środowiskiem, w którym niezawodność i bezpieczeństwo pamięci muszą być ciągle weryfikowane.
W SparkPost poświęcamy dużo czasu i wysiłku na testowanie naszego kodu. Nasza platforma jest napisana w C, a ostatnio badałem integrację z frameworkiem do testowania jednostkowego o nazwie „CppUTest”, który zapewnia testowanie w stylu xUnit dla C/C++. Ten framework jest solidny, bogaty w funkcje i znajduje się w fazie aktywnego rozwoju, co czyni go doskonałym wyborem. Zapewnia również warstwę integracji C, co ułatwia korzystanie z naszego kodu platformy C, mimo że większość frameworka jest w C++. Ten samouczek obejmuje, jak rozpocząć pracę z CppUTest w swoich własnych projektach.
Pobieranie CppUTest
Strona projektu CppUTest jest dostępna na oficjalnej stronie, a repozytorium znajduje się na github. Jest również zawarta w repozytoriach zarządzania pakietami dla wielu dystrybucji linux, a także homebrew na Mac OS. Przykłady, które dalej omówimy, były wykonane na Mac OS X, ale pochodzą z kodu napisanego dla Red Hat, systemu operacyjnego, na którym działa nasza platforma.
Podstawy są dobrze udokumentowane na stronie głównej CppUTest. Przejdziemy przez to pobieżnie i zajmiemy się niektórymi bardziej interesującymi funkcjami.
Laying the Foundation
Projekt Makefile
Plik makefile projektu będzie na tym samym poziomie co katalogi ‘src’ i ‘t’ w katalogu głównym projektu. Powinno to wyglądać następująco:
Zanotuj, że używa to ‘make -C’ dla celów testowych – co oznacza, że ponownie wywoła ‘make’ używając makefile w katalogu testowym.
Na tym etapie możemy skompilować kod ‘src’ za pomocą makefile i zobaczyć, że działa:
Testy Makefile
W przypadku testów rzecz jest trochę bardziej skomplikowana, ponieważ musimy prawidłowo załadować i zintegrować z biblioteką CppUTest.
Repozytorium CppUTest dostarcza plik o nazwie „MakefileWorker.mk”. Zapewnia on wiele funkcji, które sprawiają, że budowanie z CppUTest jest proste. Plik znajduje się w katalogu „build” w repozytorium git. W tym samouczku założymy, że został skopiowany do katalogu ‘t/’. Można go użyć w następujący sposób:
Zauważ, że CPPUTEST_HOME musi być ustawiony na miejsce, gdzie zainstalowano CppUTest. Jeśli zainstalowałeś pakiet dystrybucyjny, zazwyczaj znajduje się to w /usr/local na systemie linux/mac. Jeśli sprawdziłeś repozytorium samodzielnie, to tam, gdzie jest ten checkout.
Wszystkie te opcje są udokumentowane w MakefileWorker.mk.
MakefileWorker.mk dodaje również kilka celów makefile, w tym następujące:
all – buduje testy wskazane przez makefile
clean – usuwa wszystkie obiekty i pliki gcov wygenerowane dla testów
realclean – usuwa wszystkie pliki obiektowe i gcov w całym drzewie katalogów
flags – wyświetla wszystkie skonfigurowane flagi używane do kompilacji testów
debug – wyświetla wszystkie pliki źródłowe, obiekty, zależności i ‘rzeczy do czyszczenia’
Code Coverage
Testowanie jednostkowe nie byłoby kompletne bez raportu pokrycia. Narzędziem pierwszego wyboru dla projektów korzystających z gcc jest gcov, dostępne w standardowym zestawie narzędzi gcc. Cpputest łatwo integruje się z gcov, wystarczy dodać tę linię do pliku makefile:
CPPUTEST_USE_GCOV=Y
Potem musimy upewnić się, że skrypt filterGcov.sh z tego repozytorium znajduje się w '/scripts/filterGcov.sh' względem lokalizacji, w której ustawiłeś ‘CPPUTEST_HOME’. Musi on także mieć uprawnienia do wykonania.
W przykładowym pliku Makefile, byłby deployowany do '/usr/local/scripts/filterGcov.sh'. Jeśli uruchamiasz CppUTest z repozytorium, wszystko powinno działać bez modyfikacji.
Z tym w miejscu, możesz po prostu uruchomić ‘make gcov’ i analiza zostanie wygenerowana dla Ciebie. W naszym przypadku będziemy musieli ‘make -B’ aby przebudować pliki obiektowe z włączonym gcov:
To wygeneruje szereg plików w nowym katalogu ‘gcov’. Są to:
code.cpp.gcov – faktyczny plik ‘gcov’ dla testowanego kodu
gcov_error.txt – raport błędów (w naszym przypadku powinien być pusty)
gcov_output.txt – rzeczywisty wynik polecenia gcov, które zostało uruchomione
gcov_report.txt – podsumowanie pokrycia dla każdego pliku, który był testowany
gcov_report.txt.html – html-owa wersja raportu gcov
Cpputest Wykrywanie Wycieku Pamięci
Cpputest pozwala automatycznie wykrywać wycieki pamięci przez redefiniowanie standardowej rodziny funkcji „malloc/free”, aby zamiast tego używać własnych wrapperów. Dzięki temu może szybko wychwytywać wycieki i raportować je dla każdego wykonania testu. Jest to domyślnie włączone w MakefileWorker.mk, więc jest już aktywne z krokami opisanymi do tej pory.
By zilustrować, wycieknijmy trochę pamięci w test_func() !
Wracając do code.c, dodajemy malloc() do funkcji, jak poniżej:
Teraz, po ponownym skompilowaniu, pojawia się następujący błąd:
To pokazuje, który test spowodował wyciek, gdzie wyciek nastąpił w kodzie źródłowym i co znajdowało się w wyciekającej pamięci. Bardzo pomocne!
Istnieje kilka zastrzeżeń dotyczących tej funkcji:
Cpputest używa makr preprocesora do dynamicznego redefiniowania wszystkich wywołań standardowych funkcji zarządzania pamięcią. To oznacza, że będzie działać tylko dla wywołań w kodzie źródłowym pod testem, ponieważ to właśnie ten kod jest kompilowany z nadpisaniami CppUTest. Wycieki w bibliotekach zewnętrznych nie będą wychwytywane.
Czasami pamięć, która jest przydzielana na cały czas życia procesu, nie jest przeznaczona do zwolnienia. Może to powodować wiele spamowych błędów, jeśli testujesz moduł z takim zachowaniem. Aby wyłączyć wykrywanie wycieków, możesz to zrobić:
CPPUTEST_USE_MEM_LEAK_DETECTION=N
Zainteresowany czymś więcej?
To tylko wierzchołek góry lodowej, jeśli chodzi o wszystkie funkcje zawarte w tym narzędziu. Oprócz podstaw omówionych tutaj, posiada ono również framework do mockowania, bezpośrednią warstwę integracji z C oraz framework pluginów, żeby wymienić kilka znaczących. Repozytorium zawiera także cały katalog skryptów pomocniczych, które mogą pomóc zautomatyzować niektóre rutynowe czynności związane z pracą z frameworkiem.
Mam nadzieję, że informacje tutaj pomogą Ci poprawić jakość kodu C/C++ przy użyciu tego świetnego narzędzia!



