Testowanie jednostkowe kodu C ++ - narzędzia i metodologia [zamknięte]

134

Pracuję na dużym systemie C ++, który jest rozwijany od kilku lat. W ramach starań o poprawę jakości istniejącego kodu zaangażowaliśmy się w duży, długoterminowy projekt refaktoryzacyjny.

Czy znasz dobre narzędzie, które pomoże mi pisać testy jednostkowe w C ++? Może coś podobnego do Junit lub Nunit?

Czy ktoś może udzielić dobrej rady na temat metodologii pisania testów jednostkowych dla modułów, które zostały napisane bez uwzględnienia testów jednostkowych?

Sakin
źródło
1
Sprawdź to pytanie: stackoverflow.com/questions/3150/…
Aardvark

Odpowiedzi:

83

Zastosowanie testów jednostkowych do starszego kodu było powodem napisania pracy efektywnie ze starszym kodem . Autorem jest Michael Feathers - jak wspomniano w innych odpowiedziach, był zaangażowany w tworzenie zarówno CppUnit, jak i CppUnitLite .

tekst alternatywny

Joe Schneider
źródło
4
Dodano miniaturę - głosowano w górę. Książka pomaga bardziej niż jakiekolwiek narzędzie.
Gishu,
2
Myślę, że CPPUnit może ułatwić pisanie testów. Używamy CPPUnit, ale nie jestem zadowolony. Muszę zaktualizować dwa pliki dla każdego testu i moim zdaniem test powinien być tak prosty, jak: 'TEST ("testname") {ASSERT (1 == 1);}' Z drugiej strony książka jest
pozycja
9
Od kiedy C ++ jest starsze ?!
Nils
9
Nie chodzi o to, że C ++ jest starsze - jeśli dobrze pamiętam, ta książka definiuje starszy projekt jako taki, dla którego nie ma żadnych testów jednostkowych lub jest ich niewiele. Takie projekty są zazwyczaj / trudne / do pisania w testach jednostkowych, ponieważ programowanie sterowane testami nigdy nie wpłynęło na podstawę kodu tak, że pisanie ich jest trywialne.
Arafangion
7
@Nils: Jak wspomina jeden z recenzentów książki Amazon, „stary kod to kod bez testów jednostkowych”, o co dokładnie chodzi w tym pytaniu.
David Johnstone,
40

Niedawno firma Google wydała własną bibliotekę do testowania jednostkowego aplikacji C ++ o nazwie Google Test.

Projekt w Google Code

agnul
źródło
1
czy można tego używać z VC ++
yesraaj
Wydaje się całkiem w porządku, zwłaszcza sposób, w jaki muszą dodawać opis do każdego stwierdzenia. Z drugiej strony osobiście wolę mieć klasę testów jednostkowych zamiast makr, które tak naprawdę nie wyglądają jak klasy.
Wernight
3
Kolejnym fajnym punktem są możliwości kpiny: code.google.com/p/googlemock
Philipp
Uważam, że to ZNACZNIE ładniejsze niż CPPUNIT, który wymaga mnóstwa makr i magicznych plików, aby testy działały
paulm
30

Sprawdź doskonałe porównanie kilku dostępnych apartamentów. Autor tego artykułu później opracował UnitTest ++ .

To, co szczególnie mi się w nim podoba (poza tym, że dobrze obsługuje wyjątki itp.) To to, że istnieje bardzo ograniczona ilość „administracji” wokół przypadków testowych i definicji urządzeń testowych.

andreas buykx
źródło
2
Czy to nie jest nasz podstawowy błąd? Ma dobry wgląd w dostępne projekty - ale zamiast je ulepszać, zaczyna własne.
peterchen
@peterchen: tak; ale z drugiej strony UnitTest ++ jest tak mały i lekki, że ma wartość jako oddzielny projekt - bardzo łatwo jest go uruchomić.
TimStaley
24

Boost posiada bibliotekę Testing który zawiera wsparcie dla testów jednostkowych. Może warto to sprawdzić.

Jonas
źródło
4
Mogę polecić ten doskonały zestaw narzędzi.
Rob
1
Tak, doładowanie jest drogą do zrobienia. Bez kosztów, po prostu przetestuj i gotowe! W rzeczywistości w rozpaczy pracowałem nad własnym programem, kiedy na ratunek przyszedł boost. Dziękuję boost (za wszystko!)
daramarak
Możesz przeczytać artykuł, który napisałem wprowadzenie Boost Unit Testing beroux.com/english/articles/boost_unit_testing
Wernight
21

Noel Llopis z Games From Within jest autorem książki Exploring the C ++ Unit Testing Framework Jungle , wszechstronnej (ale już nieaktualnej) oceny różnych frameworków C ++ Unit Testing, a także książki o programowaniu gier.

Używał CppUnitLite przez dłuższy czas, naprawiając różne rzeczy, ale ostatecznie połączył siły z innym autorem biblioteki testów jednostkowych i stworzył UnitTest ++ . Używamy tutaj UnitTest ++ i jak na razie bardzo mi się to podoba. Ma (dla mnie) dokładną równowagę sił przy niewielkich rozmiarach.

Użyłem rozwiązań własnych, CxxTest (który wymaga Perla) i boost :: test. Kiedy zaimplementowałem tutaj testy jednostkowe, w mojej obecnej pracy, sprowadzało się to do UnitTest ++ vs boost :: test.

Naprawdę lubię większość bibliotek boost, z których korzystałem, ale IMHO, boost :: test jest trochę zbyt uciążliwy. Szczególnie nie podobało mi się to, że wymaga (AFAIK) zaimplementowania głównego programu wiązki testowej za pomocą makra boost :: test. Wiem, że nie jest to „czysty” TDD, ale czasami potrzebujemy sposobu na uruchomienie testów z poziomu aplikacji GUI, na przykład gdy w linii poleceń jest przekazywana specjalna flaga testowa, a boost :: test nie może obsługiwać tego typu scenariuszowy.

UnitTest ++ był najprostszym środowiskiem testowym do skonfigurowania i użycia, z jakim spotkałem się w moim (ograniczonym) doświadczeniu.

Brian Stewart
źródło
17

Używam doskonałego Boost.Test biblioteki w połączeniu z dużo mniej znaną, ale niesamowitą biblioteką Turtle : pozorowaną biblioteką obiektów opartą na boost.

Ponieważ przykład kodu mówi lepiej niż słowa, wyobraź sobie, że chciałbyś przetestować calculatorobiekt, który działa na viewinterfejsie (to jest przykład wprowadzający Turtle'a):

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

Widzisz, jak łatwe i szczegółowe jest deklarowanie oczekiwania na pozorowanym obiekcie? Oczywiście test kończy się niepowodzeniem, jeśli oczekiwania nie zostaną spełnione.

przestępczość lodowa
źródło
14

Właśnie wypuściłem mój własny framework, CATCH , tam. Jest wciąż w fazie rozwoju, ale uważam, że już przewyższa większość innych frameworków. Różni ludzie mają różne kryteria, ale starałem się omówić większość obszarów bez zbyt wielu kompromisów. Spójrz na mój powiązany wpis na blogu, aby uzyskać degustację. Pięć moich najważniejszych funkcji to:

  • Tylko nagłówek
  • Automatyczna rejestracja testów funkcjonalnych i metodologicznych
  • Rozkłada standardowe wyrażenia C ++ na LHS i RHS (więc nie potrzebujesz całej rodziny makr assert).
  • Obsługa zagnieżdżonych sekcji w urządzeniu opartym na funkcjach
  • Testy nazw z wykorzystaniem języka naturalnego - generowane są nazwy funkcji / metod

Posiada również wiązania Objective-C.

philsquared
źródło
4
doctest to moja reimplementacja Catcha z ogromnym naciskiem na szybkość kompilacji - sprawdź FAQ, aby zobaczyć, czym się różnią
onqtam
9

CxxTest to lekki, łatwy w użyciu i wieloplatformowy framework podobny do JUnit / CppUnit / xUnit dla C ++.

David Sykes
źródło
6

Obecnie szukam testów jednostkowych i makiet, które mogą być używane w naszej firmie do długoterminowego kodu. Jak wiesz, lista frameworków do testów jednostkowych dla języka c ++ jest długa, więc zastosowałem kilka filtrów, aby zredukować ją do pełnego zestawu, który można dokładniej przyjrzeć. Pierwszym kryterium filtrowania było to, że musi być za darmo. Drugim kryterium była aktywność projektowa. Szukałem również frameworków do mockowania, ponieważ potrzebujesz takiego, jeśli chcesz pisać testy jednostkowe.

Wymyśliłem następującą listę (w przybliżeniu) posortowaną według aktywności, najwyższa aktywność u góry:

  • GoogleTest / GoogleMock: wielu współpracowników i używane przez samą Google. Prawdopodobnie będzie tu przez jakiś czas i otrzyma aktualizacje. W mojej prywatnej bazie kodów przełączę się na tę kombinację w nadziei, że wskoczę na najszybszy pociąg.

  • BoostTest + Turtle: Nie aktualizowany tak często, ale framework testowy jest częścią boost, więc powinien być utrzymywany. Z drugiej strony żółw jest utrzymywany głównie przez jednego faceta, ale ma urażoną aktywność, więc nie jest martwy. Zrobiłem prawie całe moje doświadczenie testowe z tą kombinacją, ponieważ korzystaliśmy już z biblioteki boost w mojej poprzedniej pracy i obecnie używam jej do mojego prywatnego kodu.

  • CppUTest: Zapewnia testowanie i mockowanie . Projekt ten był aktywny od 2008 do 2015 roku i ostatnio był dość aktywny. To odkrycie było trochę zaskakujące, ponieważ wiele projektów o znacznie mniejszej aktywności pojawia się częściej podczas wyszukiwania w Internecie (np. CppUnit, który miał ostatnią aktualizację w 2013 r.). Nie zagłębiałem się w to głębiej, więc nie mogę nic powiedzieć o szczegółach. Edytuj (16.12.2015): Niedawno wypróbowałem to i stwierdziłem, że ten framework jest trochę niezgrabny i "C-stylowy", zwłaszcza gdy używam pozorowanych klas. Wydawało się również, że ma mniejszą różnorodność twierdzeń niż inne ramy. Myślę, że jego główną zaletą jest to, że można go używać z projektami czystego C.

  • QTest: Biblioteka testowa dostarczana z frameworkiem Qt. Utrzymanie powinno być gwarantowane przez jakiś czas, ale używam go raczej jako biblioteki pomocniczej, ponieważ rejestracja testowa jest bardziej niezgrabna w IMO niż w innych frameworkach. O ile rozumiem, zmusza cię to do posiadania jednego egzaminu testowego na urządzenie testowe. Ale funkcje pomocnicze testów mogą być przydatne podczas testowania kodu Qt-Gui. Nie ma kpiny.

  • Catch: Niedawno działał, ale został opracowany głównie przez jednego gościa. Zaletą tego frameworka jest alternatywne podejście do ustalania, które pozwala na pisanie kodu wielokrotnego użytku w samym teście. Pozwala również ustawić nazwy testów jako ciągi znaków, co jest miłe, gdy zwykle zapisujesz całe zdania jako nazwy testów. Chciałbym, żeby ten styl został wyrwany i umieszczony w GoogleTest ;-)

Mock Frameworks

Liczba fałszywych frameworków jest znacznie mniejsza niż liczba frameworków testowych, ale oto te, które okazały się ostatnio aktywne.

  • Hippomock : Aktywny od 2008 r. Teraz, ale tylko z małą intensywnością.

  • FakeIt : Aktywny od 2013 roku, ale mniej więcej opracowany przez jednego gościa.

Wniosek

Jeśli Twoja baza kodu jest na dłuższą metę, wybierz między BoostTest + Turtle a GoogleTest + GoogleMock . Myślę, że ci dwaj będą mieli długoterminową konserwację. Jeśli masz tylko krótką bazę kodu, możesz wypróbować Catch, który ma ładną składnię. Wtedy musiałbyś dodatkowo wybrać mockujący framework. Jeśli pracujesz z Visual Studio, możesz pobrać adaptery test-runner dla BoostTest i GoogleTest, które pozwolą Ci na uruchamianie testów za pomocą GUI test runner zintegrowanego z VS.

Knitschi
źródło
3

Zobacz także odpowiedzi na blisko związane pytanie „Wybór narzędzia / struktury do testów jednostkowych C ++” tutaj

TonJ
źródło
3

Jest też TUT , Template-Unit-Test, framework oparty na szablonach. Jego składnia jest niezręczna (niektórzy nazywali to nadużyciem szablonu), ale jego główną zaletą jest to, że wszystko jest zawarte w jednym pliku nagłówkowym .

Tutaj znajdziesz przykład testu jednostkowego napisanego w TUT .

filant
źródło
2
Umieściłem bibliotekę zawierającą tylko nagłówek, zawierającą makra opakowujące TUT, zapewniające działanie i testujący kod dekleracji, zarówno w celu uproszczenia go, jak i dostarczenia informacji o pliku i numerze wiersza w przypadku awarii. Oto link do postu z przykładami różnic w wynikach
Josh Heitzman
2

Wypróbowałem CPPunit i nie jest on zbyt przyjazny dla użytkownika.

Jedyną alternatywą, jaką znam, jest użycie C ++ .NET do pakowania klas C ++ i pisania testów jednostkowych za pomocą jednej z platform do testów jednostkowych .NET (NUnit, MBUnit itp.)

Dror Helper
źródło
2

CppUTest to doskonały, lekki framework do testów jednostkowych C i C ++.

ratkok
źródło
1

Michael Feathers z ObjectMentor odegrał kluczową rolę w rozwoju zarówno CppUnit, jak i CppUnitLite.

Obecnie zaleca CppUnitLite

Seb Rose
źródło
1

Spójrz na CUnitWin32 . Jest napisany dla MS Visual C. Zawiera przykład.

Dushara
źródło
1

Spójrz na cfix ( http://www.cfix-testing.org ), specjalizuje się w programowaniu w Windows C / C ++ i obsługuje testy jednostkowe zarówno w trybie użytkownika, jak i trybie jądra.

Johannes Passing
źródło
Dzięki za udostępnienie. Niedawno zacząłem używać cfix do celów testowych. Szukałem sposobu, aby wyświetlić stos wywołań zarówno w przypadku pozytywnych, jak i niepomyślnych przypadków testowych. Czy istnieje sposób w cfix, aby to osiągnąć?
TryToLearn
1

Jeśli korzystasz z programu Visual Studio 2008 z dodatkiem SP1, bardzo polecam używanie MSTest do pisania testów jednostkowych. Następnie używam makiety Google do pisania makiet. Integracja z IDE jest idealna i umożliwia i nie wiąże się z narzutem CPPunit w zakresie edycji trzech miejsc na dodanie jednego testu.

Jared
źródło
1

Myślę, że VisualAssert wykonuje świetną robotę w integracji VS. Umożliwia uruchamianie i debugowanie testów z poziomu VS i nie ma potrzeby tworzenia pliku wykonywalnego w celu uruchomienia testów.

Ohad Horesh
źródło