{"id":2047,"date":"2021-01-25T20:43:03","date_gmt":"2021-01-25T20:43:03","guid":{"rendered":"https:\/\/www.yazilimperver.com\/?p=2047"},"modified":"2021-11-03T21:31:57","modified_gmt":"2021-11-03T21:31:57","slug":"uygulama-izleme-yazilimi-serisi-3-birim-test","status":"publish","type":"post","link":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/","title":{"rendered":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon"},"content":{"rendered":"<p>Evet dostlar, uygulama yaz\u0131m\u0131za devam ediyoruz. Yaz\u0131 dizisinin di\u011fer yaz\u0131lar\u0131na eri\u015fmek i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131lar\u0131 kullanabilirsiniz:<\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2020\/12\/16\/uygulama-izleme-yazilimi\/\">Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131<\/a><\/strong><\/span><\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/03\/uygulama-izleme-yazilimi-2-baslangic\/\">Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 2 &#8211; Ba\u015flang\u0131\u00e7<\/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: #339966;\"><strong><a style=\"color: #339966;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/03\/20\/amt-4-qt-ayarlamalari\/\"><span style=\"color: #008000;\">Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 4 &#8211; Qt Ayarlamalar\u0131<\/span><\/a><\/strong><\/span><\/p>\n<p><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/11\/03\/uygulama-izleme-yazilimi-5-amt-v1-0\/\">Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 5 &#8211; AMT v1.0<\/a><\/strong><\/span><\/p>\n<p>\u00d6ncelikle bu yaz\u0131m\u0131zda nelere de\u011finece\u011fiz, k\u0131saca onlara bir g\u00f6z atal\u0131m:<\/p>\n<ul>\n<li>Utility k\u00fct\u00fcphanesi,<\/li>\n<li>Birim testler (google test) ve s\u00fcrekli entegrasyon<\/li>\n<li>CMake&#8217;e ili\u015fkin eklediklerimiz.<\/li>\n<\/ul>\n<h2><strong><span style=\"color: #0000ff;\">Utility K\u00fct\u00fcphanesi<\/span><\/strong><\/h2>\n<p>Bu k\u00fct\u00fcphane, QT&#8217;ye ba\u011f\u0131ml\u0131 olmayan, fakat uygulama ve k\u00fct\u00fcphaneler i\u00e7erisinde kullan\u0131lacak bir tak\u0131m genel kabiliyetleri bar\u0131nd\u0131ryor olacak. \u015eimdilik a\u015fa\u011f\u0131daki s\u0131n\u0131flar\u0131 i\u00e7ermektedir. \u0130lerleyen d\u00f6nem i\u00e7erisinde bunlar\u0131n says\u0131 artabilir.<\/p>\n<ul>\n<li><strong>ParameterSet:<\/strong> Bu s\u0131n\u0131f\u0131 genel olarak, &#8220;\u00f6zellik&#8221; anlam\u0131nda tutulabilecek her t\u00fcrl\u00fc\/metin de\u011fer e\u015fleni\u011fi listelerini tutmak i\u00e7in kullan\u0131yor olaca\u011f\u0131z. Burada daha \u00f6nce sizler ile de payla\u015ft\u0131\u011f\u0131m <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/08\/14\/haftalik-c-18-stdany\/\">std::any kabiliyetini<\/a><\/strong><\/span> kullan\u0131yoruz.<\/li>\n<li><strong>PropertyItem:<\/strong> Temelde bir \u00f6nceki kabiliyete benziyor fakat tekli kullan\u0131mlar i\u00e7in bir veri yap\u0131s\u0131.<\/li>\n<li><strong>Timestamp:<\/strong> Bu da yine, daha \u00f6nce bir yaz\u0131mda i\u015fledi\u011fim, <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2020\/11\/09\/haftalik-c-33-zaman-bilgisi-etiketi\/\">zaman etiketleri<\/a><\/strong><\/span> ve benzeri kabiliyetler i\u00e7in kullan\u0131lacakt\u0131r.<\/li>\n<li><strong>UniqueIDGenerator:<\/strong> Basit bir e\u015fsiz tan\u0131mlay\u0131c\u0131 \u00fcretmek i\u00e7in kullan\u0131lacak bir s\u0131n\u0131f. Burada da, <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2019\/03\/30\/haftalik-c-12-multithread-programlamada-karsilasilan-bazi-sikintilar\/\">std::atomic<\/a><\/strong><\/span> kabiliyetini kullan\u0131yoruz. Bu kabiliyete de de\u011finmi\u015ftik.<\/li>\n<\/ul>\n<p>Bu arada kodlara bakt\u0131\u011f\u0131n\u0131zda, sizlerin de fark edece\u011fi \u00fczere kod yorumlar\u0131 i\u00e7in doxygen tabanl\u0131 bir yakla\u015f\u0131m izledim. Bunun i\u00e7in de atomineer eklentisini kulland\u0131m.<\/p>\n<p>Bu k\u00fct\u00fcphaneyi statik bir k\u00fct\u00fcphane olarak kullanaca\u011f\u0131z. Bu ba\u011flamda CMake i\u00e7erisinde, <em>add_library<\/em> komutunu, <em>STATIC<\/em> ayar\u0131 ile tan\u0131ml\u0131yoruz. Ayr\u0131ca benzer \u015fekilde, bu k\u00fct\u00fcphaneye ili\u015fkin ba\u015fl\u0131k dosyalar\u0131n\u0131 kullanabilmek i\u00e7in de\u00a0<em>target_include_directories<\/em> komutunu kullan\u0131yoruz.<\/p>\n<p>Bir sonraki yaz\u0131lar\u0131m\u0131zda, QT k\u00fct\u00fcphaneleri i\u00e7in ne yapt\u0131\u011f\u0131m\u0131za bakaca\u011f\u0131z.<\/p>\n<h2><span style=\"color: #0000ff;\"><strong>Birim Testler<\/strong><\/span><\/h2>\n<p>Bu uygulama i\u00e7erisinde sizler ile payla\u015faca\u011f\u0131m bir di\u011fer kabiliyet de, birim testler. Birim testlerin temel amac\u0131, ilgili kod par\u00e7alar\u0131n\u0131n do\u011fru \u00e7al\u0131\u015f\u0131p\/\u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131n kontrol edilmesi olarak \u00f6zetlenebilir. Bu noktada tabi, birim olarak neyi referans al\u0131naca\u011f\u0131 akl\u0131n\u0131za gelebilir. Bu genelde, uygulaman\u0131n test edilebilecek olan en k\u00fc\u00e7\u00fck par\u00e7as\u0131 olarak de\u011ferlendirilmektedir. C++ ba\u011flam\u0131nda genelde &#8220;public&#8221; s\u0131n\u0131f fonksiyonlar\u0131 referans al\u0131nmaktad\u0131r. Birim testler ile bu par\u00e7alar\u0131n birbirlerinden izole edilerek, tek tek do\u011fru \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131n g\u00f6sterilmesi ama\u00e7lanmaktad\u0131r. Burada son bir \u00f6nemli noktada da, bu testlerin h\u0131zl\u0131 bir \u015fekilde ko\u015fturulabilip, yap\u0131lan de\u011fi\u015fikliklerden yaz\u0131l\u0131m\u0131n etkilenmedi\u011fini g\u00f6stermektir.<\/p>\n<p>Elbette birim teslerin bir \u00e7ok faydas\u0131 var. A\u015fa\u011f\u0131da bunlar\u0131 k\u0131saca s\u0131ralamaya \u00e7al\u0131\u015ft\u0131m:<\/p>\n<ul>\n<li>Kodun mod\u00fclarize 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 bulunur<\/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,<\/li>\n<li>Yaz\u0131l\u0131m test edilmesi i\u00e7in, bitmesi beklenmez,<\/li>\n<li>Zaman kazand\u0131r\u0131r ve maliyeti d\u00fc\u015f\u00fcr\u00fcr.<\/li>\n<\/ul>\n<p>Birim testler genel olarak \u00fc\u00e7 faza ayr\u0131l\u0131r ve orjinal isimleri ile<strong> &#8220;Arrange, Act, Assert&#8221;<\/strong> olarak ifade edilir. Bu a\u015famalar a\u015fa\u011f\u0131daki gibi g\u00f6sterilebilir:<\/p>\n<pre class=\"lang:c++ decode:true \">Test (TestGrup\u0130smi, Test\u0130smi) \r\n{\r\n     1 - Haz\u0131rl\u0131k (Arrange\/Setup)\r\n     2 - Testi Ger\u00e7ekle\u015ftir (Act\/Run Test)\r\n     3 - Sonu\u00e7lar\u0131 Kontrol Et(Assert)\r\n}<\/pre>\n<p>birim testlerinin a\u00e7\u0131k ve spesifik, ge\u00e7me\/kalma ko\u015fullar\u0131 vard\u0131r. Burada birim testleri yazarken dikkat etmek gereken bir ka\u00e7 husustan da bahsetmek istiyorum. Bunlar:<\/p>\n<ul>\n<li>\u0130lgili s\u0131n\u0131f\u0131n b\u00fct\u00fcn <em>public\u00a0<\/em>fonksiyon, yap\u0131c\u0131 ve operat\u00f6rlerini test etmelisiniz,<\/li>\n<li>A\u00e7\u0131k olan ko\u015fullar yan\u0131nda, di\u011fer ko\u015fullar, hatal\u0131 girdiler ve u\u00e7 ko\u015fullar\u0131 da test etmelisiniz,<\/li>\n<li>Her bir test bir birinden ba\u011f\u0131ms\u0131z ve di\u011ferlerinin ko\u015fumunu etkilemiyor olmal\u0131,<\/li>\n<li>Testlerin ko\u015fum s\u0131ras\u0131, sonucu etkilemiyor olmal\u0131d\u0131r.<\/li>\n<\/ul>\n<p>Birim testlerin yan\u0131nda ayr\u0131ca &#8220;mocking&#8221; kabiliyetinden de s\u0131k s\u0131k bahsedilir ve kullan\u0131l\u0131r. Bu da, test etmek oldu\u011funuz kabiliyetin di\u011fer birimler ile olan etkile\u015fimlerini kontrol etmek i\u00e7in sizlere yard\u0131mc\u0131 ara\u00e7lar sunar. Bu konuya, ilerleyen yaz\u0131lar\u0131mda \u00f6rnekler ile de\u011finece\u011fim.<\/p>\n<p>Birim testler i\u00e7in kullan\u0131labilecek bir \u00e7ok k\u00fct\u00fcphane mevcut. Bu yaz\u0131l\u0131mda biz, google test&#8217;i kullanaca\u011f\u0131z. Google test ile ilgili \u00e7ok g\u00fczel kaynaklar var. \u00d6zellikle ho\u015fuma gidenleri kaynaklar k\u0131sm\u0131na ekliyorum, burada temel bir tak\u0131m \u00f6zelliklerini sizler ile payla\u015faca\u011f\u0131m, daha detayl\u0131 bilgi i\u00e7in kaynaklara g\u00f6z atabilirsiniz.<\/p>\n<h3><span style=\"color: #0000ff;\"><strong>Google Test\u00a0<\/strong><\/span><\/h3>\n<p>Google Test ve Google Mock, google taraf\u0131ndan geli\u015ftirilen ve bir \u00e7ok kullan\u0131c\u0131s\u0131 bulunan test k\u00fct\u00fcphanelerinden biri. Bir \u00e7ok platformu desteklemesi yan\u0131nda, \u00e7e\u015fitli durdurucu (fatal) ve durdurucu olmayan (non-fatal) \u00f6nerme kontrolleri, test &#8220;fixture&#8221;&#8216;lar\u0131, gruplamalar\u0131, bilgilendirici mesajlar\u0131, xml tabanl\u0131 raporlama ve bir \u00e7ok kabiliyeti bar\u0131nd\u0131rmaktad\u0131r.<\/p>\n<p>Di\u011fer bir tak\u0131m k\u00fct\u00fcphanelerden farkl\u0131 olarak, ne yaz\u0131k ki, k\u00fct\u00fcphane \u015feklinde kullan\u0131lmakta. Bir di\u011fer ifade ile kullanaca\u011f\u0131n\u0131z platform i\u00e7in, google test ve mock&#8217;u olu\u015fturman\u0131z gerekiyor. Neyse ki, sizlere sundu\u011fum kodta (ve bir \u00f6nceki yaz\u0131mda) bunu nas\u0131l yapabilece\u011finizi sizlere aktarm\u0131\u015ft\u0131m. \u015eimdi, h\u0131zl\u0131ca google testin \u00f6zelliklerin \u00fczerinden ge\u00e7elim.<\/p>\n<p>Google test i\u00e7erisinde, kod par\u00e7alar\u0131n\u0131z\u0131n do\u011frulu\u011funu test etmek i\u00e7in kulland\u0131\u011f\u0131n\u0131z ifadeler, \u00f6nerme olarak &#8220;assertion&#8221; adland\u0131r\u0131lmaktad\u0131r. Bunlardan durdurucu (&#8220;fatal&#8221;) olanlar, <strong>ASSERT_ <\/strong>\u00f6n eki ile ba\u015flarken, durdurucu olmayanlar (&#8220;non-fatal&#8221;) ise, <strong>EXPECT_\u00a0<\/strong>\u00f6n eki ile ba\u015flamaktad\u0131r. Bu ikisi aras\u0131ndan en \u00f6nemli fark, durdurucu \u00f6nermelerdeki ko\u015fullar sa\u011flanamaz ise test orada biter ve sonraki \u00f6nermelere bak\u0131lmaz. Di\u011ferinde ise, di\u011fer \u00f6nermelere de bak\u0131l\u0131r.\u00a0 Testleri tan\u0131mlamak i\u00e7in ise <strong>TEST,\u00a0<\/strong>makrosunu kullan\u0131yoruz. Hemen bir \u00f6rnek inceleyelim:<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/ kare almak testleri \r\nTEST (SquareTesti \/*test grup ismi *\/, PozitifVeSifirSayilari \/* test ismi*\/) \r\n{ \r\n\tEXPECT_EQ (9.0, (3.0*2.0));  \/\/ hata ama teste devam \r\n\tASSERT_EQ (0.0, (0.0));      \/\/ ba\u015far\u0131l\u0131 \r\n\tASSERT_EQ (9, (3)*(-3.0));   \/\/ hata, test burada biter \r\n\tASSERT_EQ (-9, (-3)*(-3.0)); \/\/ bir \u00f6nceki satirdan \u00f6t\u00fcr\u00fc ko\u015fturulmaz \r\n}<\/pre>\n<p>Google test ile gelen \u00f6nerme kontrollerinden bir k\u0131sm\u0131n\u0131 a\u015fa\u011f\u0131ya ekliyorum. Daha detayl\u0131 \u00f6nermeler i\u00e7in <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md\">https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md<\/a><\/strong><\/span>&#8216;a g\u00f6z atabilirsiniz. Burada, durdurucu olmayan \u00f6nermelere ili\u015fkin komutlar mevcut, EXPECT yerine ASSERT kullanarak durdurucu olanlar\u0131 kullanabilirsiniz:<\/p>\n<table width=\"0\">\n<tbody>\n<tr>\n<td width=\"30%\"><strong>Mant\u0131ksal \u00d6nermeler<\/strong><\/td>\n<td>EXPECT_TRUE(condition)<br \/>\nEXPECT_FALSE(condition)<\/td>\n<\/tr>\n<tr>\n<td><strong>Genel Kar\u015f\u0131la\u015ft\u0131rmalar<\/strong><\/td>\n<td>EXPECT_EQ(expected, actual) \/ EXPECT_NE(val1, val2)<br \/>\nEXPECT_LT(val1, val2) \/ EXPECT_LE(val1, val2)<br \/>\nEXPECT_GT(val1, val2) \/ EXPECT_GE(val1, val2)<\/td>\n<\/tr>\n<tr>\n<td><strong>Kayan Noktal\u0131 Say\u0131lar<\/strong><\/td>\n<td>EXPECT_FLOAT_EQ(expected, actual)<br \/>\nEXPECT_DOUBLE_EQ(expected, actual)<br \/>\nEXPECT_NEAR(val1, val2, abs_error)<\/td>\n<\/tr>\n<tr>\n<td><strong>Metin Kar\u015f\u0131la\u015ft\u0131rma<\/strong><\/td>\n<td>EXPECT_STREQ(expected_str, actual_str) \/ EXPECT_STRNE(str1, str2)<br \/>\nEXPECT_STRCASEEQ(expected_str, actual_str) \/ EXPECT_STRCASENE(str1, str2)<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0130stisna Kontrolleri<\/strong><\/td>\n<td>EXPECT_THROW(statement, exception_type)<br \/>\nEXPECT_ANY_THROW(statement)<br \/>\nEXPECT_NO_THROW(statement)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Bir s\u00fcre test yazd\u0131ktan sonra, testlerde bir \u00e7ok veriyi kullanma ve ortak i\u015flevleri bir araya getirme ihtiyac\u0131n\u0131z olabilir. \u0130\u015fte &#8220;test fixture&#8221;&#8216;lar\u0131 tam olarak bu noktada imdad\u0131n\u0131za yeti\u015fiyor. Asl\u0131nda bakarsan\u0131z, yukar\u0131da verdi\u011fim google test sayfas\u0131nda da, e\u011fer birden fazla test i\u00e7in veri haz\u0131rl\u0131yor durumda kendinizi bulursan\u0131z. Test &#8220;fixture&#8221;&#8216;lar\u0131n\u0131 kullanmal\u0131s\u0131n\u0131z diye \u00f6neriyor \ud83d\ude42 Hemen bir \u00f6rnek ile inceleyelim:<\/p>\n<pre class=\"lang:c++ decode:true\">class myTestFixture: \r\n  public ::testing::test {\r\n    public:\r\n    void SetUp( ) {\r\n         \/\/ Her test \u00f6ncesinde yap\u0131lacak olan ilklendirmeler\r\n    }\r\n\r\n    void TearDown( ) {\r\n         \/\/ Her test tamamland\u0131ktan sonra gerceklestirilecek islevler\r\n     }\r\n\r\n     \/\/ Di\u011fer fonksiyon ve veri yap\u0131lar\u0131\r\n};<\/pre>\n<p>\u00d6ncelikli olarak, ::testing::test s\u0131n\u0131f\u0131ndan bir s\u0131n\u0131f t\u00fcretiyorsunuz ve fonksiyon kapsam tan\u0131mlay\u0131c\u0131s\u0131n\u0131n en k\u00f6t\u00fc &#8220;protected&#8221; oldu\u011fundan emin oluyoruz. Her testin ba\u015f\u0131nda yap\u0131lmas\u0131n\u0131 istedi\u011finiz i\u015flevleri SetUp() i\u00e7erisinde, test sonras\u0131nda yap\u0131lmas\u0131n\u0131 istedi\u011finiz i\u015flevleri de TearDown() i\u00e7erisine ekliyorsunuz. Bunlara ihtiyac\u0131n\u0131z yok ise eklemeyebilirsiniz. Bunlar d\u0131\u015f\u0131nda da, kendi ihtiya\u00e7lar\u0131n\u0131z do\u011frultusunda bir \u00e7ok fonksiyon ya da \u00fcye veri yap\u0131s\u0131 ekleyebilirsiniz. \u015eimdi de, google testin, bir kuyruk veri yap\u0131s\u0131 i\u00e7in verdi\u011fi \u00f6rne\u011fe g\u00f6z atal\u0131m. \u00d6nce veri yap\u0131s\u0131 s\u0131n\u0131f\u0131na, daha sonra da ilgili fixture s\u0131n\u0131f\u0131 a\u015fa\u011f\u0131daki gibi:<\/p>\n<pre class=\"lang:c++ decode:true \">template &lt;typename E&gt;  \/\/ E is the element type.\r\nclass Queue {\r\n public:\r\n  Queue();\r\n  void Enqueue(const E&amp; element);\r\n  E* Dequeue();  \/\/ Returns NULL if the queue is empty.\r\n  size_t size() const;\r\n  ...\r\n};\r\n\r\nclass QueueTest : public ::testing::Test {\r\n protected:\r\n  void SetUp() override {\r\n     q1_.Enqueue(1);\r\n     q2_.Enqueue(2);\r\n     q2_.Enqueue(3);\r\n  }\r\n\r\n  \/\/ void TearDown() override {}\r\n\r\n  Queue&lt;int&gt; q0_;\r\n  Queue&lt;int&gt; q1_;\r\n  Queue&lt;int&gt; q2_;\r\n};<\/pre>\n<p>Bu &#8220;fixture&#8221;&#8216;lar\u0131 kullanarak test yazmak i\u00e7in ise <strong>TEST_F<\/strong> makrosunu kullan\u0131yoruz ve ilk parametrenin yukar\u0131daki s\u0131n\u0131f olarak verildi\u011finden emin oluyoruz:<\/p>\n<pre class=\"lang:c++ decode:true\">TEST_F(QueueTest, IsEmptyInitially) {\r\n  EXPECT_EQ(q0_.size(), 0);\r\n}\r\n\r\nTEST_F(QueueTest, DequeueWorks) {\r\n  int* n = q0_.Dequeue();\r\n  EXPECT_EQ(n, nullptr);\r\n\r\n  n = q1_.Dequeue();\r\n  ASSERT_NE(n, nullptr);\r\n  EXPECT_EQ(*n, 1);\r\n  EXPECT_EQ(q1_.size(), 0);\r\n  delete n;\r\n\r\n  n = q2_.Dequeue();\r\n  ASSERT_NE(n, nullptr);\r\n  EXPECT_EQ(*n, 2);\r\n  EXPECT_EQ(q2_.size(), 1);\r\n  delete n;\r\n}<\/pre>\n<p>Burada unutmaman\u0131z gereken \u015fey, hem <em>IsEmptyInitially\u00a0<\/em>hem de\u00a0<em>DequeueWorks\u00a0<\/em>i\u00e7in ayr\u0131 QueueTest nesneleri olu\u015fturulmaktad\u0131r. Detaylar i\u00e7in<a href=\"https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md\"><strong><span style=\"color: #008000;\"> https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md<\/span><\/strong><\/a>&#8216;a g\u00f6z atabilirsiniz<\/p>\n<p>Uygulama izleme yaz\u0131l\u0131m\u0131 i\u00e7in google test&#8217;i, ext dizini i\u00e7erisinde projemize dahil ediyoruz ve CMake yard\u0131m\u0131 ile hedef platforma g\u00f6re olu\u015fturuyoruz.<\/p>\n<p>Mevcut, proje dizini i\u00e7erisinde, Utility k\u00fct\u00fcphanesine ili\u015fkin google test ile yaz\u0131l\u0131m\u0131\u015f birim testleri g\u00f6rebilirsiniz. Bu da size, bu testleri nas\u0131l kullan\u0131labilece\u011fine ili\u015fkin birinci elden bir \u00f6rnek te\u015fkil edece\u011fini umuyorum. Zamanla di\u011fer ekledi\u011fim s\u0131n\u0131flara dair testleri de ekliyor olaca\u011f\u0131m. Hatta QT kod par\u00e7alar\u0131 i\u00e7in QTest&#8217;e de h\u0131zl\u0131ca bakaca\u011f\u0131z.<\/p>\n<p>\u015eimdilik google test olay\u0131n\u0131 burada b\u0131rak\u0131yoruz. Sonraki yaz\u0131 serisinde ya da ba\u011f\u0131ms\u0131z yaz\u0131lar\u0131mda, google test&#8217;e ili\u015fkin ip u\u00e7lar\u0131n\u0131 sizlerle payla\u015faca\u011f\u0131m.<\/p>\n<h3><span style=\"color: #0000ff;\"><strong>S\u00fcrekli Entegrasyon<\/strong><\/span><\/h3>\n<p>Gelelim bir di\u011fer \u00f6nemli ba\u015fl\u0131k olan s\u00fcrekli entegrasyona. Asl\u0131nda ba\u015fl\u0131 ba\u015f\u0131na bir yaz\u0131 olabilecek bir konuya burada h\u0131zl\u0131ca bir giri\u015f yap\u0131p, \u00f6n\u00fcm\u00fczdeki yaz\u0131larda bu konuya de\u011finmeye devam edece\u011fim. S\u00fcrekli entegrasyon amac\u0131 ile gitlab kullanaca\u011f\u0131m\u0131 bir \u00f6nceki yaz\u0131mda sizlere aktarm\u0131\u015ft\u0131m. Burada k\u0131saca s\u00fcrekli entegrasyon ve konu\u015fland\u0131rma konular\u0131n\u0131n arkas\u0131ndaki motivasyona g\u00f6z at\u0131yor olaca\u011f\u0131z.<\/p>\n<p>S\u00fcrekli entegrasyon kavram\u0131 ilk olarak Kent Back taraf\u0131ndan 90&#8217;l\u0131 y\u0131llarda kullan\u0131lm\u0131\u015ft\u0131r ve g\u00fcn\u00fcm\u00fczde art\u0131k bir \u00e7ok yaz\u0131l\u0131m firmas\u0131 ve projesinde kullan\u0131lan \u00f6nemli bir \u00e7evik yaz\u0131l\u0131m geli\u015ftirme pratiklerinden biri haline gelmi\u015ftir.<\/p>\n<p>Bu konuda olduk\u00e7a fazla makale yazm\u0131\u015f olan Martin Fowler&#8217;\u0131n, s\u00fcrekli entegrasyon i\u00e7in <strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html\">kulland\u0131\u011f\u0131 tan\u0131ma <\/a><\/span><\/strong>bir bakal\u0131m:<\/p>\n<blockquote><p>S\u00fcrekli entegrasyon, yaz\u0131l\u0131m tak\u0131m \u00fcyelerinin i\u015flerini s\u0131k bir \u015fekilde\u00a0 ana kod yap\u0131sna entegre etti\u011fi, genelde g\u00fcnde en az bir kere, bir yaz\u0131l\u0131m geli\u015ftirme prati\u011fidir. Her bir entegrasyon, test de i\u00e7eren otomatik bir olu\u015fturma i\u015flemi taraf\u0131ndan kontrol edilerek, bu entegrasyonun sebep oldu\u011fu hatalar varsa erken ortaya konulmas\u0131na yard\u0131mc\u0131 olur.<\/p><\/blockquote>\n<p>Bu makale, bu prati\u011fi uygulayan bir \u00e7ok yaz\u0131l\u0131mc\u0131 taraf\u0131ndan kabul g\u00f6rm\u00fc\u015f, s\u00fcrekli entegrasyona dair bir tak\u0131m aktivitelerden bahsedilmi\u015f. Nedir peki bu s\u00fcrekli entegrasyon aktiviteleri, k\u0131saca bunlara bir g\u00f6z atal\u0131m. Daha sonraki yaz\u0131larda bunlar\u0131n detaylar\u0131na bak\u0131yor olaca\u011f\u0131z:<\/p>\n<p><strong>1. Bir Tane Kod Kayna\u011f\u0131 Olmal\u0131<\/strong><br \/>\n<strong>2. Derleme ve Olu\u015fturma S\u00fcreci, Otomatize Edilmeli<\/strong><br \/>\n<strong>3. Derleme, Kendi Kendini Test Eder \u015eekilde Olmal\u0131<\/strong><br \/>\n<strong>4. Herkes Geli\u015ftirdi\u011fi Kodu, Her G\u00fcn Entegre Eder<\/strong><br \/>\n<strong>5. Yaz\u0131l\u0131m Geli\u015ftiriciler Taraf\u0131ndan G\u00f6nderilen Her Kod, Entegrasyon Makinesi \u00dczerinde Derlenmelidir<\/strong><br \/>\n<strong>6. Hatal\u0131 Oluturmalar\/Derlemeler Hemen D\u00fczeltilmelidir<\/strong><br \/>\n<strong>7. Olu\u015fturma H\u0131zl\u0131 Olmal\u0131d\u0131r<\/strong><br \/>\n<strong>8. Testler, \u00dcretim Ortam\u0131na Benzer Bir Ortamda Yap\u0131lmal\u0131d\u0131r<\/strong><br \/>\n<strong>9. En Son \u00c7al\u0131\u015ft\u0131r\u0131labilir Kod, Herkes \u0130\u00e7in Kolay Ula\u015f\u0131labilir Olmal\u0131d\u0131r<\/strong><br \/>\n<strong>10. Herkes Olanlar\u0131 G\u00f6rebiliyor Olmal\u0131<\/strong><br \/>\n<strong>11. Konu\u015flanma Otomatikle\u015ftirilmelidir<\/strong><\/p>\n<p>Yukar\u0131daki kalemler, sizlere s\u00fcrekli entegrasyonun temelde neyi ba\u015farmay\u0131 hedefledi\u011fini ve ne yap\u0131l\u0131rsa bu pratikten daha fazla faydalan\u0131labilece\u011fini \u00e7ok g\u00fczel bir \u015fekilde \u00f6zetliyor. Bunlar\u0131n detaylar\u0131na <a href=\"https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html\"><span style=\"color: #008000;\"><strong>https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html<\/strong><\/span><\/a> adresinden ula\u015fabilirsiniz, fakat bu yaz\u0131 dizisi boyunca, bunlara da zaman zaman de\u011finece\u011fiz.<\/p>\n<p>Peki, bu a\u015famada biz ne yapt\u0131k? Hemen aktaray\u0131m.<img decoding=\"async\" src=\"https:\/\/about.gitlab.com\/images\/blogimages\/updatedcicd.png\" alt=\"Updated CI\/CD Pipeline\" \/><\/p>\n<p>Gitlab&#8217;\u0131n bizlere sundu\u011fu s\u00fcrekli entegrasyon kabiliyetlerini kullan\u0131yoruz. Bunun i\u00e7in de yapman\u0131z gereken tek \u015fey. Repository&#8217;niz i\u00e7erisinde, tepe dizinde, &#8220;.gitlab-ci.yml&#8221; dosyas\u0131 olu\u015fturmak ya da &#8220;CI\/CD Configuration&#8221; d\u00fc\u011fmesine t\u0131klamak:<\/p>\n<p id=\"GFBdBSN\"><img loading=\"lazy\" decoding=\"async\" width=\"1173\" height=\"210\" class=\"alignnone size-full wp-image-2079 \" src=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4.png\" alt=\"\" srcset=\"https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4.png 1173w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-300x54.png 300w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-1024x183.png 1024w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-768x137.png 768w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-500x90.png 500w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-150x27.png 150w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-400x72.png 400w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-800x143.png 800w, https:\/\/www.yazilimperver.com\/wp-content\/uploads\/2021\/01\/img_600f1b3a6aaa4-200x36.png 200w\" sizes=\"auto, (max-width: 1173px) 100vw, 1173px\" \/><\/p>\n<p>Buna t\u0131klad\u0131\u011f\u0131n\u0131zda kar\u015f\u0131n\u0131za a\u015fa\u011f\u0131daki gibi bir betik geliyor olacak:<\/p>\n<pre class=\"lang:yaml decode:true\">image: rabits\/qt:5.14-desktop\r\n\r\nstages:\r\n    - build\r\n    \r\nbuildJob:\r\n    stage: build\r\n    script:\r\n        - echo \"Building Phase\"\r\n        - cd build\r\n        - cmake ..\r\n        - make\r\n        - ctest --verbose\r\n    artifacts:\r\n        when: always\r\n        paths:\r\n          - build\/\r\n          - binary\/\r\n<\/pre>\n<p>\u015eimdi buradaki anahtar kelimelere bir g\u00f6z atal\u0131m.<\/p>\n<p>Bu yaz\u0131da yine,\u00e7ok detaya girmeden sadece kulland\u0131klar\u0131ma bakaca\u011f\u0131z. \u0130leride bir yaz\u0131y\u0131 sadece bu konuya ay\u0131r\u0131rz. Ama \u015fimdiden daha derine inmek istiyorsan\u0131z <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/docs.gitlab.com\/ee\/ci\/quick_start\/\">https:\/\/docs.gitlab.com\/ee\/ci\/quick_start\/<\/a><\/strong><\/span> adresine bir g\u00f6z atabilirsiniz \ud83d\ude09<\/p>\n<p>Uygulama izleme yaz\u0131l\u0131m\u0131 i\u00e7in \u015fimdilik tek a\u015famadan olu\u015fan bir ak\u0131\u015f (&#8220;pipeline&#8221;) kullan\u0131yor olaca\u011f\u0131z. Ak\u0131\u015f asl\u0131nda, bizim s\u00fcrekli entegrasyon kapsam\u0131nda otomatikle\u015ftirmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z aktiviteleri, a\u015famalar\u0131 ve bu a\u015famalar kapsam\u0131nda ko\u015fturulan i\u015fleri (&#8220;Jobs&#8221;) kapsar. Her bir i\u015f i\u00e7in, betikler, \u00f6n ko\u015fullar ve ba\u011f\u0131ml\u0131l\u0131klar tan\u0131mlanabilir.\u00a0 Yukar\u0131da verilen betik ile asl\u0131nda basit bir ak\u0131\u015f\u0131 tan\u0131mlam\u0131\u015f olduk. Ne i\u00e7eriyor bu ak\u0131\u015f? \u015eimdilik sadece bir a\u015fama (&#8220;stages&#8221;) i\u00e7eriyor ve bu a\u015fama olu\u015fturma (&#8220;build&#8221;) a\u015famas\u0131d\u0131r. Bu a\u015fama i\u00e7erisinde yine tek bir i\u015f tan\u0131mlanm\u0131\u015f durumda, o da &#8220;buildJob&#8221; i\u015fidir.<\/p>\n<p>Tahmin edebilece\u011finiz \u00fczere, bu a\u015famalar\u0131n say\u0131s\u0131, uygulaman\u0131za, ihtiya\u00e7lar\u0131n\u0131za g\u00f6re de\u011fi\u015fiyor olacakt\u0131r ama en az\u0131ndan, olu\u015fturma\/test\/konu\u015fland\u0131rma a\u015famalar\u0131n\u0131 i\u00e7eriyor olabilir. Bizim ak\u0131\u015f\u0131m\u0131z da in\u015fallah yak\u0131nda bu a\u015famalara sahip olacak \ud83d\ude42 Bu a\u015famalar paralel olabilece\u011fi gibi genelde s\u0131ral\u0131 olarak da tasarlanabilmektedir.<\/p>\n<p id=\"hXQNqdZ\">Bizim \u00f6rne\u011fimizden devam edelim. &#8220;image&#8221; anahtar kelimesine bakal\u0131m. Bu asl\u0131nda, ilgili ak\u0131\u015f i\u00e7in hangi imaj&#8217;\u0131n referans al\u0131naca\u011f\u0131n\u0131 ifade ediyor. Burada se\u00e7ti\u011finiz asl\u0131nda Docker imaj\u0131n\u0131n ismi oluyor ve gitlab sizler i\u00e7in otomatik olarak bunu <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a><\/strong><\/span>&#8216;tan \u00e7ekiyor. Bizim \u00f6rne\u011fimizde, uygulamam\u0131zda, QT&#8217;yi kullanaca\u011f\u0131m\u0131z i\u00e7in, Qt kurulu bir imaj se\u00e7tim. Siz de ihtiya\u00e7lar\u0131n\u0131za g\u00f6re Docker Hub&#8217;tan bir imaj se\u00e7ebilirsiniz.<\/p>\n<p id=\"hmnSEwv\">Daha sonra, build a\u015famas\u0131 tan\u0131mlan\u0131yor ve bunun i\u00e7in de &#8220;buildJob&#8221; i\u015fi tan\u0131mlan\u0131yor. Bunun alt\u0131ndaki &#8220;stage:&#8221; anahtar kelimesi ile, bu i\u015fin hangi a\u015famaya ait oldu\u011funu belirtiyorsunuz.<\/p>\n<p>Daha sonra verilen &#8220;script:&#8221; anahtar kelimesi ile de ilgili i\u015fe ili\u015fkin b\u00fcy\u00fcn\u00fcn yap\u0131ld\u0131\u011f\u0131, betiklerin tan\u0131mland\u0131\u011f\u0131 sat\u0131rlar geliyor. Bu sat\u0131rlar ile, ilgili i\u015fin ne yapaca\u011f\u0131n\u0131 belirleyebiliyorsunuz. Burada basit\u00e7e \u00fc\u00e7\/d\u00f6rt ad\u0131m\u0131 i\u00e7eriyor:<\/p>\n<ul>\n<li>build dizini olu\u015ftur<\/li>\n<li>dizin i\u00e7erisine gir ve CMake ile gerekli olu\u015fturma dosyalar\u0131n\u0131 \u00fcret. Bizim durumumuzda, linux \u00fczerinde makefile<\/li>\n<li>daha sonra bu makefile dosyas\u0131n\u0131 ve make komutunu kullanarak, projeyi olu\u015ftur<\/li>\n<li>son olarak test&#8217;leri CMake alt yap\u0131s\u0131 ile ko\u015ftur.<\/li>\n<\/ul>\n<p>\u015eimdilik bu ad\u0131mlar\u0131n hepsi tek bir i\u015f i\u00e7erisinde ama kodumuz b\u00fcy\u00fcd\u00fck\u00e7e bunlar\u0131 birlikte farkl\u0131 i\u015flere ve a\u015famalara da\u011f\u0131t\u0131yor olaca\u011f\u0131z \ud83d\ude09<\/p>\n<p>Son olarak &#8220;artifacts:&#8221; anahtar kelimesi ile de, a\u015famalarda \u00fcretilen dosyalardan hangilerinin, ak\u0131\u015f tamamland\u0131ktan sonra silin<strong>memesini<\/strong> istedi\u011finizi belirtiyorsunuz. Bizim \u00f6rne\u011fimizde tek bir a\u015fama oldu\u011fu i\u00e7in bu pek anlaml\u0131 gelmeyebilir fakat \u00e7oklu a\u015famalar\u0131 i\u00e7eren ak\u0131\u015flarda, a\u015famalar aras\u0131 baz\u0131 verilerin aktar\u0131lmas\u0131n\u0131 istiyor olabiliriz. O noktada &#8220;artifact&#8221; i olduk\u00e7a s\u0131k kullan\u0131yor olaca\u011f\u0131z.<\/p>\n<p>Evet dostlar, bu yaz\u0131m\u0131n di\u011fer \u00f6nemli bir konusu olan s\u00fcrekli entegrasyona da dalm\u0131\u015f bulunduk. Yaz\u0131m\u0131 tamamlamadan \u00f6nce de\u011finece\u011fim bir ka\u00e7 konu daha var.<\/p>\n<h2><span style=\"color: #0000ff;\"><strong>CMake&#8217;e Dair Notlar<\/strong><\/span><\/h2>\n<p>Yaz\u0131m\u0131 tamamlamadan \u00f6nce CMake&#8217;e ili\u015fkin yapt\u0131\u011f\u0131m bir tak\u0131m eklemeleri sizler ile payla\u015fmak istiyorum. Bu yaz\u0131lar boyunca, CMake ile ilgili bir \u00e7ok kod par\u00e7as\u0131n\u0131 sizler ile payla\u015f\u0131yor olaca\u011f\u0131m:<\/p>\n<ul>\n<li>\u0130lk ekledi\u011fimiz komut, debug derlemeler sonucu elde edilen \u00e7\u0131kt\u0131lar\u0131n sonuna bir son ek eklenmesi. Bunun i\u00e7in a\u015fa\u011f\u0131daki komutu kullanabilirsiniz. Bunu en tepedeki CMakeLists.txt i\u00e7erisinde yapt\u0131\u011f\u0131m\u0131z i\u00e7in alt seviyedeki b\u00fct\u00fcn projeler bundan faydalan\u0131yor olacaklar:\n<ul>\n<li>&#8220;<code><span class=\"nb\">set<\/span><span class=\"p\">(<\/span>CMAKE_DEBUG_POSTFIX D<span class=\"p\">)\"<\/span><\/code><\/li>\n<\/ul>\n<\/li>\n<li>Diyelim ki, k\u00fct\u00fcphanelerinizin ve \u00e7al\u0131\u015ft\u0131r\u0131labilir dosyalar\u0131n\u0131z\u0131n belirli bir dizinde toplamak istiyorsunuz ki ben de genelde bu y\u00f6ntemi tercih ediyorum. Bunu peki nas\u0131l sa\u011flayabiliriz? Hemen bak\u0131yoruz:<\/li>\n<\/ul>\n<pre class=\"lang:js decode:true \">foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )\r\n    string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )\r\n    set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}\/lib )\r\n    set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}\/lib )\r\n    set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}\/binary )\r\nendforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )\r\n<\/pre>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\u015eimdi sizin kafan\u0131zda iki tane soru i\u015fareti var. Bir; dayak nedir? \u0130ki; neden at\u0131l\u0131r? Evet hatlar kar\u0131\u015ft\u0131 ama kafalarda bir tak\u0131m soru i\u015faretleri olu\u015fmu\u015f olabilir. Hemen a\u00e7\u0131klayal\u0131m. \u00d6ncelikle, &#8220;<strong>CMAKE_[ARCHIVE|LIBRARY|RUNTIME]_OUTPUT_DIRECTORY<\/strong>&#8221; de\u011fi\u015fkenlerinin az \u00e7ok ne i\u00e7in kullan\u0131ld\u0131\u011f\u0131n\u0131 anlam\u0131\u015fs\u0131n\u0131zd\u0131r. Peki &#8220;foreach&#8221; i ne i\u00e7in kullan\u0131yoruz. \u015eunu i\u00e7in: \u00f6zellik Visual Studio ve benzeri ara\u00e7lar i\u00e7erisinde sadece Debug ve Release de\u011fil, ba\u015fka bir tak\u0131m konfig\u00fcrasyon tipleri de tan\u0131mlanmakta. Buradaki d\u00f6ng\u00fc ile bu dizinleri, her biri i\u00e7in ayn\u0131 olacak \u015fekilde ayarlayabiliyoruz. Elbette, bunlar\u0131n ayr\u0131 olmas\u0131n\u0131 istiyorsan\u0131z ya da \u00f6zel bir dizin, \u015fu \u015fekilde tan\u0131mlamalar yapabilirsiniz:\u00a0<strong>CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG, CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE.<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2><strong><span style=\"color: #0000ff;\">Sonu\u00e7<\/span><\/strong><\/h2>\n<p>Evet dostlar, bu yaz\u0131m\u0131z\u0131 da burada sonland\u0131r\u0131yoruz. Bir sonraki yaz\u0131mda, CMake ile QT&#8217;yi nas\u0131l kullanabiliriz. Statik k\u00fct\u00fcphaneler ve QT uygulamalar\u0131 i\u00e7in nas\u0131l konfig\u00fcre edebiliriz ona bakaca\u011f\u0131z.<\/p>\n<h2><span style=\"color: #0000ff;\"><strong>Kaynaklar<\/strong><\/span><\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md\"><span style=\"color: #008000;\"><strong>https:\/\/github.com\/google\/googletest\/blob\/master\/docs\/primer.md<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/developer.ibm.com\/technologies\/systems\/articles\/au-googletestingframework\/\"><span style=\"color: #008000;\"><strong>https:\/\/developer.ibm.com\/technologies\/systems\/articles\/au-googletestingframework\/<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/cheuksblog.ca\/tutorial\/2017\/12\/19\/googletest-tutorial.html\"><span style=\"color: #008000;\"><strong>https:\/\/cheuksblog.ca\/tutorial\/2017\/12\/19\/googletest-tutorial.html<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.toptal.com\/qa\/how-to-write-testable-code-and-why-it-matters\"><span style=\"color: #008000;\"><strong>https:\/\/www.toptal.com\/qa\/how-to-write-testable-code-and-why-it-matters<\/strong><\/span><\/a><\/li>\n<li><a href=\"http:\/\/mochan.info\/c++\/cmake\/tutorial\/2019\/03\/23\/gtest-cmake.html\"><span style=\"color: #008000;\"><strong>http:\/\/mochan.info\/c++\/cmake\/tutorial\/2019\/03\/23\/gtest-cmake.html<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html\"><span style=\"color: #008000;\"><strong>https:\/\/www.martinfowler.com\/articles\/continuousIntegration.html<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/ci\/quick_start\/\"><span style=\"color: #008000;\"><strong>https:\/\/docs.gitlab.com\/ee\/ci\/quick_start\/<\/strong><\/span><\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ee\/ci\/docker\/using_docker_images.html\"><span style=\"color: #008000;\"><strong>https:\/\/docs.gitlab.com\/ee\/ci\/docker\/using_docker_images.html<\/strong><\/span><\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Evet dostlar, uygulama yaz\u0131m\u0131za devam ediyoruz. Yaz\u0131 dizisinin di\u011fer yaz\u0131lar\u0131na eri\u015fmek i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131lar\u0131 kullanabilirsiniz: Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 2 &#8211; Ba\u015flang\u0131\u00e7 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 4 &#8211; Qt Ayarlamalar\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 5 &#8211; AMT v1.0 \u00d6ncelikle bu yaz\u0131m\u0131zda nelere de\u011finece\u011fiz, k\u0131saca onlara&#8230; <a class=\"more-link\" href=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\">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,685],"tags":[841,837,840,842,155,472,829,839,501,844,843,406,836,838,835],"class_list":["post-2047","post","type-post","status-publish","format-standard","hentry","category-c","category-modern-c","category-qt","tag-act","tag-add_library","tag-arrange","tag-assert","tag-cmake","tag-continous-integration","tag-gitlab","tag-google-mock","tag-google-test","tag-martin-fowler","tag-pipeline","tag-stdany","tag-stdatomic","tag-unit-tests","tag-utility"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - 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\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"og:description\" content=\"Evet dostlar, uygulama yaz\u0131m\u0131za devam ediyoruz. Yaz\u0131 dizisinin di\u011fer yaz\u0131lar\u0131na eri\u015fmek i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131lar\u0131 kullanabilirsiniz: Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 2 &#8211; Ba\u015flang\u0131\u00e7 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 4 &#8211; Qt Ayarlamalar\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 5 &#8211; AMT v1.0 \u00d6ncelikle bu yaz\u0131m\u0131zda nelere de\u011finece\u011fiz, k\u0131saca onlara... Continue reading &#8594;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\" \/>\n<meta property=\"og:site_name\" content=\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-25T20:43:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-11-03T21:31:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/about.gitlab.com\/images\/blogimages\/updatedcicd.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=\"17 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\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\"},\"author\":{\"name\":\"yaz\u0131l\u0131mperver\",\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"headline\":\"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon\",\"datePublished\":\"2021-01-25T20:43:03+00:00\",\"dateModified\":\"2021-11-03T21:31:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\"},\"wordCount\":3019,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb\"},\"keywords\":[\"act\",\"add_library\",\"arrange\",\"assert\",\"CMAKE\",\"Continous Integration\",\"gitlab\",\"google mock\",\"Google Test\",\"martin fowler\",\"pipeline\",\"std::any\",\"std::atomic\",\"unit tests\",\"utility\"],\"articleSection\":[\"C++\",\"Modern C++\",\"QT\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\",\"url\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\",\"name\":\"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/www.yazilimperver.com\/#website\"},\"datePublished\":\"2021-01-25T20:43:03+00:00\",\"dateModified\":\"2021-11-03T21:31:57+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Ana sayfa\",\"item\":\"https:\/\/www.yazilimperver.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon\"}]},{\"@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":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - 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\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/","og_locale":"tr_TR","og_type":"article","og_title":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","og_description":"Evet dostlar, uygulama yaz\u0131m\u0131za devam ediyoruz. Yaz\u0131 dizisinin di\u011fer yaz\u0131lar\u0131na eri\u015fmek i\u00e7in a\u015fa\u011f\u0131daki ba\u011flant\u0131lar\u0131 kullanabilirsiniz: Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 2 &#8211; Ba\u015flang\u0131\u00e7 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 4 &#8211; Qt Ayarlamalar\u0131 Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 5 &#8211; AMT v1.0 \u00d6ncelikle bu yaz\u0131m\u0131zda nelere de\u011finece\u011fiz, k\u0131saca onlara... Continue reading &#8594;","og_url":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/","og_site_name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","article_published_time":"2021-01-25T20:43:03+00:00","article_modified_time":"2021-11-03T21:31:57+00:00","og_image":[{"url":"https:\/\/about.gitlab.com\/images\/blogimages\/updatedcicd.png"}],"author":"yaz\u0131l\u0131mperver","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"yaz\u0131l\u0131mperver","Tahmini okuma s\u00fcresi":"17 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#article","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/"},"author":{"name":"yaz\u0131l\u0131mperver","@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"headline":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon","datePublished":"2021-01-25T20:43:03+00:00","dateModified":"2021-11-03T21:31:57+00:00","mainEntityOfPage":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/"},"wordCount":3019,"commentCount":0,"publisher":{"@id":"https:\/\/www.yazilimperver.com\/#\/schema\/person\/6497f6de4df6ba469748b861a2b3fcdb"},"keywords":["act","add_library","arrange","assert","CMAKE","Continous Integration","gitlab","google mock","Google Test","martin fowler","pipeline","std::any","std::atomic","unit tests","utility"],"articleSection":["C++","Modern C++","QT"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/","url":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/","name":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 - Utility, Birim Testler, S\u00fcrekli Entegrasyon - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/www.yazilimperver.com\/#website"},"datePublished":"2021-01-25T20:43:03+00:00","dateModified":"2021-11-03T21:31:57+00:00","breadcrumb":{"@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.yazilimperver.com\/index.php\/2021\/01\/25\/uygulama-izleme-yazilimi-serisi-3-birim-test\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Ana sayfa","item":"https:\/\/www.yazilimperver.com\/"},{"@type":"ListItem","position":2,"name":"Uygulama \u0130zleme Yaz\u0131l\u0131m\u0131 3 &#8211; Utility, Birim Testler, S\u00fcrekli Entegrasyon"}]},{"@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\/2047","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=2047"}],"version-history":[{"count":24,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/2047\/revisions"}],"predecessor-version":[{"id":2339,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/2047\/revisions\/2339"}],"wp:attachment":[{"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/media?parent=2047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/categories?post=2047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yazilimperver.com\/index.php\/wp-json\/wp\/v2\/tags?post=2047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}