Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
TDD'nin Sınırları: "Is TDD Dead?" Tartışması, Araştırmalar, Ne Zaman TDD Yapmamalı ve AI Agent'larla TDD
TDD bir ritüel değil bir takastır: araştırmalar küçük bir kalite artışı ve karışık üretkenlik sonuçları gösteriyor, faydanın test-first sırasından çok kısa ve düzenli adımlardan gelebileceğini söylüyor. 2014'teki "Is TDD Dead?" tartışmasını, TDD'nin zayıf kaldığı spike, UI ve performans gibi yerleri, AI coding agent'larının testleri atlama ve gevşetme eğilimine karşı kuralları ve bunu yakalayan bir CI adımını gerçek çıktıyla ele alıyoruz.
Bug Fix ve Legacy Kodda TDD: Önce Kırmızı Test, Characterization ve Sprout ile Yeni Kod
Bug düzeltirken TDD önce hatayı en düşük doğru seviyede yeniden üreten kırmızı bir testle başlar; testi olmayan legacy kodda ise önce characterization testlerle bugünkü davranış kaydedilir, yeni kural ayrı bir sprout'ta test-first büyütülüp eskiye tek satırla bağlanır. Testsiz bir CheckoutService'te bug'ı kaydetmiş bir characterization testin düzeltmeden sonra neden kırmızıya döndüğünü ve iki test türünün farkını gerçek çıktılarla görüyoruz.
Angular'da TDD: Vitest ve Signal Tabanlı Component'i Test-first Geliştirmek
Angular'da TDD'ye component'ten değil saf TypeScript fonksiyonundan başlamak testleri hızlı, component'i ince tutar. Angular 22 ve Vitest ile sepet toplamlarını kayan nokta sürprizini yakalayarak, signal input'lu CartSummary component'ini whenStable ve setInput ile, HttpClient service'ini provideHttpClientTesting ile isteği önce yazarak geliştiriyor; zoneless projede fakeAsync'in neden çalışmadığını gerçek çıktıyla görüyoruz.
Outside-in TDD: Double Loop, Acceptance Test'ten Domain'e ve London ile Classical Okulu Pratikte
Outside-in TDD, özellik bitene kadar kırmızı kalan bir acceptance test'le dış döngüyü, onu geçirecek parçaları büyüten unit test döngüleriyle iç döngüyü kurar. POST /api/cart/{id}/coupon endpoint'ini WebApplicationFactory ile walking skeleton'dan başlatıp mock'larla collaborator keşfediyor, aynı handler'ı classical yolla da test ediyor ve davranışı değiştirmeyen bir refactor'da hangi testlerin kırıldığını gerçek çıktıyla karşılaştırıyoruz.
Kata'larla TDD Pratiği: String Calculator, Bowling Game ve Bilinçli Tekrar
Kata, cevabı bilinen küçük bir problemi defalarca çözerek TDD ritmini bilinçli tekrarla geliştirmektir; başarı ölçütü bitirmek değil adım kalitesidir. Coding dojo, randori ve ping-pong formatlarını, String Calculator'ı C# ve xUnit v3 Theory ile, Bowling Game'i TypeScript ve Vitest ile çözerken test list'in evrimini, kritik karar anlarını ve kata'yı zorlaştıran varyasyonları gerçek çıktılarla görüyoruz.
Red-Green-Refactor Uygulamada: Fake It, Triangulation, Obvious Implementation ve Baby Step'ler
Kırmızı testi yeşile çevirmenin üç yolu var: kodu biliyorsan obvious implementation, bilmiyorsan fake it, tasarım belirsizse triangulation; seni şaşırtan her kırmızıda adımı küçültürsün. CouponValidator'ı xUnit v3 ile canlı geliştirirken banker's rounding sürprizini, eski testleri kıran bir fake'i, hemen yeşil olan testi bozarak doğrulamayı, TimeProvider ile İstanbul saatine göre son kullanma kuralını ve her yeşilde küçük commit ritmini gerçek çıktılarla görüyoruz.
TDD Nedir? Canon TDD, Test List ve Red-Green-Refactor'ın Asıl Amacı
TDD çok unit test yazmak değil, davranışı küçük adımlarla büyütürken tasarımı sürekli düzeltme disiplinidir: önce test list, sonra listeden tek test, kırmızı, yeşil, isteğe bağlı refactor ve listeyi güncellemek. Kent Beck'in Canon TDD tarifini, Uncle Bob'un three laws anlatımıyla farkını ve Bookstore'un CouponValidator'ı için listenin iki döngüde nasıl değiştiğini gerçek test çıktılarıyla görüyoruz.
Eski Integration ve E2E Testlerini Okumak: WebApplicationFactory .NET 6'dan 11'e, Testcontainers 3'ten 4'e, Protractor'dan Playwright'a
Eski bir integration testini okurken ilk soru, factory'nin hangi uygulamayı ayağa kaldırdığıdır: Startup tabanlı bir factory .NET 10'da derlenip Bookstore'u hiç çalıştırmadan 404 döndürebilir. WebApplicationFactory'nin .NET 6'dan 11'e değişimini, .NET 11'in ConfigureWebApplicationBuilder hook'unu, Testcontainers 4 değişikliklerini, Protractor'dan geçişi ve Playwright 1.58–1.65'teki kırıcı değişiklikleri gerçek derleme ve koşularla anlatıyoruz.
Flaky E2E Testleri: İzolasyon, Paralellik, Retry, Network Mocking ve Görsel Karşılaştırma
Flaky bir E2E testi çoğu zaman uygulamadaki gerçek bir belirsizliği gösterir: Bookstore'daki arama testi, geç gelen bir HTTP cevabının sonucu ezdiği bir yarış durumunu yakalıyordu. Paylaşılan veri, saat dilimi, page.clock, worker ve sharding, retry'ın gizlediği hatalar, page.route'un meşru kullanımları, toHaveScreenshot'ta platform farkı ve axe ile accessibility kontrolünü gerçek koşularla anlatıyoruz.
Bookstore'u Uçtan Uca Test Etmek: API, Angular ve Veritabanını Birlikte Ayağa Kaldırmak
Playwright'ın webServer'ı iki process başlatır: SQL Server container'ını açıp API'yi WebApplicationFactory.UseKestrel ile gerçek portta çalıştıran bir .NET host'u ve ng serve. Host'taki üç sürprizi, login'i setup project ve storageState ile bir kez yapmayı, test verisini API'den hazırlamayı, page object ile fixture'ı birlikte kullanmayı ve UseKestrel'in WithWebHostBuilder'la portu yok saymasını gerçek koşularla gösteriyoruz.
Playwright'a Giriş: Playwright Test mi Playwright for .NET mi, Locator'lar, Auto-wait ve Trace Viewer
Playwright action'dan önce element'i bekler ama action'ın sonucunu beklemez; sonucu expect(locator) ile kurulan web-first assertion'lara bırak. .NET + Angular ekibi için Playwright Test ile Microsoft.Playwright'ı karşılaştırıyor, getByRole ve getByLabel ile kullanıcı gözüyle locator yazmayı, strict mode'u, codegen'i ve kalan bir testi trace viewer ile okumayı gerçek koşularla gösteriyoruz.
Angular ile API Arasındaki Contract: OpenAPI Dokümanı, Breaking Change Tespiti ve Ne Zaman Pact?
Angular ile API arasındaki sözleşmeyi build'de üretilip commit'lenen OpenAPI 3.1 dokümanı taşır; CI'da oasdiff breaking change'i, dokümandan üretilen TypeScript tipleri ve tsc de kullanılan alanların kırılmasını yakalar. Dokümanın sayıları neden 'integer ya da string' gösterdiğini, enum, nullable ve required tuzaklarını, breaking change sınıflandırmasını ve Pact'in ne zaman gerektiğini gerçek çıktılarla anlatıyoruz.