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

Najważniejsze informacje
CppUTest to lekki, aktywnie utrzymywany framework do testowania w stylu xUnit dla C/C++, z warstwą integracyjną C, która działa bezproblemowo nawet w kodzie intensywnie opartym na C.
Możesz go zainstalować za pomocą menedżerów pakietów (dystrybucje Linux, Homebrew) lub sklonować repozytorium GitHub.
Minimalna konfiguracja składa się z:
katalogu produkcyjnego
src/,katalogu testowego
t/,urządzenia do uruchamiania testów (
CommandLineTestRunner), orazmodułów testowych używających bloków
TEST_GROUPiTEST().
CppUTest dostarcza pomocnika 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 nadpisania malloc/free, wychwytując wycieki w testowanym kodzie źródłowym.
Pokrycie kodu za pomocą gcov łatwo integruje się poprzez włączenie
CPPUTEST_USE_GCOV=Y, generując pełne raporty z pokrycia i podsumowania HTML.Framework zawiera zaawansowane funkcje: mockowanie, wtyczki, skrypty pomocnicze oraz bezpośrednią interoperacyjność z C — przydatne dla złożonych kodów korporacyjnych.
Podsumowanie pytań i odpowiedzi
Czym jest CppUTest i dlaczego warto go używać?
To solidny, stylu xUnit framework testowy dla C/C++ z czystym API, wbudowanymi makrami asercji, wykrywaniem wycieków i aktywnym rozwojem — idealny dla systemów dziedzictwa lub nowoczesnych.
Jak zorganizować podstawowy projekt używając 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 budujesz testy bez ręcznej konfiguracji opcji kompilatora?
Użyj
MakefileWorker.mkz CppUTest, który automatycznie obsługuje flagi, łączenie i wykonywanie testów.Czy CppUTest może automatycznie wykrywać wycieki pamięci?
Tak. Nadpisuje malloc/free podczas budowy testów, zgłaszając:
który test wyciekł,
gdzie to miało miejsce,
wielkość wycieku i zawartość pamięci.
Przykład nieudanej jednoznacznej informacji:
Memory leak(s) found. Allocated at: code.c line 6 Leak size: 1
Jak mogę wygenerować pokrycie kodu?
Włącz:
CPPUTEST_USE_GCOV=YUpewnij się, że
filterGcov.shjest dostępny w$(CPPUTEST_HOME)/scripts/.Uruchom: make
gcovTo generuje
.gcov, tekst podsumowania i raporty pokrycia w formacie HTML.
Co jeszcze może zrobić CppUTest poza podstawowym testowaniem?
framework do mockowania
system wtyczek
skrypty automatyzacji pomocniczej
integracja z natywnym C
rozbudowane 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ć nieustannie 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 testów jednostkowych o nazwie „CppUTest”, który oferuje testowanie w stylu xUnit dla C/C++. Ten framework jest solidny, bogaty w funkcje i znajduje się w aktywnej fazie rozwoju, co czyni go świetnym wyborem. Oferuje również warstwę integracyjną w C, co ułatwiło korzystanie z naszego kodu C na platformie, mimo że większość frameworka jest napisana w C++. Ten samouczek omawia, jak rozpocząć pracę z CppUTest w swoich 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 testów jednostkowych o nazwie „CppUTest”, który oferuje testowanie w stylu xUnit dla C/C++. Ten framework jest solidny, bogaty w funkcje i znajduje się w aktywnej fazie rozwoju, co czyni go świetnym wyborem. Oferuje również warstwę integracyjną w C, co ułatwiło korzystanie z naszego kodu C na platformie, mimo że większość frameworka jest napisana w C++. Ten samouczek omawia, jak rozpocząć pracę z CppUTest w swoich 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 testów jednostkowych o nazwie „CppUTest”, który oferuje testowanie w stylu xUnit dla C/C++. Ten framework jest solidny, bogaty w funkcje i znajduje się w aktywnej fazie rozwoju, co czyni go świetnym wyborem. Oferuje również warstwę integracyjną w C, co ułatwiło korzystanie z naszego kodu C na platformie, mimo że większość frameworka jest napisana w C++. Ten samouczek omawia, jak rozpocząć pracę z CppUTest w swoich projektach.
Zainteresowany 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, ma również framework do mockowania, bezpośrednią warstwę integracyjną C oraz framework wtyczek, żeby wymienić tylko kilka ważnych. Repozytorium zawiera również całą katalog pomocniczych skryptów, które mogą pomóc zautomatyzować niektóre rutynowe części pracy z frameworkiem.
Mam nadzieję, że informacje tutaj pomogą Ci poprawić jakość Twojego kodu C/C++ dzięki temu wspaniałemu narzędziu!
To tylko wierzchołek góry lodowej, jeśli chodzi o wszystkie funkcje zawarte w tym narzędziu. Oprócz podstaw omówionych tutaj, ma również framework do mockowania, bezpośrednią warstwę integracyjną C oraz framework wtyczek, żeby wymienić tylko kilka ważnych. Repozytorium zawiera również całą katalog pomocniczych skryptów, które mogą pomóc zautomatyzować niektóre rutynowe części pracy z frameworkiem.
Mam nadzieję, że informacje tutaj pomogą Ci poprawić jakość Twojego kodu C/C++ dzięki temu wspaniałemu narzędziu!
To tylko wierzchołek góry lodowej, jeśli chodzi o wszystkie funkcje zawarte w tym narzędziu. Oprócz podstaw omówionych tutaj, ma również framework do mockowania, bezpośrednią warstwę integracyjną C oraz framework wtyczek, żeby wymienić tylko kilka ważnych. Repozytorium zawiera również całą katalog pomocniczych skryptów, które mogą pomóc zautomatyzować niektóre rutynowe części pracy z frameworkiem.
Mam nadzieję, że informacje tutaj pomogą Ci poprawić jakość Twojego kodu C/C++ dzięki temu wspaniałemu narzędziu!
Pobieranie CppUTest
Strona projektu CppUTest jest dostępna na oficjalnej stronie, a repozytorium znajduje się na githubie. Jest również dostępny w repozytoriach zarządzania pakietami dla wielu dystrybucji Linuxa, a także w homebrew na Mac OS. Przykłady, które następują, 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. Przechodzimy przez to szybko, aby dotrzeć do niektórych ciekawszych funkcji.
Strona projektu CppUTest jest dostępna na oficjalnej stronie, a repozytorium znajduje się na githubie. Jest również dostępny w repozytoriach zarządzania pakietami dla wielu dystrybucji Linuxa, a także w homebrew na Mac OS. Przykłady, które następują, 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. Przechodzimy przez to szybko, aby dotrzeć do niektórych ciekawszych funkcji.
Strona projektu CppUTest jest dostępna na oficjalnej stronie, a repozytorium znajduje się na githubie. Jest również dostępny w repozytoriach zarządzania pakietami dla wielu dystrybucji Linuxa, a także w homebrew na Mac OS. Przykłady, które następują, 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. Przechodzimy przez to szybko, aby dotrzeć do niektórych ciekawszych funkcji.
Kładzenie fundamentów
Najpierw należy napisać trochę kodu!
Nasz projekt testowy będzie miał plik 'main' i zawierał bibliotekę narzędziową o nazwie 'code'. Biblioteka dostarczy prostą funkcję, która zwróci 1 (na razie). Pliki będą uporządkowane w ten 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 zróbmy testy, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie runnera testów, który uruchomi nasze pliki testowe. To także jest funkcja 'main' , która wykona się, gdy to wszystko zostanie skompilowane:
// 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ć pliki make. Będziemy potrzebować dwóch: jednego dla plików projektu w src/, i jednego dla testów.
Najpierw należy napisać trochę kodu!
Nasz projekt testowy będzie miał plik 'main' i zawierał bibliotekę narzędziową o nazwie 'code'. Biblioteka dostarczy prostą funkcję, która zwróci 1 (na razie). Pliki będą uporządkowane w ten 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 zróbmy testy, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie runnera testów, który uruchomi nasze pliki testowe. To także jest funkcja 'main' , która wykona się, gdy to wszystko zostanie skompilowane:
// 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ć pliki make. Będziemy potrzebować dwóch: jednego dla plików projektu w src/, i jednego dla testów.
Najpierw należy napisać trochę kodu!
Nasz projekt testowy będzie miał plik 'main' i zawierał bibliotekę narzędziową o nazwie 'code'. Biblioteka dostarczy prostą funkcję, która zwróci 1 (na razie). Pliki będą uporządkowane w ten 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 zróbmy testy, które będą znajdować się w katalogu t/. Pierwszą rzeczą do zrobienia jest skonfigurowanie runnera testów, który uruchomi nasze pliki testowe. To także jest funkcja 'main' , która wykona się, gdy to wszystko zostanie skompilowane:
// 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ć pliki make. Będziemy potrzebować dwóch: jednego dla plików projektu w src/, i jednego dla testów.
Plik Makefile projektu
Plik makefile projektu będzie na tym samym poziomie co katalogi ‘src’ i ‘t’ w głównym katalogu projektu. Powinien wyglądać tak:
# 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)
Zauważ, że to używa ‘make -C’ dla celów testowych – co oznacza, że wywoła ‘make’ ponownie używając pliku makefile w katalogu testowym.
W tym momencie możemy skompilować kod ‘src’ za pomocą pliku 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 głównym katalogu projektu. Powinien wyglądać tak:
# 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)
Zauważ, że to używa ‘make -C’ dla celów testowych – co oznacza, że wywoła ‘make’ ponownie używając pliku makefile w katalogu testowym.
W tym momencie możemy skompilować kod ‘src’ za pomocą pliku 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 głównym katalogu projektu. Powinien wyglądać tak:
# 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)
Zauważ, że to używa ‘make -C’ dla celów testowych – co oznacza, że wywoła ‘make’ ponownie używając pliku makefile w katalogu testowym.
W tym momencie możemy skompilować kod ‘src’ za pomocą pliku 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
Dla testów sprawy są nieco bardziej złożone, ponieważ musimy odpowiednio załadować i zintegrować się z biblioteką CppUTest.
Repozytorium CppUTest dostarcza plik o nazwie „MakefileWorker.mk”. Oferuje on wiele funkcji, które ułatwiają budowanie z CppUTest. Plik znajduje się w katalogu „build” w repozytorium git. Na potrzeby tego samouczka założymy, że został skopiowany do katalogu 't/'. Może być użyty 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
Uwaga: CPPUTEST_HOME musi być ustawione na miejsce, w którym zainstalowano CppUTest. Jeśli zainstalowałeś pakiet z dystrybucji, zazwyczaj będzie to w /usr/local w systemie linux/mac. Jeśli samodzielnie sklonowałeś repozytorium, jest to tam, gdzie to klonowanie się znajduje.
Te opcje są wszystkie udokumentowane w MakefileWorker.mk.
MakefileWorker.mk dodaje również kilka celów makefile, w tym następujące:
wszystkie – buduje testy wskazane przez makefile
czyść – usuwa wszystkie pliki obiektowe i gcov utworzone dla testów
naprawdę czyść – usuwa wszelkie pliki obiektowe lub gcov w całym drzewie katalogów
flagi – wypisuje wszystkie skonfigurowane flagi używane do kompilacji testów
debug – wypisuje wszystkie pliki źródłowe, obiekty, zależności i 'rzeczy do czyszczenia'
Komponent | Cel | Kluczowe pliki / flagi | Uwagi |
|---|---|---|---|
Makefile projektu | Buduje główny kod źródłowy | Makefile na poziomie root używający make | Kompiluje |
Makefile testów | Buduje i łączy testy z CppUTest |
| Obsługuje kompilację testu, łączenie i flagi biblioteki |
MakefileWorker.mk | Oferuje wielokrotnego użytku logikę budowy | Znajduje się w katalogu CppUTest | Dodaje cele: |
Integracja GCov | Umożliwia raportowanie pokrycia kodu |
| Produkuje pliki |
Wykrywanie wycieków pamięci | Wykrywa wycieki malloc/free |
| Włączone domyślnie; można je wyłączyć ustawiając |
Uruchamiacz testów | Wykonuje grupy testowe |
| Wymagany główny punkt wejścia do uruchamiania testów |
Dla testów sprawy są nieco bardziej złożone, ponieważ musimy odpowiednio załadować i zintegrować się z biblioteką CppUTest.
Repozytorium CppUTest dostarcza plik o nazwie „MakefileWorker.mk”. Oferuje on wiele funkcji, które ułatwiają budowanie z CppUTest. Plik znajduje się w katalogu „build” w repozytorium git. Na potrzeby tego samouczka założymy, że został skopiowany do katalogu 't/'. Może być użyty 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
Uwaga: CPPUTEST_HOME musi być ustawione na miejsce, w którym zainstalowano CppUTest. Jeśli zainstalowałeś pakiet z dystrybucji, zazwyczaj będzie to w /usr/local w systemie linux/mac. Jeśli samodzielnie sklonowałeś repozytorium, jest to tam, gdzie to klonowanie się znajduje.
Te opcje są wszystkie udokumentowane w MakefileWorker.mk.
MakefileWorker.mk dodaje również kilka celów makefile, w tym następujące:
wszystkie – buduje testy wskazane przez makefile
czyść – usuwa wszystkie pliki obiektowe i gcov utworzone dla testów
naprawdę czyść – usuwa wszelkie pliki obiektowe lub gcov w całym drzewie katalogów
flagi – wypisuje wszystkie skonfigurowane flagi używane do kompilacji testów
debug – wypisuje wszystkie pliki źródłowe, obiekty, zależności i 'rzeczy do czyszczenia'
Komponent | Cel | Kluczowe pliki / flagi | Uwagi |
|---|---|---|---|
Makefile projektu | Buduje główny kod źródłowy | Makefile na poziomie root używający make | Kompiluje |
Makefile testów | Buduje i łączy testy z CppUTest |
| Obsługuje kompilację testu, łączenie i flagi biblioteki |
MakefileWorker.mk | Oferuje wielokrotnego użytku logikę budowy | Znajduje się w katalogu CppUTest | Dodaje cele: |
Integracja GCov | Umożliwia raportowanie pokrycia kodu |
| Produkuje pliki |
Wykrywanie wycieków pamięci | Wykrywa wycieki malloc/free |
| Włączone domyślnie; można je wyłączyć ustawiając |
Uruchamiacz testów | Wykonuje grupy testowe |
| Wymagany główny punkt wejścia do uruchamiania testów |
Dla testów sprawy są nieco bardziej złożone, ponieważ musimy odpowiednio załadować i zintegrować się z biblioteką CppUTest.
Repozytorium CppUTest dostarcza plik o nazwie „MakefileWorker.mk”. Oferuje on wiele funkcji, które ułatwiają budowanie z CppUTest. Plik znajduje się w katalogu „build” w repozytorium git. Na potrzeby tego samouczka założymy, że został skopiowany do katalogu 't/'. Może być użyty 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
Uwaga: CPPUTEST_HOME musi być ustawione na miejsce, w którym zainstalowano CppUTest. Jeśli zainstalowałeś pakiet z dystrybucji, zazwyczaj będzie to w /usr/local w systemie linux/mac. Jeśli samodzielnie sklonowałeś repozytorium, jest to tam, gdzie to klonowanie się znajduje.
Te opcje są wszystkie udokumentowane w MakefileWorker.mk.
MakefileWorker.mk dodaje również kilka celów makefile, w tym następujące:
wszystkie – buduje testy wskazane przez makefile
czyść – usuwa wszystkie pliki obiektowe i gcov utworzone dla testów
naprawdę czyść – usuwa wszelkie pliki obiektowe lub gcov w całym drzewie katalogów
flagi – wypisuje wszystkie skonfigurowane flagi używane do kompilacji testów
debug – wypisuje wszystkie pliki źródłowe, obiekty, zależności i 'rzeczy do czyszczenia'
Komponent | Cel | Kluczowe pliki / flagi | Uwagi |
|---|---|---|---|
Makefile projektu | Buduje główny kod źródłowy | Makefile na poziomie root używający make | Kompiluje |
Makefile testów | Buduje i łączy testy z CppUTest |
| Obsługuje kompilację testu, łączenie i flagi biblioteki |
MakefileWorker.mk | Oferuje wielokrotnego użytku logikę budowy | Znajduje się w katalogu CppUTest | Dodaje cele: |
Integracja GCov | Umożliwia raportowanie pokrycia kodu |
| Produkuje pliki |
Wykrywanie wycieków pamięci | Wykrywa wycieki malloc/free |
| Włączone domyślnie; można je wyłączyć ustawiając |
Uruchamiacz testów | Wykonuje grupy testowe |
| Wymagany główny punkt wejścia do uruchamiania testów |
Pokrycie kodu
Testowanie jednostkowe nie byłoby pełne bez raportu pokrycia. Narzędziem do tego dla projektów używających gcc jest gcov, dostępne jako część standardowego zestawu narzędzi gcc. Cpputest łatwo integruje się z gcov, wystarczy dodać tę linię do pliku makefile:
CPPUTEST_USE_GCOV=Y
Następnie musimy upewnić się, że skrypt filterGcov.sh z tego repo znajduje się w ‘/scripts/filterGcov.sh’ w stosunku do miejsca, w którym ustawiłeś ‘CPPUTEST_HOME’. Musi mieć również odpowiednie uprawnienia do wykonywania.
W przykładowym pliku Makefile, zostałby wdrożony do ‘/usr/local/scripts/filterGcov.sh’. Jeśli uruchamiasz CppUTest z wykonanego repo, wszystko powinno działać bez modyfikacji.
Majac to, możesz po prostu uruchomić ‘make gcov’ i analiza zostanie wygenerowana dla Ciebie. W naszym przypadku będziemy musieli użyć ‘make -B’, aby odbudować 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 – rzeczywisty plik ‘gcov’ dla testowanego kodu
gcov_error.txt – raport o błędach (w naszym przypadku powinien być pusty)
gcov_output.txt – rzeczywiste wyjście polecenia gcov, które zostało uruchomione
gcov_report.txt – podsumowanie pokrycia dla każdego testowanego pliku
gcov_report.txt.html – wersja html raportu gcov
Testowanie jednostkowe nie byłoby pełne bez raportu pokrycia. Narzędziem do tego dla projektów używających gcc jest gcov, dostępne jako część standardowego zestawu narzędzi gcc. Cpputest łatwo integruje się z gcov, wystarczy dodać tę linię do pliku makefile:
CPPUTEST_USE_GCOV=Y
Następnie musimy upewnić się, że skrypt filterGcov.sh z tego repo znajduje się w ‘/scripts/filterGcov.sh’ w stosunku do miejsca, w którym ustawiłeś ‘CPPUTEST_HOME’. Musi mieć również odpowiednie uprawnienia do wykonywania.
W przykładowym pliku Makefile, zostałby wdrożony do ‘/usr/local/scripts/filterGcov.sh’. Jeśli uruchamiasz CppUTest z wykonanego repo, wszystko powinno działać bez modyfikacji.
Majac to, możesz po prostu uruchomić ‘make gcov’ i analiza zostanie wygenerowana dla Ciebie. W naszym przypadku będziemy musieli użyć ‘make -B’, aby odbudować 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 – rzeczywisty plik ‘gcov’ dla testowanego kodu
gcov_error.txt – raport o błędach (w naszym przypadku powinien być pusty)
gcov_output.txt – rzeczywiste wyjście polecenia gcov, które zostało uruchomione
gcov_report.txt – podsumowanie pokrycia dla każdego testowanego pliku
gcov_report.txt.html – wersja html raportu gcov
Testowanie jednostkowe nie byłoby pełne bez raportu pokrycia. Narzędziem do tego dla projektów używających gcc jest gcov, dostępne jako część standardowego zestawu narzędzi gcc. Cpputest łatwo integruje się z gcov, wystarczy dodać tę linię do pliku makefile:
CPPUTEST_USE_GCOV=Y
Następnie musimy upewnić się, że skrypt filterGcov.sh z tego repo znajduje się w ‘/scripts/filterGcov.sh’ w stosunku do miejsca, w którym ustawiłeś ‘CPPUTEST_HOME’. Musi mieć również odpowiednie uprawnienia do wykonywania.
W przykładowym pliku Makefile, zostałby wdrożony do ‘/usr/local/scripts/filterGcov.sh’. Jeśli uruchamiasz CppUTest z wykonanego repo, wszystko powinno działać bez modyfikacji.
Majac to, możesz po prostu uruchomić ‘make gcov’ i analiza zostanie wygenerowana dla Ciebie. W naszym przypadku będziemy musieli użyć ‘make -B’, aby odbudować 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 – rzeczywisty plik ‘gcov’ dla testowanego kodu
gcov_error.txt – raport o błędach (w naszym przypadku powinien być pusty)
gcov_output.txt – rzeczywiste wyjście polecenia gcov, które zostało uruchomione
gcov_report.txt – podsumowanie pokrycia dla każdego testowanego pliku
gcov_report.txt.html – wersja html raportu gcov
Wykrywanie wycieków pamięci Cpputest
Cpputest pozwala na automatyczne wykrywanie wycieków pamięci poprzez zdefiniowanie ponownie standardowej rodziny funkcji „malloc/free” w celu użycia swoich własnych wrapperów. Pozwala to na szybkie wychwytywanie wycieków i zgłaszanie ich dla każdego wykonania testu. Jest to włączone domyślnie w MakefileWorker.mk, więc już działa z krokami przedstawionymi do tej pory.
Aby zilustrować, zróbmy wyciek pamięci w test_func() !
Wracając do code.c, dodajemy malloc() do funkcji, w ten sposób:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym kompilowaniu, 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 wystąpił w kodzie źródłowym i co było w wyciekniętej pamięci. Bardzo pomocne!
Istnieje kilka zastrzeżeń dotyczących tej funkcji:
Cpputest używa makr preprocesora do dynamicznego zdefiniowania 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 będącym przedmiotem testu, ponieważ to jest skompilowane z nadpisaniami CppUTest. Wycieków w powiązanych bibliotekach nie będzie można wychwycić.
Niektóre pamięci, które są alokowane na cały czas życia procesu, nie są przeznaczone do zwolnienia. Może to spowodować wiele męczących 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 na automatyczne wykrywanie wycieków pamięci poprzez zdefiniowanie ponownie standardowej rodziny funkcji „malloc/free” w celu użycia swoich własnych wrapperów. Pozwala to na szybkie wychwytywanie wycieków i zgłaszanie ich dla każdego wykonania testu. Jest to włączone domyślnie w MakefileWorker.mk, więc już działa z krokami przedstawionymi do tej pory.
Aby zilustrować, zróbmy wyciek pamięci w test_func() !
Wracając do code.c, dodajemy malloc() do funkcji, w ten sposób:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym kompilowaniu, 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 wystąpił w kodzie źródłowym i co było w wyciekniętej pamięci. Bardzo pomocne!
Istnieje kilka zastrzeżeń dotyczących tej funkcji:
Cpputest używa makr preprocesora do dynamicznego zdefiniowania 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 będącym przedmiotem testu, ponieważ to jest skompilowane z nadpisaniami CppUTest. Wycieków w powiązanych bibliotekach nie będzie można wychwycić.
Niektóre pamięci, które są alokowane na cały czas życia procesu, nie są przeznaczone do zwolnienia. Może to spowodować wiele męczących 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 na automatyczne wykrywanie wycieków pamięci poprzez zdefiniowanie ponownie standardowej rodziny funkcji „malloc/free” w celu użycia swoich własnych wrapperów. Pozwala to na szybkie wychwytywanie wycieków i zgłaszanie ich dla każdego wykonania testu. Jest to włączone domyślnie w MakefileWorker.mk, więc już działa z krokami przedstawionymi do tej pory.
Aby zilustrować, zróbmy wyciek pamięci w test_func() !
Wracając do code.c, dodajemy malloc() do funkcji, w ten sposób:
int test_func() { malloc(1); return 1; }
Teraz, po ponownym kompilowaniu, 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 wystąpił w kodzie źródłowym i co było w wyciekniętej pamięci. Bardzo pomocne!
Istnieje kilka zastrzeżeń dotyczących tej funkcji:
Cpputest używa makr preprocesora do dynamicznego zdefiniowania 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 będącym przedmiotem testu, ponieważ to jest skompilowane z nadpisaniami CppUTest. Wycieków w powiązanych bibliotekach nie będzie można wychwycić.
Niektóre pamięci, które są alokowane na cały czas życia procesu, nie są przeznaczone do zwolnienia. Może to spowodować wiele męczących 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



