C++ में परीक्षण: फ्रेमवर्क और टूल्स
गुणवत्तापूर्ण परीक्षण C++ में विकास का एक अनिवार्य हिस्सा है। डायनेमिक भाषाओं के विपरीत, C++ को मेमोरी प्रबंधन, ऑब्जेक्ट के जीवनकाल और प्रदर्शन पर विशेष ध्यान देने की आवश्यकता होती है। इस लेख में, हम मॉड्यूलर परीक्षण के तीन सबसे लोकप्रिय फ्रेमवर्क: Google Test, Catch2 और doctest पर चर्चा करेंगे, साथ ही अतिरिक्त टूल्स का भी उल्लेख करेंगे।
C++ में परीक्षण की आवश्यकता क्यों है?
C++ एक ऐसी भाषा है जिसमें मैन्युअल मेमोरी प्रबंधन और शक्तिशाली टेम्पलेट मैजिक है। परीक्षणों के बिना, निम्नलिखित गलतियाँ आसानी से हो सकती हैं:
- मेमोरी लीक और डबल फ्री
- पॉइंटर्स के साथ काम करते समय अपरिभाषित व्यवहार (UB)
- ऑपरेटर ओवरलोडिंग और कॉपी कंस्ट्रक्टर में त्रुटियाँ
- लेगसी कोड के रिफैक्टरिंग में रिग्रेशन
परीक्षण फ्रेमवर्क जाँच को स्वचालित करते हैं और समस्याओं को जल्दी खोजने में मदद करते हैं।
Google Test (gtest)
Google का सबसे व्यापक रूप से उपयोग किया जाने वाला फ्रेमवर्क। यह सभी मुख्य सुविधाओं का समर्थन करता है: ASSERT_* और EXPECT_* मैक्रोज़, पैरामीटराइज्ड टेस्ट, फिक्स्चर (test fixtures), डेथ-टेस्ट।
स्थापना (CMake FetchContent के माध्यम से)
include(FetchContent)FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.14.0)FetchContent_MakeAvailable(googletest)एक सरल परीक्षण का उदाहरण
#include <gtest/gtest.h>
int factorial(int n) { return (n <= 1) ? 1 : n * factorial(n - 1);}
TEST(FactorialTest, HandlesZeroInput) { EXPECT_EQ(factorial(0), 1);}
TEST(FactorialTest, HandlesPositiveInput) { EXPECT_EQ(factorial(5), 120); EXPECT_EQ(factorial(3), 6);}
int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();}फिक्स्चर और पैरामीटराइज्ड टेस्ट
class MathFixture : public ::testing::Test {protected: void SetUp() override { /* आरंभीकरण */ } void TearDown() override { /* सफाई */ }};
// पैरामीटराइज्ड टेस्टclass SumTest : public ::testing::TestWithParam<std::tuple<int, int, int>> {};TEST_P(SumTest, CheckSum) { auto [a, b, expected] = GetParam(); EXPECT_EQ(a + b, expected);}INSTANTIATE_TEST_SUITE_P(SumParams, SumTest, ::testing::Values( std::make_tuple(1, 1, 2), std::make_tuple(0, 0, 0) ));लाभ: विशाल समुदाय, CI/CD के साथ एकीकरण, शक्तिशाली मैक्रोज़, डेथ-टेस्ट का समर्थन।
नुकसान: अपेक्षाकृत धीमी संकलन, बड़ा निष्पादन योग्य फ़ाइल आकार।
Catch2
परीक्षणों की पठनीयता पर ध्यान केंद्रित करने वाला आधुनिक फ्रेमवर्क। यह BDD-शैली (Behaviour-Driven Development) का उपयोग करता है और सेक्शन (sections) का समर्थन करता है।
स्थापना (header-only)
Catch2 एक एकल हेडर फ़ाइल के रूप में वितरित किया जाता है। बस catch_amalgamated.hpp डाउनलोड करें और इसे शामिल करें।
सेक्शन के साथ उदाहरण
#define CATCH_CONFIG_MAIN#include <catch2/catch.hpp>
int divide(int a, int b) { if (b == 0) throw std::invalid_argument("division by zero"); return a / b;}
TEST_CASE("Division tests", "[math]") { SECTION("Normal division") { REQUIRE(divide(10, 2) == 5); } SECTION("Division by zero") { REQUIRE_THROWS_AS(divide(5, 0), std::invalid_argument); }}BDD-शैली (Given-When-Then)
SCENARIO("Vector push_back operation", "[container]") { GIVEN("An empty vector") { std::vector<int> v; WHEN("We push one element") { v.push_back(42); THEN("The size becomes 1") { REQUIRE(v.size() == 1); } AND_THEN("The element is correct") { REQUIRE(v[0] == 42);