Close Menu
    Ciekawe

    Jak zabezpieczyć pendrive hasłem bez dodatkowych programów?

    2025-11-13

    Ile kosztuje prowadzenie jednoosobowej działalności gospodarczej? Przegląd opłat

    2025-11-10

    Acer czy Asus – który laptop wybrać? Porównanie i porady

    2025-11-05
    Facebook X (Twitter) Instagram
    CPP Polska
    Facebook X (Twitter) Instagram
    • Biznes

      Ile kosztuje prowadzenie jednoosobowej działalności gospodarczej? Przegląd opłat

      2025-11-10

      Jak wziąć samochód w leasing bez firmy? Poradnik dla osób fizycznych

      2025-10-29

      Jak założyć firmę jednoosobową krok po kroku – koszty, formalności i czas trwania

      2025-10-23

      Ile kosztuje stworzenie strony internetowej dla firmy? Cennik i porady

      2025-10-07

      Jak usunąć profil firmy z Google i Facebooka? Instrukcja krok po kroku

      2025-10-07
    • Technologie

      Jak zabezpieczyć pendrive hasłem bez dodatkowych programów?

      2025-11-13

      Acer czy Asus – który laptop wybrać? Porównanie i porady

      2025-11-05

      Jak przenieść okno na drugi monitor? Skróty i metody dla Windows i macOS

      2025-11-01

      Jak sprawdzić specyfikację laptopa? Pełna konfiguracja sprzętowa

      2025-10-26

      Co to jest VR? Wirtualna rzeczywistość i jej zastosowania

      2025-10-20
    • Programowanie

      Maszyna stanów oparta o std::variant

      2025-10-07

      Tablice w C++ od podstaw – deklaracja, inicjalizacja, iteracja i typowe pułapki

      2025-10-07

      std::deque w C++ – kiedy wybrać dwukierunkową kolejkę zamiast vectora

      2025-10-07

      itoa i std::to_chars – konwersja liczb na tekst bez narzutu wydajności

      2025-10-07

      strcpy vs strncpy vs std::string – bezpieczne kopiowanie łańcuchów w C++

      2025-10-07
    • Inne

      Jak prowadzić blog programistyczny i dzielić się wiedzą?

      2025-06-28
    CPP Polska
    Home»C++»Wprowadzenie do testów jednostkowych z Google Test
    C++

    Wprowadzenie do testów jednostkowych z Google Test

    Oskar KlimkiewiczBy Oskar KlimkiewiczBrak komentarzy4 Mins Read
    Share Facebook Twitter LinkedIn Email Copy Link
    Follow Us
    RSS
    woman in pink shirt sitting in front of black laptop computer
    Share
    Facebook Twitter LinkedIn Email Copy Link

    Wprowadzenie do testów jednostkowych z Google Test

    Google Test (gtest) to zaawansowana rama testująca dla C++ stworzona przez Google, umożliwiająca pisanie niezależnych, powtarzalnych i dobrze zorganizowanych testów jednostkowych. Bazując na architekturze xUnit, gtest oferuje bogaty zestaw asercji, obsługę testów parametryzowanych oraz integrację z nowoczesnymi systemami budowania jak CMake. Testy jednostkowe stanowią kluczowy element rozwoju oprogramowania, pełniąc rolę „wykonywalnej specyfikacji” systemu, dokumentując jego zachowanie w różnych scenariuszach i umożliwiając bezpieczny refaktoring kodu. Zasady FIRST (szybkie, niezależne, powtarzalne, samokontrolujące się, pisane w odpowiednim czasie) stanowią fundament efektywnego testowania jednostkowego, gdzie izolacja testowanego systemu (SUT) od zależności poprzez obiekty pozorujące (Test Doubles) jest kluczowa. Google Test implementuje te zasady, pozwalając na automatyczne uruchamianie testów bez ręcznej enumeracji, eksport wyników do XML oraz współpracę z wieloma platformami i kompilatorami.

    Podstawowe koncepcje testowania

    Testy jednostkowe weryfikują najmniejsze jednostki kodu w izolacji od zależności zewnętrznych. Ich główne cele obejmują: wykrywanie błędów na wczesnym etapie cyklu rozwojowego, dokumentowanie zachowań systemu, redukcję ryzyka regresji oraz umożliwienie bezpiecznego wprowadzania zmian w kodzie. Skuteczne testy charakteryzują się:

    • Niezależnością – brak współdzielenia stanu między testami eliminuje interferencje;
    • Szybkością – umożliwiają częste uruchamianie w procesie CI/CD;
    • Wyraźną intencją – nazwy testów precyzyjnie opisują weryfikowany scenariusz;
    • Jednozagadnieniowością – każdy test koncentruje się na pojedynczej funkcjonalności.

    Struktura testów w Google Test bazuje na trzech fundamentalnych pojęciach: asercjach (instrukcje weryfikujące warunki), testach (funkcje zawierające asercje) oraz pakietach testowych (grupy logicznie powiązanych testów). Asercje dzielą się na fatalne (ASSERT_*) przerywające test przy niepowodzeniu oraz niezakończone (EXPECT_*) pozwalające na kontynuację pomimo błędu. Przykładowo, ASSERT_EQ(a,b) weryfikuje równość wartości, podczas gdy EXPECT_TRUE(condition) sprawdza prawdziwość warunku bez przerywania testu.

    Konfiguracja środowiska testowego

    Integracja Google Test z projektem odbywa się poprzez dołączenie biblioteki do systemu budowania. W przypadku CMake minimalna konfiguracja wymaga:

    cmake_minimum_required(VERSION 3.14)
    project(example_project)
    set(CMAKE_CXX_STANDARD 17)
    include(FetchContent)
    FetchContent_Declare(
      googletest
      URL https://github.com/google/googletest/archive/<commit_hash>.zip
    )
    FetchContent_MakeAvailable(googletest)
    add_executable(tests test.cpp)
    target_link_libraries(tests PRIVATE gtest_main)
    

    Gdzie <commit_hash> oznacza identyfikator konkretnej wersji gtest. Alternatywnie, użycie menedżerów pakietów jak vcpkg lub Conan upraszcza proces poprzez automatyzację zależności:

    cmake .. -DCMAKE_TOOLCHAIN_FILE=[path/to/vcpkg.cmake]
    

    Umożliwia to kompilację testów poleceniem cmake --build . i uruchomienie za pomocą ctest. Podstawowy program testujący zawiera inicjalizację frameworka i uruchomienie wszystkich testów:

    #include <gtest/gtest.h>
    int main(int argc, char **argv) {
      ::testing::InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
    }
    

    Pisanie podstawowych testów

    Makro TEST() definiuje pojedynczy test, przyjmując nazwę pakietu testowego i unikalną nazwę testu:

    TEST(TestSuiteName, TestName) {
      // Konfiguracja SUT object;
      // Weryfikacja
      EXPECT_EQ(object.method(), expected_value);
    }
    

    Testy funkcji silnia demonstrują praktyczne zastosowanie:

    TEST(FactorialTest, HandlesZero) {
      EXPECT_EQ(Factorial(0), 1);
    }
    TEST(FactorialTest, HandlesPositive) {
      EXPECT_EQ(Factorial(1), 1);
      EXPECT_EQ(Factorial(3), 6);
    }
    

    Każdy test jest niezależną jednostką kompilowaną i wykonywaną w izolacji. W przypadku niepowodzenia asercji Google Test precyzyjnie zgłasza:

    • lokalizację błędu (plik, linia),
    • oczekiwaną i rzeczywistą wartość,
    • dodatkową informację diagnostyczną.

    Zaawansowane techniki testowania

    Dla scenariuszy wymagających współdzielenia konfiguracji między testami Google Test wprowadza fixtury testowe – klasy dziedziczące po ::testing::Test:

    class DatabaseTest : public ::testing::Test {
     protected:
      void SetUp() override {
        db.Connect("test_db");
      }
      void TearDown() override {
        db.Disconnect();
      }
      Database db;
    };
    
    TEST_F(DatabaseTest, InsertRecord) {
      EXPECT_TRUE(db.Insert("data"));
    }
    
    TEST_F(DatabaseTest, QueryRecord) {
      db.Insert("sample");
      EXPECT_EQ(db.Query("sample"), "data");
    }
    

    Makro TEST_F() wykorzystuje fixturę, automatycznie wywołując SetUp() przed i TearDown() po każdym teście. Dla testów operujących na różnych typach danych stosuje się testy parametryzowane typem –

    template <typename T>
    class ContainerTest : public ::testing::Test {
     protected:
      Container<T> container;
    };
    TYPED_TEST_SUITE_P(ContainerTest);
    
    TYPED_TEST_P(ContainerTest, InsertElement) {
      TypeParam value = TypeParam();
      this->container.Add(value);
      EXPECT_EQ(this->container.Size(), 1);
    }
    
    REGISTER_TYPED_TEST_SUITE_P(ContainerTest, InsertElement);
    
    using Types = testing::Types<int, double, std::string>;
    INSTANTIATE_TYPED_TEST_SUITE_P(ContainerTypes, ContainerTest, Types);
    

    Pozwala to na generowanie wersji testu dla każdego typu z listy. Testy parametryzowane wartościowo umożliwiają iterowanie po zbiorze danych wejściowych:

    struct InputOutput { int input; int output; };
    class CalcTest : public testing::TestWithParam<InputOutput> {};
    
    TEST_P(CalcTest, Process) {
      auto params = GetParam();
      EXPECT_EQ(Process(params.input), params.output);
    }
    
    INSTANTIATE_TEST_SUITE_P(Default, CalcTest, testing::Values(
      InputOutput{2,4},
      InputOutput{-1,1}
    ));
    

    Generowane są osobne testy dla każdej pary wartości.

    Integracja z procesem rozwoju

    W środowiskach IDE jak Visual Studio testy Google Test integrują się z Eksploratorem Testów, umożliwiając:

    • selektywne uruchamianie grup testów,
    • debugowanie nieudanych testów,
    • generowanie raportów pokrycia kodu. W procesie CI/CD uruchamianie testów może być egzekwowane jako brama jakości przed scaleniem kodu, co zapewnia, że zmiany nie wprowadzają regresji. Eksport wyników do formatu JUnit XML umożliwia integrację z systemami jak Jenkins lub GitLab CI.

    Wnioski

    Google Test stanowi dojrzałe rozwiązanie dla testów jednostkowych w C++, oferując zarówno podstawowe funkcjonalności jak asercje i prostą konfigurację, jak i zaawansowane mechanizmy w postaci fikstur, parametryzacji oraz mocków. Jego integracja z nowoczesnymi systemami budowania i środowiskami programistycznymi czyni go uniwersalnym narzędziem wspierającym rozwój oprogramowania od fazy prototypu po wdrożenie produkcyjne. Przestrzeganie zasad FIRST w połączeniu z funkcjonalnościami Google Test pozwala tworzyć testy, które nie tylko weryfikują poprawność kodu, ale także pełnią rolę żywej dokumentacji i zabezpieczenia przed regresją. Dalszy rozwój frameworka koncentruje się na rozszerzaniu obsługi nowych standardów C++, usprawnianiu integracji z systemami CI/CD oraz rozwijaniu narzędzi diagnostycznych do analizy nieudanych testów.

    Polecane:

    • Podstawy pracy z Google Mock – kurs krok po kroku
    • CMake w praktyce – konfiguracja wieloplatformowych projektów
    • Testy parametryzowane w Google Test – praktyczny przewodnik
    • Wyszukiwanie testów w Google Test – metody i narzędzia
    • Nowe możliwości CMake – co przynosi najnowsza wersja
    Share. Facebook Twitter LinkedIn Email Copy Link
    Oskar Klimkiewicz
    • Website

    Inżynier oprogramowania specjalizujący się w C++, absolwent Wydziału Elektroniki i Technik Informacyjnych Politechniki Warszawskiej. Od ponad 8 lat projektuje i rozwija systemy o wysokiej dostępności, głównie dla branży fintech i IoT. PS. Zdjęcie wyretuszowane przez AI :)

    Podobne artykuły

    Maszyna stanów oparta o std::variant

    8 Mins Read

    Tablice w C++ od podstaw – deklaracja, inicjalizacja, iteracja i typowe pułapki

    4 Mins Read

    std::deque w C++ – kiedy wybrać dwukierunkową kolejkę zamiast vectora

    4 Mins Read
    Leave A Reply Cancel Reply

    Oglądaj, słuchaj, ćwicz - zdobywaj nowe umiejętności online
    Nie przegap

    Jak zabezpieczyć pendrive hasłem bez dodatkowych programów?

    Oskar Klimkiewicz5 Mins Read

    Zabezpieczenie danych na przenośnych nośnikach USB jest kluczowe we współczesnym środowisku cyfrowym, gdzie zagrożenia cybernetyczne…

    Ile kosztuje prowadzenie jednoosobowej działalności gospodarczej? Przegląd opłat

    2025-11-10

    Acer czy Asus – który laptop wybrać? Porównanie i porady

    2025-11-05

    Jak przenieść okno na drugi monitor? Skróty i metody dla Windows i macOS

    2025-11-01
    Social media
    • Facebook
    • Twitter
    • LinkedIn
    O nas
    O nas

    CPP Polska to serwis internetowy poświęcony technologii, programowaniu, IT, biznesowi i finansom. Znajdziesz tu porady, wskazówki i instrukcje dla wszystkich czytelników IT & Tech & Biz.

    Facebook X (Twitter) LinkedIn RSS
    Najnowsze

    Jak zabezpieczyć pendrive hasłem bez dodatkowych programów?

    2025-11-13

    Ile kosztuje prowadzenie jednoosobowej działalności gospodarczej? Przegląd opłat

    2025-11-10

    Acer czy Asus – który laptop wybrać? Porównanie i porady

    2025-11-05
    Popularne

    Skrajnie niepotrzebne, skrajne przypadki w C++

    2025-06-28

    Wyszukiwanie testów w Google Test – metody i narzędzia

    2025-06-28

    Czy C jest wolniejszy od C++? Zero-cost abstraction w praktyce

    2025-06-28
    © 2025 CPP Polska. Wszelkie prawa zastrzeżone.
    • Lista publikacji
    • Współpraca
    • Kontakt

    Type above and press Enter to search. Press Esc to cancel.