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?
src/ code/ code.cpp code.h main.cpp t/ main.cpp (test runner) test.cpp (test suite)
Jak uruchomić wszystkie testy?
Tester używa:
return CommandLineTestRunner::RunAllTests(ac, av);
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:
Memory leak(s) found. Allocated at: code.c line 6 Leak size: 1
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.
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.
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.
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!
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!
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!
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.
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.
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
Po pierwsze, napiszmy trochę kodu!
Nasz projekt testowy będzie miał plik ‘main’ i będzie zawierał bibliotekę użytkową o nazwie ‘code’. Biblioteka ta dostarczy prostą funkcję zwracającą 1 (na razie). Pliki będą zorganizowane w następujący sposób:
├── src │ ├── code │ │ ├── code.cpp │ │ └── code.h │ └── main.cpp └── t ├── main.cpp └── test.cpp
Zacznijmy od napisania plików src/
// src/main.cpp #include <stdlib.h> #include <stdio.h> #include "code.h" int main(void) { test_func(); printf("hello world!\n"); exit(0); }
// src/code/code.cpp #include <stdlib.h> #include "code.h" int test_func() { return 1; }
// src/code/code.h #ifndef __code_h__ #define __code_h__ int test_func(); #endif
Teraz przejdźmy do testów, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie test runnera, który uruchomi nasze pliki testowe. Jest to również funkcja ‘main’ która zostanie wykonana po skompilowaniu tego wszystkiego:
// t/main.cpp #include "CppUTest/CommandLineTestRunner.h" int main(int ac, char** av) { return CommandLineTestRunner::RunAllTests(ac, av); }
Teraz możemy napisać nasz pierwszy moduł testowy:
// t/test.cpp #include "CppUTest/TestHarness.h" #include "code.h" TEST_GROUP(AwesomeExamples) { }; TEST(AwesomeExamples, FirstExample) { int x = test_func(); CHECK_EQUAL(1, x); }
Następnie musimy napisać makefiles. Potrzebujemy dwóch: jednego dla plików projektu pod src/ i jednego dla testów.
Po pierwsze, napiszmy trochę kodu!
Nasz projekt testowy będzie miał plik ‘main’ i będzie zawierał bibliotekę użytkową o nazwie ‘code’. Biblioteka ta dostarczy prostą funkcję zwracającą 1 (na razie). Pliki będą zorganizowane w następujący sposób:
├── src │ ├── code │ │ ├── code.cpp │ │ └── code.h │ └── main.cpp └── t ├── main.cpp └── test.cpp
Zacznijmy od napisania plików src/
// src/main.cpp #include <stdlib.h> #include <stdio.h> #include "code.h" int main(void) { test_func(); printf("hello world!\n"); exit(0); }
// src/code/code.cpp #include <stdlib.h> #include "code.h" int test_func() { return 1; }
// src/code/code.h #ifndef __code_h__ #define __code_h__ int test_func(); #endif
Teraz przejdźmy do testów, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie test runnera, który uruchomi nasze pliki testowe. Jest to również funkcja ‘main’ która zostanie wykonana po skompilowaniu tego wszystkiego:
// t/main.cpp #include "CppUTest/CommandLineTestRunner.h" int main(int ac, char** av) { return CommandLineTestRunner::RunAllTests(ac, av); }
Teraz możemy napisać nasz pierwszy moduł testowy:
// t/test.cpp #include "CppUTest/TestHarness.h" #include "code.h" TEST_GROUP(AwesomeExamples) { }; TEST(AwesomeExamples, FirstExample) { int x = test_func(); CHECK_EQUAL(1, x); }
Następnie musimy napisać makefiles. Potrzebujemy dwóch: jednego dla plików projektu pod src/ i jednego dla testów.
Po pierwsze, napiszmy trochę kodu!
Nasz projekt testowy będzie miał plik ‘main’ i będzie zawierał bibliotekę użytkową o nazwie ‘code’. Biblioteka ta dostarczy prostą funkcję zwracającą 1 (na razie). Pliki będą zorganizowane w następujący sposób:
├── src │ ├── code │ │ ├── code.cpp │ │ └── code.h │ └── main.cpp └── t ├── main.cpp └── test.cpp
Zacznijmy od napisania plików src/
// src/main.cpp #include <stdlib.h> #include <stdio.h> #include "code.h" int main(void) { test_func(); printf("hello world!\n"); exit(0); }
// src/code/code.cpp #include <stdlib.h> #include "code.h" int test_func() { return 1; }
// src/code/code.h #ifndef __code_h__ #define __code_h__ int test_func(); #endif
Teraz przejdźmy do testów, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie test runnera, który uruchomi nasze pliki testowe. Jest to również funkcja ‘main’ która zostanie wykonana po skompilowaniu tego wszystkiego:
// t/main.cpp #include "CppUTest/CommandLineTestRunner.h" int main(int ac, char** av) { return CommandLineTestRunner::RunAllTests(ac, av); }
Teraz możemy napisać nasz pierwszy moduł testowy:
// t/test.cpp #include "CppUTest/TestHarness.h" #include "code.h" TEST_GROUP(AwesomeExamples) { }; TEST(AwesomeExamples, FirstExample) { int x = test_func(); CHECK_EQUAL(1, x); }
Następnie musimy napisać makefiles. Potrzebujemy dwóch: jednego dla plików projektu pod src/ i jednego dla testów.
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:
# Makefile SRC_DIR = ./src CODE_DIR = $(SRC_DIR)/code OUT = example TEST_DIR = t test: make -C $(TEST_DIR) test_clean: make -C $(TEST_DIR) clean code.o: gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o main: code.o gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT) all: test main clean: test_clean rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)
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:
[]$ make main gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example []$ ./example hello world
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:
# Makefile SRC_DIR = ./src CODE_DIR = $(SRC_DIR)/code OUT = example TEST_DIR = t test: make -C $(TEST_DIR) test_clean: make -C $(TEST_DIR) clean code.o: gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o main: code.o gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT) all: test main clean: test_clean rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)
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:
[]$ make main gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example []$ ./example hello world
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:
# Makefile SRC_DIR = ./src CODE_DIR = $(SRC_DIR)/code OUT = example TEST_DIR = t test: make -C $(TEST_DIR) test_clean: make -C $(TEST_DIR) clean code.o: gcc -c -I$(CODE_DIR) $(CODE_DIR)/code.cpp -o $(CODE_DIR)/code.o main: code.o gcc -I$(CODE_DIR) $(CODE_DIR)/code.o $(SRC_DIR)/main.cpp -o $(OUT) all: test main clean: test_clean rm $(SRC_DIR)/*.o $(CODE_DIR)/*.o $(OUT)
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:
[]$ make main gcc -c -I./src/code ./src/code/code.cpp -o ./src/code/code.o gcc -I./src/code ./src/code/code.o ./src/main.cpp -o example []$ ./example hello world
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:
# we don’t want to use relative paths, so we set these variables PROJECT_DIR=/path/to/project SRC_DIR=$(PROJECT_DIR)/src TEST_DIR=$(PROJECT_DIR)/t # specify where the source code and includes are located INCLUDE_DIRS=$(SRC_DIR)/code SRC_DIRS=$(SRC_DIR)/code # specify where the test code is located TEST_SRC_DIRS=$(TEST_DIR) # what to call the test binary TEST_TARGET=example # where the cpputest library is located CPPUTEST_HOME=/usr/local # run MakefileWorker.mk with the variables defined here include MakefileWorker.mk
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’
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:
# we don’t want to use relative paths, so we set these variables PROJECT_DIR=/path/to/project SRC_DIR=$(PROJECT_DIR)/src TEST_DIR=$(PROJECT_DIR)/t # specify where the source code and includes are located INCLUDE_DIRS=$(SRC_DIR)/code SRC_DIRS=$(SRC_DIR)/code # specify where the test code is located TEST_SRC_DIRS=$(TEST_DIR) # what to call the test binary TEST_TARGET=example # where the cpputest library is located CPPUTEST_HOME=/usr/local # run MakefileWorker.mk with the variables defined here include MakefileWorker.mk
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’
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:
# we don’t want to use relative paths, so we set these variables PROJECT_DIR=/path/to/project SRC_DIR=$(PROJECT_DIR)/src TEST_DIR=$(PROJECT_DIR)/t # specify where the source code and includes are located INCLUDE_DIRS=$(SRC_DIR)/code SRC_DIRS=$(SRC_DIR)/code # specify where the test code is located TEST_SRC_DIRS=$(TEST_DIR) # what to call the test binary TEST_TARGET=example # where the cpputest library is located CPPUTEST_HOME=/usr/local # run MakefileWorker.mk with the variables defined here include MakefileWorker.mk
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:
[]$ make -B gcov < compilation output > for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \ FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \ gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \ done for f in ; do \ gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \ done /usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt cat gcov_report.txt 100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp mkdir -p gcov mv *.gcov gcov mv gcov_* gcov See gcov directory for details
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
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:
[]$ make -B gcov < compilation output > for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \ FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \ gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \ done for f in ; do \ gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \ done /usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt cat gcov_report.txt 100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp mkdir -p gcov mv *.gcov gcov mv gcov_* gcov See gcov directory for details
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
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:
[]$ make -B gcov < compilation output > for d in /Users/ykuperman/code/blogpost/qa/src/code ; do \ FILES=`ls $d/*.c $d/*.cc $d/*.cpp 2> /dev/null` ; \ gcov --object-directory objs/$d $FILES >> gcov_output.txt 2>>gcov_error.txt ; \ done for f in ; do \ gcov --object-directory objs/$f $f >> gcov_output.txt 2>>gcov_error.txt ; \ done /usr/local/scripts/filterGcov.sh gcov_output.txt gcov_error.txt gcov_report.txt example.txt cat gcov_report.txt 100.00% /Users/ykuperman/code/blogpost/qa/src/code/code.cpp mkdir -p gcov mv *.gcov gcov mv gcov_* gcov See gcov directory for details
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:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym skompilowaniu, pojawia się następujący błąd:
test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample) Memory leak(s) found. Alloc num (4) Leak size: 1 Allocated at: ./code.c and line: 6 Type: "malloc" Memory: <
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
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:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym skompilowaniu, pojawia się następujący błąd:
test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample) Memory leak(s) found. Alloc num (4) Leak size: 1 Allocated at: ./code.c and line: 6 Type: "malloc" Memory: <
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
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:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym skompilowaniu, pojawia się następujący błąd:
test.cpp:9: error: Failure in TEST(AwesomeExamples, FirstExample) Memory leak(s) found. Alloc num (4) Leak size: 1 Allocated at: ./code.c and line: 6 Type: "malloc" Memory: <
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



