{"id":3060,"date":"2025-07-13T14:48:22","date_gmt":"2025-07-13T14:48:22","guid":{"rendered":"https:\/\/www.yazilimperver.com\/?p=3060"},"modified":"2025-07-13T14:48:22","modified_gmt":"2025-07-13T14:48:22","slug":"arac-sdl3-birim-testler","status":"publish","type":"post","link":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/","title":{"rendered":"[ARA\u00c7] SDL3 Birim Testler"},"content":{"rendered":"<p>Evet, sevgili yaz\u0131l\u0131mperver dostlar\u0131m son yaz\u0131lar\u0131mla birlikte art\u0131k SDL3 uygulamalar\u0131n\u0131z\u0131 olu\u015fturmaya ba\u015flad\u0131\u011f\u0131n\u0131z\u0131 d\u00fc\u015f\u00fcn\u00fcyorum. Bu yaz\u0131lar ile birlikte, SDL3 giri\u015f yapm\u0131\u015f ve yaz\u0131l\u0131m tasar\u0131m \u00f6r\u00fcnt\u00fclerini de kulland\u0131\u011f\u0131m\u0131z temel bir \u00f6rnek olu\u015fturmu\u015ftuk.<\/p>\n<p><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2025\/06\/09\/arac-sdl3-ilk-adimlar-i\/\"><strong>[ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar &#8211; I<\/strong><\/a><\/span><\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2025\/06\/24\/arac-sdl3-ilk-adimlar-ii\/\">[ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar \u2013 II<\/a><\/strong><\/span><\/p>\n<p>Bu yaz\u0131m\u0131zda ise, yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinin \u00f6nemli bir par\u00e7as\u0131 olan birim testlere e\u011filerek, en son geli\u015ftirdi\u011fimiz uygulama i\u00e7in gerekli birim testleri (tabi ki yapay zeka yard\u0131m\u0131 ile \ud83d\ude42 ) olu\u015fturarak projemize ekliyor olaca\u011f\u0131z. Bunu yaparken nelere dikkat etmemiz gerekti\u011fine, cmake&#8217;i nas\u0131l kullanaca\u011f\u0131m\u0131za ve ilgili test projesini nas\u0131l olu\u015fturaca\u011f\u0131m\u0131za bakaca\u011f\u0131z.<\/p>\n<p>Yaz\u0131l\u0131m geli\u015ftirme hayat\u0131n\u0131z boyunca, vazge\u00e7mememiz gereken (elbette istisnalar olabilir) en \u00f6nemli hususlardan birisi de birim testlerdir. Birim testler, geli\u015ftirdi\u011finiz yaz\u0131l\u0131mlar\u0131n\u0131z\u0131n g\u00fcrb\u00fczl\u00fc\u011f\u00fc i\u00e7in ilk sat\u0131ht\u0131r. Bu testler ile ilk etapta temel kabiliyetleri do\u011frular sonras\u0131nda ise her de\u011fi\u015fiklikte yaz\u0131l\u0131m\u0131n b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fcn korundu\u011funu garanti alt\u0131na almam\u0131za yard\u0131mc\u0131 olur.<\/p>\n<p>Birim testler geli\u015ftirilirken d\u00fc\u015f\u00fclen ikilemlerden birisi de, bunlara ger\u00e7ekten vakit ay\u0131rmal\u0131 m\u0131y\u0131zd\u0131r? Bazen bunlar vakit kayb\u0131 olarak da g\u00f6r\u00fcnse de (ilk etapta elbette alt yap\u0131n\u0131n aya\u011fa kald\u0131r\u0131lmas\u0131 ve birim testlerin yaz\u0131lmas\u0131 i\u00e7in biraz emek gerekiyor), sonras\u0131nda bunun sizlere d\u00f6n\u00fc\u015f\u00fc ve kazanc\u0131 \u00e7ok daha b\u00fcy\u00fck olacakt\u0131r. Neyse bu yaz\u0131m\u0131z\u0131n amac\u0131 birim testler de\u011fil ama k\u0131saca birim testlerin faydalar\u0131n\u0131 s\u0131ralay\u0131p, merakl\u0131 okuyucular\u0131m\u0131 daha \u00f6nce bu minvalde kaleme ald\u0131\u011f\u0131m yaz\u0131lara y\u00f6nlendiriyorum. Birim testlerin faydalar\u0131n\u0131 k\u0131saca s\u0131ralayacak olursak:<\/p>\n<ul>\n<li>Kodun mod\u00fclerize edilmesine, daha kolay test edilebilir par\u00e7alara ayr\u0131lmas\u0131na yard\u0131mc\u0131 olur,<\/li>\n<li>Hatalar daha kolay ve h\u0131zl\u0131 bir \u015fekilde bulman\u0131za olanak sa\u011flar,<\/li>\n<li>Her birim taraf\u0131ndan sunulan i\u015flevsellik daha iyi anla\u015f\u0131l\u0131r,<\/li>\n<li>Yaz\u0131l\u0131m\u0131n hayat d\u00f6ng\u00fcs\u00fcnde ileri zamanlarda yap\u0131lacak g\u00fcncellemelerin do\u011fru bir \u015fekilde yap\u0131ld\u0131\u011f\u0131ndan emin olunur (alt seviye regresyon testleri olarak d\u00fc\u015f\u00fcnebilirsiniz),<\/li>\n<li>Zaman kazand\u0131r\u0131r ve maliyeti d\u00fc\u015f\u00fcr\u00fcr.<\/li>\n<\/ul>\n<p>Daha \u00f6nce bu konuya de\u011findi\u011fim yaz\u0131lara da a\u015fa\u011f\u0131dan ula\u015fabilirsiniz:<\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/09\/30\/birim-test-tavsiyeleri\/\">Birim Test Tavsiyeleri<\/a><\/strong><\/span><\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\">Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon<\/a><\/strong><\/span><\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2024\/08\/01\/uengine4-github-actions\/\">uEngine4 &#8211; GitHub Actions<\/a><\/strong><\/span><\/p>\n<p>Evet gelelim SDL3 \u00f6rne\u011fimize. Biz \u00f6rne\u011fimizde google test ve mock kullan\u0131yor olaca\u011f\u0131z. Bu k\u00fct\u00fcphanelerin nas\u0131l kullan\u0131laca\u011f\u0131na da burada de\u011finmeyece\u011fim, yukar\u0131daki yaz\u0131larda bunlara de\u011findim.<\/p>\n<p>Birim testler genel olarak kodlar\u0131m\u0131z ile birlikte ya\u015farlar ve dizin olarak da onlara yak\u0131n olurlar. Biz de benzer bir yakla\u015f\u0131m izleyece\u011fiz (asl\u0131na bakarsan\u0131z C++ \u015fablon repomuzda da bu \u015fekilde \ud83d\ude42 ). Ana dizin alt\u0131nda bulunan &#8220;\/test&#8221; dizini i\u00e7erisinde ilgili test kodlar\u0131m\u0131z bulunuyor olacak.<\/p>\n<p>Testleri yazd\u0131rmak i\u00e7in ise VsCode ile GitHub CoPilot&#8217;u kullanaca\u011f\u0131m. Belki ayr\u0131 bir yaz\u0131da, VsCode i\u00e7erisinden, CoPilot&#8217;\u0131 nas\u0131l kullanaca\u011f\u0131m\u0131za da de\u011finebiliriz. Muhtemelen \u00fcretti\u011fi kodlara ufak dokunu\u015flar yapmak gerekecektir ama bu a\u015famada sunaca\u011f\u0131 testlerin yeterli olaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcn\u00fcyorum.<\/p>\n<p>\u0130lk olarak ana proje dizininde bulunan cmake beti\u011fine test dizinini ekliyoruz:<\/p>\n<pre class=\"lang:c decode:true \">if(BUILD_TESTING)\r\n\u00a0\u00a0\u00a0 add_subdirectory(test)\u00a0\r\nendif()<\/pre>\n<p>Bundan sonra uygulama kodlar\u0131m\u0131z\u0131 birim testlere nas\u0131l dahil edece\u011fimize s\u0131ra geldi. Bunun i\u00e7in farkl\u0131 y\u00f6ntemler mevcut, biz burada genel kabul g\u00f6ren, ilgili kod par\u00e7alar\u0131n\u0131 statik k\u00fct\u00fcphane haline getirip daha sonra bunu ilgili test projesinde ba\u011flama yakla\u015f\u0131m\u0131n\u0131 tercih edece\u011fiz.<\/p>\n<p>Peki ba\u015fka nas\u0131l yapabiliriz? \u0130lgili kod par\u00e7alar\u0131n\u0131 ilgili test projesine ayr\u0131 ayr\u0131 ekleyebiliriz. K\u00fc\u00e7\u00fck projeler i\u00e7in bu olabilir ama projeniz b\u00fcy\u00fcd\u00fck\u00e7e bu zor olacakt\u0131r.<\/p>\n<p>CMake kulland\u0131\u011f\u0131m\u0131z i\u00e7in statik k\u00fct\u00fcphane olu\u015fturmak bizim i\u00e7in \u00e7ok da s\u0131k\u0131nt\u0131 olmayacak sadece a\u015fa\u011f\u0131daki sat\u0131r\u0131 eklememiz yeterli olacak. \u0130lgili cmake betik dosyas\u0131n\u0131 inceledi\u011finizde, ana uygulama projesine de art\u0131k, kaynak kodlar\u0131 tek tek eklemiyor, yeni ekledi\u011fimiz statik k\u00fct\u00fcphane target&#8217;\u0131n\u0131 ba\u011fl\u0131yoruz.<\/p>\n<pre class=\"lang:c decode:true \">set(TARGET_UNIT_TEST_LIB ${TARGET_NAME}-lib)\r\nadd_library(${TARGET_UNIT_TEST_LIB} \"\")\r\ntarget_sources(${TARGET_UNIT_TEST_LIB} PRIVATE\r\n\u00a0 \u00a0 src\/components.cpp\r\n\u00a0 \u00a0 src\/event-system.cpp\r\n\u00a0 \u00a0 src\/render-strategies.cpp\r\n\u00a0 \u00a0 src\/renderer.cpp\r\n\u00a0 \u00a0 src\/sdl-application.cpp\r\n\u00a0 \u00a0 src\/graphical-object-factory.cpp\r\n)\r\n\r\ntarget_link_libraries(${TARGET_NAME}\r\n\u00a0 \u00a0 PRIVATE SDL3::SDL3 ${TARGET_UNIT_TEST_LIB}\r\n)<\/pre>\n<p>Bir sonraki ad\u0131m, test projemiz i\u00e7in kullanaca\u011f\u0131m\u0131z google test k\u00fct\u00fcphanesinin ilgili birim test projesine dahil edilmesi olacak. Bunun i\u00e7in a\u015fa\u011f\u0131daki g\u00fcncellemeleri yapaca\u011f\u0131z cmake i\u00e7erisinde. Bu sat\u0131rlar ile cmake \u00fczerinden, konfig\u00fcrasyon zaman\u0131nda ilgili k\u00fct\u00fcphaneyi indirerek derlemekte ve kullan\u0131m\u0131n\u0131za sunmakta.<\/p>\n<pre class=\"lang:c decode:true\">include(FetchContent)\r\n\r\nFetchContent_Declare(\r\n    googletest\r\n    URL https:\/\/github.com\/google\/googletest\/archive\/refs\/tags\/v1.13.0.zip\r\n)\r\nFetchContent_MakeAvailable(googletest)\r\n\r\n...\r\n\r\n# Testleri aktiflestirelim\r\nenable_testing()\r\n\r\ntarget_link_libraries(${TEST_TARGET_NAME} \r\n    GTest::gtest_main \r\n    sdl3-example-app-lib\r\n)\r\n\r\ninclude(GoogleTest)\r\ngtest_discover_tests(${TEST_TARGET_NAME})\r\n\r\n<\/pre>\n<p>Bu ayarlamalar\u0131 da yapt\u0131ktan sonra s\u0131ra geldi birim testlerimize. Bu yaz\u0131m\u0131z i\u00e7in, birim testleri, as\u0131l kaynak kodlar\u0131 yazd\u0131ktan sonra yaz\u0131yoruz ama bu a\u00e7\u0131k\u00e7as\u0131, yaz\u0131 dizisinin anlam b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korumak i\u00e7in. Normal \u015fartlarda, kendi yaz\u0131l\u0131m\u0131n\u0131z\u0131 geli\u015ftirirken, s\u0131n\u0131flar\u0131n\u0131z i\u00e7in birim testleri peyder pey yaz\u0131yor olman\u0131zda fayda var. Her eklenen public fonksiyon i\u00e7in birim testlerinizi yazmaya ba\u015flayabilirsiniz.<\/p>\n<p>\u015eimdi konumuza geri d\u00f6nelim ve <em>SDLResource<\/em> s\u0131n\u0131f\u0131m\u0131zdan ba\u015flayarak birim test yazmaya ba\u015flayal\u0131m dilerseniz. Bu s\u0131n\u0131f\u0131m\u0131z bir \u00f6nceki yaz\u0131m\u0131zda RAII prensibine g\u00f6re SDL kaynaklar\u0131n\u0131n jenerik bir \u015fekilde y\u00f6netilmesi i\u00e7in kullanabilece\u011finiz bir s\u0131n\u0131f.<\/p>\n<p>Bu s\u0131n\u0131f i\u00e7in birim testleri \u00fcretmek i\u00e7in, <em>SDLResource<\/em> s\u0131n\u0131f\u0131na giderek, ilgili kod par\u00e7as\u0131n\u0131 se\u00e7ip, copilot&#8217;a birim test \u00fcret dedi\u011fimizde muhtemelen <strong>sdl_resource_test.cpp<\/strong> deki gibi bir kod \u00fcretiliyor olacak. Burada, <strong>ilk de\u011finece\u011fimiz konu<\/strong>, <strong>birim test dosya isimlendirmesi<\/strong>. Her\u015feyde oldu\u011fu gibi burada bir standart izlemekte fayda var ve biz uygulamalar\u0131m\u0131zda &#8220;s\u0131n\u0131f-ismi-test.cpp&#8221; isimlendirmesini takip ediyor olaca\u011f\u0131z.<\/p>\n<p>\u00dcretilen testlere y\u00f6nelik de\u011finece\u011fim <strong>ikinci konu<\/strong> ise, <strong>birim testlerin isimlendirilmesi<\/strong>. Burada, a\u00e7\u0131k\u00e7as\u0131 testlerin ne yapmas\u0131 gerekti\u011fine odaklanarak, testin ne yapmay\u0131 hedefledi\u011fini ifade edecek bir isimlendirme yapmay\u0131 tercih ediyorum. Bu bazen uzun olabiliyor, bununla birlikte birim testler i\u00e7in bunun bir problem te\u015fkil etmedi\u011fini d\u00fc\u015f\u00fcn\u00fcyorum. Elbette burada, birden fazla &#8220;and&#8221;&#8216;ler ile bir \u015feyleri test edip\/do\u011frulamaktan ka\u00e7\u0131nmakta fayda var.<\/p>\n<p>A\u015fa\u011f\u0131da, benim \u00fcretti\u011fim testleri g\u00f6rebilirsiniz:<\/p>\n<pre class=\"lang:c++ decode:true\">#include &lt;gtest\/gtest.h&gt;\r\n#include &lt;sdl-resource.h&gt;\r\n\r\n\/\/ Sahte kaynak ve silici (deleter) fonksiyon\r\nstruct MockResource {\r\n    int value;\r\n};\r\n\r\nstatic int delete_call_count = 0;\r\nvoid MockDeleter(MockResource* resource) {\r\n    if (resource) {\r\n        ++delete_call_count;\r\n        delete resource;\r\n    }\r\n}\r\n\r\nusing Resource = SDLResource&lt;MockResource, MockDeleter&gt;;\r\n\r\nclass SDLResourceTest : public ::testing::Test {\r\nprotected:\r\n    void SetUp() override {\r\n        delete_call_count = 0;\r\n    }\r\n};\r\n\r\nTEST_F(SDLResourceTest, ConstructorShouldStoreGivenResource) {\r\n    auto* raw = new MockResource{42};\r\n    Resource res(raw);\r\n    EXPECT_EQ(res.Get(), raw);\r\n    EXPECT_TRUE(res.IsValid());\r\n}\r\n\r\nTEST_F(SDLResourceTest, DestructorShouldCallDeleterWhenResourceIsValid) {\r\n    {\r\n        auto* raw = new MockResource{42};\r\n        Resource res(raw);\r\n    }\r\n    EXPECT_EQ(delete_call_count, 1);\r\n}\r\n\r\n\r\nTEST_F(SDLResourceTest, DestructorShouldNotCallDeleterWhenResourceIsNull) {\r\n    {\r\n        Resource res(nullptr);\r\n    }\r\n    EXPECT_EQ(delete_call_count, 0);\r\n}\r\n\r\nTEST_F(SDLResourceTest, MoveConstructorShouldTransferOwnership) {\r\n    auto* raw = new MockResource{42};\r\n    Resource res1(raw);\r\n    Resource res2(std::move(res1));\r\n\r\n    EXPECT_EQ(res2.Get(), raw);\r\n    EXPECT_FALSE(res1.IsValid());\r\n    EXPECT_TRUE(res2.IsValid());\r\n}\r\n\r\nTEST_F(SDLResourceTest, MoveAssignmentShouldTransferOwnershipAndCallDeleterOnOldResource) {\r\n    auto* raw1 = new MockResource{1};\r\n    auto* raw2 = new MockResource{2};\r\n\r\n    Resource res1(raw1);\r\n    Resource res2(raw2);\r\n\r\n    res2 = std::move(res1);\r\n\r\n    EXPECT_EQ(res2.Get(), raw1);\r\n    EXPECT_FALSE(res1.IsValid());\r\n    EXPECT_TRUE(res2.IsValid());\r\n    EXPECT_EQ(delete_call_count, 1); \/\/ raw2 silinmi\u015f olmal\u0131\r\n}\r\n\r\nTEST_F(SDLResourceTest, MoveAssignmentShouldHandleSelfAssignmentGracefully) {\r\n    auto* raw = new MockResource{42};\r\n    Resource res(raw);\r\n    res = std::move(res); \/\/ kendi kendine move\r\n\r\n    EXPECT_EQ(res.Get(), raw); \/\/ kaynak kaybolmamal\u0131\r\n    EXPECT_TRUE(res.IsValid());\r\n    EXPECT_EQ(delete_call_count, 0);\r\n}\r\n\r\nTEST_F(SDLResourceTest, ReleaseShouldReturnAndClearInternalPointer) {\r\n    auto* raw = new MockResource{123};\r\n    Resource res(raw);\r\n\r\n    auto* released = res.Release();\r\n\r\n    EXPECT_EQ(released, raw);\r\n    EXPECT_FALSE(res.IsValid());\r\n\r\n    \/\/ Manuel silmek gerekir \u00e7\u00fcnk\u00fc art\u0131k RAII d\u0131\u015f\u0131\r\n    MockDeleter(released);\r\n    EXPECT_EQ(delete_call_count, 1);\r\n}\r\n\r\nTEST_F(SDLResourceTest, BoolConversionShouldReflectValidity) {\r\n    Resource valid(new MockResource{});\r\n    Resource invalid(nullptr);\r\n\r\n    EXPECT_TRUE(valid);\r\n    EXPECT_FALSE(invalid);\r\n}<\/pre>\n<p>S\u0131n\u0131f\u0131m\u0131z i\u00e7in gerekli birim testleri yazd\u0131ktan sonra gelelim <strong>\u00fc\u00e7\u00fcnc\u00fc konuya<\/strong>. Birim test yazd\u0131k g\u00fczel de, bu testler geli\u015ftirdi\u011fimiz kodlar\u0131n y\u00fczde ka\u00e7\u0131n\u0131 i\u00e7eriyor. \u0130\u015fte buna birim test kapsama oran\u0131 diyoruz (<em>u\u0131nit test coverage<\/em>). Bunun \u00f6l\u00e7\u00fcm\u00fc, birim testlerin ko\u015fturularak, buradan \u00e7a\u011fr\u0131lan fonksiyonlar\u0131 analiz edip hangi sat\u0131rlar\u0131n \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131 temeline dayanmakta (\u015fimdi gidip ben elle b\u00fct\u00fcn API&#8217;leri \u00e7a\u011f\u0131rsam, kapsama oran\u0131 %100 olmaz m\u0131 diye sorabilirsiniz, elbette olur ama bu da kendimizi kand\u0131rmaktan ba\u015fka bir i\u015fe yaramaz \u00f6yle de\u011fil mi:) ).<\/p>\n<p>Bu i\u015f i\u00e7in de yine bir \u00e7ok haz\u0131r ara\u00e7 bulunmakta. Ben burada linux i\u00e7in <em><strong>gcov + lcov<\/strong><\/em> ile <em><strong>gcovr<\/strong><\/em>&#8216;u kullanaca\u011f\u0131m. <strong>Gcov<\/strong>, kapsama analizi verilerini \u00fcretiyor, <strong>lcov<\/strong> ile <strong>gcovr<\/strong> ise bunlar\u0131 kullanarak raporlama yap\u0131yor. Windows i\u00e7in ise opencppcoverage arac\u0131 da olduk\u00e7a kullan\u0131\u015fl\u0131 bir ara\u00e7.<\/p>\n<p>\u00d6ncelikle bu ara\u00e7lar\u0131 y\u00fcklememiz gerekiyor. A\u015fa\u011f\u0131daki sat\u0131rlar ile bunlar\u0131 kurabilirsiniz:<\/p>\n<pre class=\"lang:sh decode:true \">sudo apt install lcov gcovr<\/pre>\n<p>Daha sonra, test projesinin cmake beti\u011fi i\u00e7erisine a\u015fa\u011f\u0131daki sat\u0131rlar\u0131 ekliyorsunuz. Bu sayede derleyici, yaz\u0131l\u0131m olu\u015fturma a\u015famas\u0131nda gerekli eklemeleri yap\u0131yor.<\/p>\n<pre class=\"lang:c decode:true \">target_compile_options(SDLResourceTest PRIVATE --coverage)\r\ntarget_link_options(SDLResourceTest PRIVATE --coverage)<\/pre>\n<p>Daha sonra build dizinini silip, test uygulamam\u0131z\u0131 ba\u015ftan derleyelim. Sonra da testleri ko\u015ftural\u0131m ve a\u015fa\u011f\u0131daki komutlar\u0131 \u00e7a\u011f\u0131ral\u0131m:<\/p>\n<pre class=\"lang:sh decode:true \">lcov --capture --directory . --output-file coverage.info      \r\nlcov --remove coverage.info '*test*' '\/usr\/*' --output-file coverage_filtered.info\r\ngenhtml coverage_filtered.info --output-directory coverage_report<\/pre>\n<p>Yukar\u0131daki komutlar\u0131 \/scripts dizini alt\u0131ndaki generate_coverage.sh beti\u011fi ile de \u00e7a\u011f\u0131rabilirsiniz.<\/p>\n<p>Komutlar sonras\u0131nda <strong>\/coverage_report\/index.html<\/strong> ile kodunuzun ne kadar\u0131n\u0131n testler ile kontrol edildi\u011fini g\u00f6r\u00fcnt\u00fcleyebilirsiniz. Benim \u00e7a\u011f\u0131rd\u0131\u011f\u0131m ko\u015fum i\u00e7in g\u00f6r\u00fcnt\u00fc a\u015fa\u011f\u0131daki gibi:<\/p>\n<p id=\"eEteqns\"><img loading=\"lazy\" decoding=\"async\" width=\"1267\" height=\"328\" class=\"size-full wp-image-3062 aligncenter\" src=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9.png\" alt=\"\" srcset=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9.png 1267w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-300x78.png 300w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-1024x265.png 1024w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-768x199.png 768w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-500x129.png 500w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-150x39.png 150w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-1200x311.png 1200w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-400x104.png 400w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-800x207.png 800w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9-200x52.png 200w\" sizes=\"auto, (max-width: 1267px) 100vw, 1267px\" \/><\/p>\n<p>Yukar\u0131dakine benzer \u015fekilde <strong>gcovr<\/strong> ile de raporlama almak i\u00e7in a\u015fa\u011f\u0131daki komutlar\u0131 kullanabilirsiniz:<\/p>\n<pre class=\"lang:sh decode:true \">mkdir gcovr_report\r\ngcovr -r .. --html --html-details -o gcovr_report\/coverage.html<\/pre>\n<p>Umar\u0131m birim testler, bunlar\u0131n kullan\u0131m\u0131 ve neye hizmet etti\u011fi konusuna y\u00f6nelik kafan\u0131zda bir soru i\u015fareti kalmam\u0131\u015ft\u0131r.<\/p>\n<p>G\u00fcncel repoya a\u015fa\u011f\u0131daki adresten ula\u015fabilirsiniz.<\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/github.com\/yazilimperver\/cpp-playground\">https:\/\/github.com\/yazilimperver\/cpp-playground<\/a><\/strong><\/span><\/p>\n<p>Bir sonraki yaz\u0131mda, birim testleri de ko\u015fturduktan sonra yine yaz\u0131l\u0131m geli\u015ftirmenin \u00f6nemli bir par\u00e7as\u0131 olan ve daha \u00f6nce bir \u00e7ok yaz\u0131mda da bahsetti\u011fim CI\/CD ad\u0131mlar\u0131na g\u00f6z at\u0131yor olaca\u011f\u0131z. O yaz\u0131ma kadar kendinize iyi bak\u0131n, serin kal\u0131n \ud83d\ude42<\/p>\n<h2><span style=\"color: #0000ff;\"><strong>Kaynaklar<\/strong><\/span><\/h2>\n<ul>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/wiki.cs.jmu.edu\/student\/gcov\/start\">https:\/\/wiki.cs.jmu.edu\/student\/gcov\/start<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/medium.com\/@xianpeng.shen\/use-gcov-and-lcov-to-perform-code-coverage-testing-for-c-c-projects-c85708b91c78\">https:\/\/medium.com\/@xianpeng.shen\/use-gcov-and-lcov-to-perform-code-coverage-testing-for-c-c-projects-c85708b91c78<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/gcovr.com\/en\/stable\/index.html\">https:\/\/gcovr.com\/en\/stable\/index.html<\/a><\/strong><\/span><\/li>\n<li><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/github.com\/OpenCppCoverage\/OpenCppCoverage\">https:\/\/github.com\/OpenCppCoverage\/OpenCppCoverage<\/a><\/strong><\/span><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Evet, sevgili yaz\u0131l\u0131mperver dostlar\u0131m son yaz\u0131lar\u0131mla birlikte art\u0131k SDL3 uygulamalar\u0131n\u0131z\u0131 olu\u015fturmaya ba\u015flad\u0131\u011f\u0131n\u0131z\u0131 d\u00fc\u015f\u00fcn\u00fcyorum. Bu yaz\u0131lar ile birlikte, SDL3 giri\u015f yapm\u0131\u015f ve yaz\u0131l\u0131m tasar\u0131m \u00f6r\u00fcnt\u00fclerini de kulland\u0131\u011f\u0131m\u0131z temel bir \u00f6rnek olu\u015fturmu\u015ftuk. [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar &#8211; I [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar \u2013 II Bu yaz\u0131m\u0131zda ise, yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinin \u00f6nemli bir par\u00e7as\u0131 olan birim testlere e\u011filerek,&#8230; <a class=\"more-link\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\">Continue reading <span class=\"meta-nav\">&#8594;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[10,41,25],"tags":[1182,1184,1181,1183,42,1155,1185,838],"class_list":["post-3060","post","type-post","status-publish","format-standard","hentry","category-c","category-modern-c","category-oyun-gelistirme","tag-gcov","tag-gcovr","tag-gtest","tag-lcov","tag-modern-c","tag-sdl3","tag-unit-test-coverage","tag-unit-tests"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"og:description\" content=\"Evet, sevgili yaz\u0131l\u0131mperver dostlar\u0131m son yaz\u0131lar\u0131mla birlikte art\u0131k SDL3 uygulamalar\u0131n\u0131z\u0131 olu\u015fturmaya ba\u015flad\u0131\u011f\u0131n\u0131z\u0131 d\u00fc\u015f\u00fcn\u00fcyorum. Bu yaz\u0131lar ile birlikte, SDL3 giri\u015f yapm\u0131\u015f ve yaz\u0131l\u0131m tasar\u0131m \u00f6r\u00fcnt\u00fclerini de kulland\u0131\u011f\u0131m\u0131z temel bir \u00f6rnek olu\u015fturmu\u015ftuk. [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar &#8211; I [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar \u2013 II Bu yaz\u0131m\u0131zda ise, yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinin \u00f6nemli bir par\u00e7as\u0131 olan birim testlere e\u011filerek,... Continue reading &#8594;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\" \/>\n<meta property=\"og:site_name\" content=\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-13T14:48:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9.png\" \/>\n<meta name=\"author\" content=\"yaz\u0131l\u0131mperver\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"yaz\u0131l\u0131mperver\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\"},\"author\":{\"name\":\"yaz\u0131l\u0131mperver\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"headline\":\"[ARA\u00c7] SDL3 Birim Testler\",\"datePublished\":\"2025-07-13T14:48:22+00:00\",\"dateModified\":\"2025-07-13T14:48:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\"},\"wordCount\":1509,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"keywords\":[\"gcov\",\"gcovr\",\"gtest\",\"lcov\",\"Modern C++\",\"SDL3\",\"unit test coverage\",\"unit tests\"],\"articleSection\":[\"C++\",\"Modern C++\",\"Oyun Geli\u015ftirme\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\",\"url\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\",\"name\":\"[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#website\"},\"datePublished\":\"2025-07-13T14:48:22+00:00\",\"dateModified\":\"2025-07-13T14:48:22+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Ana sayfa\",\"item\":\"https:\/\/www.yazilimperver.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"[ARA\u00c7] SDL3 Birim Testler\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.yazilimperver.com\/#website\",\"url\":\"https:\/\/www.yazilimperver.com\/\",\"name\":\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"description\":\"Payla\u015fmak g\u00fczeldir.\",\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.yazilimperver.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\",\"name\":\"yaz\u0131l\u0131mperver\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png\",\"contentUrl\":\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png\",\"caption\":\"yaz\u0131l\u0131mperver\"},\"logo\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/","og_locale":"tr_TR","og_type":"article","og_title":"[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","og_description":"Evet, sevgili yaz\u0131l\u0131mperver dostlar\u0131m son yaz\u0131lar\u0131mla birlikte art\u0131k SDL3 uygulamalar\u0131n\u0131z\u0131 olu\u015fturmaya ba\u015flad\u0131\u011f\u0131n\u0131z\u0131 d\u00fc\u015f\u00fcn\u00fcyorum. Bu yaz\u0131lar ile birlikte, SDL3 giri\u015f yapm\u0131\u015f ve yaz\u0131l\u0131m tasar\u0131m \u00f6r\u00fcnt\u00fclerini de kulland\u0131\u011f\u0131m\u0131z temel bir \u00f6rnek olu\u015fturmu\u015ftuk. [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar &#8211; I [ARA\u00c7] SDL3 \u0130lk Ad\u0131mlar \u2013 II Bu yaz\u0131m\u0131zda ise, yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinin \u00f6nemli bir par\u00e7as\u0131 olan birim testlere e\u011filerek,... Continue reading &#8594;","og_url":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/","og_site_name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","article_published_time":"2025-07-13T14:48:22+00:00","og_image":[{"url":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2025\/07\/img_6873c5b3be2e9.png"}],"author":"yaz\u0131l\u0131mperver","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"yaz\u0131l\u0131mperver","Tahmini okuma s\u00fcresi":"7 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#article","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/"},"author":{"name":"yaz\u0131l\u0131mperver","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"headline":"[ARA\u00c7] SDL3 Birim Testler","datePublished":"2025-07-13T14:48:22+00:00","dateModified":"2025-07-13T14:48:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/"},"wordCount":1509,"commentCount":1,"publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"keywords":["gcov","gcovr","gtest","lcov","Modern C++","SDL3","unit test coverage","unit tests"],"articleSection":["C++","Modern C++","Oyun Geli\u015ftirme"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/","url":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/","name":"[ARA\u00c7] SDL3 Birim Testler - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/#website"},"datePublished":"2025-07-13T14:48:22+00:00","dateModified":"2025-07-13T14:48:22+00:00","breadcrumb":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.yazilimperver.com\/index.php\/2025\/07\/13\/arac-sdl3-birim-testler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Ana sayfa","item":"https:\/\/www.yazilimperver.com\/"},{"@type":"ListItem","position":2,"name":"[ARA\u00c7] SDL3 Birim Testler"}]},{"@type":"WebSite","@id":"https:\/\/www.yazilimperver.com\/#website","url":"https:\/\/www.yazilimperver.com\/","name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","description":"Payla\u015fmak g\u00fczeldir.","publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.yazilimperver.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb","name":"yaz\u0131l\u0131mperver","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/","url":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png","contentUrl":"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2018\/04\/OnlyIcon-1-114x114.png","caption":"yaz\u0131l\u0131mperver"},"logo":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3060","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/comments?post=3060"}],"version-history":[{"count":4,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3060\/revisions"}],"predecessor-version":[{"id":3066,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3060\/revisions\/3066"}],"wp:attachment":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/media?parent=3060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/categories?post=3060"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/tags?post=3060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}