Close Menu
    Ciekawe

    Jak podłączyć telefon do monitora? Przewodowe i bezprzewodowe sposoby

    2025-12-08

    Co można wrzucić w koszty firmy jednoosobowej? Lista i praktyczne przykłady

    2025-12-03

    Jak podłączyć okulary VR do PS4? Poradnik podłączenia i konfiguracji

    2025-12-02
    Facebook X (Twitter) Instagram
    CPP Polska
    Facebook X (Twitter) Instagram
    • Biznes

      Co można wrzucić w koszty firmy jednoosobowej? Lista i praktyczne przykłady

      2025-12-03

      Jak zapobiec wyciekom danych firmowych?

      2025-11-28

      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
    • Technologie

      Jak podłączyć telefon do monitora? Przewodowe i bezprzewodowe sposoby

      2025-12-08

      Jak podłączyć okulary VR do PS4? Poradnik podłączenia i konfiguracji

      2025-12-02

      Jak zapobiec wyciekom danych firmowych?

      2025-11-28

      Jak sprawdzić rozdzielczość monitora w Windows i macOS?

      2025-11-26

      Jak zresetować laptopa Acer do ustawień fabrycznych? Poradnik krok po kroku

      2025-11-25
    • 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++»Testy parametryzowane w Google Test – praktyczny przewodnik
    C++

    Testy parametryzowane w Google Test – praktyczny przewodnik

    Oskar KlimkiewiczBy Oskar KlimkiewiczBrak komentarzy5 Mins Read
    Share Facebook Twitter LinkedIn Email Copy Link
    Follow Us
    RSS
    a computer screen with a lot of text on it
    Share
    Facebook Twitter LinkedIn Email Copy Link

    Testy parametryzowane w Google Test – praktyczny przewodnik

    Testy parametryzowane stanowią kluczowe narzędzie w frameworku Google Test (GTest), umożliwiające wykonywanie tych samych przypadków testowych z różnymi zestawami danych wejściowych. Technika ta eliminuje redundancję kodu, zwiększa pokrycie testowe i usprawnia weryfikację algorytmów działających na zróżnicowanych danych. W przeciwieństwie do standardowych testów jednostkowych, gdzie każdy scenariusz wymaga oddzielnej implementacji, parametryzacja pozwala na centralne zarządzanie danymi testowymi i automatyczne generowanie przypadków.

    Podstawy testów parametryzowanych w GTest

    Aby utworzyć testy parametryzowane, należy zdefiniować klasę fixture dziedziczącą po testing::TestWithParam<T>, gdzie T oznacza typ parametrów testowych. Klasa ta pełni rolę kontenera dla logiki inicjalizacyjnej i sprzątającej, identycznie jak w tradycyjnych fixture’ach. Różnica polega na dostępie do parametrów poprzez metodę GetParam() w ciele testów.

    #include <gtest/gtest.h>
    class ExampleFixture : public testing::TestWithParam<int> {
    protected:
      void SetUp() override { /* inicjalizacja */ }
      void TearDown() override { /* sprzątanie */ }
    };
    

    Do definiowania samych testów wykorzystuje się makro TEST_P, którego składnia odzwierciedla strukturę TEST_F, lecz z dodatkowym dostępem do parametrów:

    TEST_P(ExampleFixture, TestCase) {
      int param = GetParam();
      ASSERT_GT(param, 0); // Przykładowa asercja
    }
    

    Kluczowym etapem jest instancjacja zestawu testowego z konkretnymi parametrami za pomocą makra INSTANTIATE_TEST_SUITE_P. Składnia:

    INSTANTIATE_TEST_SUITE_P(
      NazwaInstancji, // Unikalny prefiks dla wyników
      ExampleFixture, // Klasa fixture
      testing::Values(1, 2, 3, 4) // Generator parametrów
    );
    

    W wyniku tego zestaw testów zostanie wykonany dla każdej wartości w Values, a w wynikach pojawią się nazwy postaci NazwaInstancji/ExampleFixture.TestCase/0, /1, itd.

    Typy generatorów parametrów

    GTest oferuje kilka wbudowanych generatorów:

    • Values(v1, v2, …, vN) – jawna lista wartości;
    • Range(start, end, step) – sekwencja liczb (domyślnie step=1);
    • ValuesIn(container) – wartości z kontenera (np. vector, tablica);
    • Bool() – wartości false i true;
    • Combine(g1, g2, …) – produkt kartezjański generatorów (wymaga krotki std::tuple).

    Przykład użycia ValuesIn z wektorem:

    std::vector<std::string> inputs = {"cat", "dog"};
    INSTANTIATE_TEST_SUITE_P(
      AnimalTests,
      MyFixture,
      testing::ValuesIn(inputs)
    );
    

    Dla generatora Combine należy zadeklarować parametr jako krotkę:

    class AdvancedFixture : public testing::TestWithParam<std::tuple<int, bool>> {};
    TEST_P(AdvancedFixture, CombinedTest) {
      auto [num, flag] = GetParam();
      // ...
    }
    INSTANTIATE_TEST_SUITE_P(
      CombineDemo,
      AdvancedFixture,
      testing::Combine(
        testing::Values(1, 2),
        testing::Bool()
      )
    );
    

    Zaawansowane techniki parametryzacji

    Niestandardowe nazwy testów

    Domyślne nazwy generowane przez GTest (np. /0, /1) bywają nieczytelne. Aby temu zaradzić, można dostarczyć funkcję generującą nazwy jako czwarty argument INSTANTIATE_TEST_SUITE_P.

    std::string CustomName(const testing::TestParamInfo<std::tuple<int, bool>>& info) {
      auto [num, flag] = info.param;
      return fmt::format("{}_Flag{}", num, flag);
    }
    INSTANTIATE_TEST_SUITE_P(
      CustomNamedTests,
      AdvancedFixture,
      testing::Combine(/*...*/),
      CustomName // Wskaźnik do funkcji
    );
    

    Wynik: CustomNamedTests/AdvancedFixture.CombinedTest/0_FlagTrue

    Łączenie parametryzacji z fixture’ami

    Parametryzację można łączyć z fixture’ami klasycznymi, tworząc wielowarstwowe struktury testowe. Przykładowo, gdy potrzebne są zarówno różne typy danych, jak i wartości:

    template <typename T>
    class TypedFixture : public testing::Test {};
    TYPED_TEST_SUITE_P(TypedFixture); // Rejestracja szablonu
    TYPED_TEST_P(TypedFixture, TypeTest) {
      TypeParam value{};
      // ...
    }
    REGISTER_TYPED_TEST_SUITE_P(TypedFixture, TypeTest); // Rejestracja testów
    using Types = testing::Types<int, float, double>;
    INSTANTIATE_TYPED_TEST_SUITE_P(NumericTypes, TypedFixture, Types);
    

    Dodanie parametryzacji wartościowej wymaga rozszerzenia fixture’a o TestWithParam:

    template <typename T>
    class ComboFixture : public testing::TestWithParam<std::tuple<T, std::string>> {};
    TEST_P(ComboFixture, AdvancedTest) {
      auto [value, str] = GetParam();
      // ...
    }
    

    Testowanie interfejsów HAL

    W środowisku Android (VTS), testy parametryzowane wykorzystuje się do weryfikacji implementacji sprzętowych (HAL). Przykładowo, test USB HAL:

    class UsbHidlTest : public testing::TestWithParam<std::string> {
      void SetUp() override {
        usb = IUsb::getService(GetParam()); // Pobranie instancji
      }
      sp<IUsb> usb;
    };
    TEST_P(UsbHidlTest, SetCallback) {
      // ... test z użyciem 'usb'
    }
    INSTANTIATE_TEST_SUITE_P(
      PerInstance,
      UsbHidlTest,
      testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor))
    );
    

    Generator getAllHalInstanceNames automatycznie zbiera dostępne implementacje interfejsu.

    Przykłady praktyczne

    Testowanie roku przestępnego

    Rozważmy test logiki określającej lata przestępne. Parametry obejmują rok i oczekiwany wynik:

    struct LeapYearParams {
      int year;
      bool expected;
    };
    class LeapYearTest : public testing::TestWithParam<LeapYearParams> {};
    TEST_P(LeapYearTest, ValidityCheck) {
      auto params = GetParam();
      ASSERT_EQ(isLeapYear(params.year), params.expected);
    }
    INSTANTIATE_TEST_SUITE_P(
      LeapYearTests,
      LeapYearTest,
      testing::Values(
        LeapYearParams{2020, true},
        LeapYearParams{1900, false},
        LeapYearParams{2000, true}
      )
    );
    

    Testowanie funkcji matematycznych

    Dla funkcji addOne test z użyciem krotek:

    TEST_P(AddOneTests, CheckResults) {
      auto [input, expected] = GetParam();
      ASSERT_EQ(addOne(input), expected);
    }
    INSTANTIATE_TEST_SUITE_P(
      AddOneTests,
      AddOneTestsFixture,
      testing::Values(
        std::make_tuple(1, 2),
        std::make_tuple(-3, -2)
      )
    );
    

    Rozwiązywanie problemów i najlepsze praktyki

    Ograniczenia i pułapki

    • Struktury z wiązaniami w C++17 – w lambda-generatorach nazw nie można używać strukturalnych wiązań (auto [a,b] = ...);
    • Wskaźniki jako parametry – gdy T jest wskaźnikiem, użytkownik musi zarządzać cyklem życia danych;
    • Unikanie _ w nazwach – GTest wymaga, aby nazwy fixture’ów i testów były poprawnymi identyfikatorami C++ bez znaku podkreślenia.

    Zalecane praktyki

    1. Izolacja parametrów – każdy test powinien być niezależny; unikać współdzielonego stanu modyfikowalnego między instancjami;
    2. Czytelność wyników – generuj opisowe nazwy testów poprzez funkcje customowe;
    3. Minimalizacja zakresu – parametryzuj tylko testy wymagające wielu danych. Pozostałe implementuj jako TEST_F;
    4. Testowanie skrajnych przypadków – wartości brzegowe (np. 0, INT_MAX, puste stringi) zawsze powinny znaleźć się w parametrach.

    Podsumowanie

    Testy parametryzowane w GTest stanowią potężny mechanizm zwiększający efektywność testowania. Poprzez oddzielenie danych testowych od logiki testów, pozwalają na łatwe dodawanie przypadków i utrzymanie czytelności kodu. Połączenie generatorów (Values, Range, Combine) z możliwością definiowania własnych formatterów nazw daje elastyczność niezbędną w złożonych projektach.

    W środowiskach produkcyjnych, szczególnie w testach warstw sprzętowych (np. Android VTS), technika ta okazuje się nieoceniona dla zapewnienia kompletności walidacji. Przestrzeganie zasad izolacji testów i dbałość o czytelność wyników stanowią klucz do sukcesu w długoterminowym utrzymaniu testów parametryzowanych.

    Uwaga: Wszystkie przykłady kodu pochodzą z dokumentacji GTest i zmodyfikowanych przypadków użycia z podanych źródeł. Wdrożenie tych technik wymaga aktualnej wersji Google Test (min. 1.10) i wsparcia C++14.

    Polecane:

    • Podstawy pracy z Google Mock – kurs krok po kroku
    • Wyszukiwanie testów w Google Test – metody i narzędzia
    • Google Mock: cardinality, matcher, action w praktyce
    • Zaawansowane scenariusze z std::visit i wieloma wariantami
    • Google Mock – definiowanie zachowań i oczekiwań
    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 podłączyć telefon do monitora? Przewodowe i bezprzewodowe sposoby

    Oskar Klimkiewicz6 Mins Read

    Podłączenie telefonu do monitora to jedna z najistotniejszych innowacji ery mobilnej, umożliwiająca przeniesienie doświadczeń z…

    Co można wrzucić w koszty firmy jednoosobowej? Lista i praktyczne przykłady

    2025-12-03

    Jak podłączyć okulary VR do PS4? Poradnik podłączenia i konfiguracji

    2025-12-02

    Jak zapobiec wyciekom danych firmowych?

    2025-11-28
    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 podłączyć telefon do monitora? Przewodowe i bezprzewodowe sposoby

    2025-12-08

    Co można wrzucić w koszty firmy jednoosobowej? Lista i praktyczne przykłady

    2025-12-03

    Jak podłączyć okulary VR do PS4? Poradnik podłączenia i konfiguracji

    2025-12-02
    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.