Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
33 posts found
The Limits of TDD: The "Is TDD Dead?" Debate, Research, When Not to TDD and TDD with AI Agents
Testing & Quality PART 07

The Limits of TDD: The "Is TDD Dead?" Debate, Research, When Not to TDD and TDD with AI Agents

TDD is a trade-off, not a ritual: research shows a small quality gain and mixed productivity results, and suggests the benefit may come from short, steady steps more than from the test-first order. We cover the 2014 "Is TDD Dead?" debate, where TDD falls short (spikes, UI, performance), rules against AI coding agents' tendency to skip and loosen tests, and a CI step that catches it, with real output.

14 Nov 2026 11 min 3
TDD for Bug Fixes and Legacy Code: Red Test First, Characterization and Sprouting New Code
Testing & Quality PART 06

TDD for Bug Fixes and Legacy Code: Red Test First, Characterization and Sprouting New Code

When fixing a bug, TDD starts with a red test that reproduces it at the lowest right level; in legacy code without tests, characterization tests first record today's behavior, and a new rule is grown test-first in a separate sprout and wired in with one line. In an untested CheckoutService we see, with real output, why a characterization test that had recorded the bug turns red after the fix, and how the two kinds of test differ.

14 Nov 2026 10 min 3
TDD in Angular: Building a Signal-Based Component Test-First with Vitest
Testing & Quality PART 05

TDD in Angular: Building a Signal-Based Component Test-First with Vitest

Starting TDD in Angular from a plain TypeScript function instead of the component keeps tests fast and the component thin. With Angular 22 and Vitest we grow cart totals while catching a floating point surprise, a CartSummary component with signal inputs using whenStable and setInput, and an HttpClient service by writing the request first with provideHttpClientTesting; and we see with real output why fakeAsync fails in a zoneless project.

14 Nov 2026 11 min 3
Outside-In TDD: The Double Loop, From Acceptance Test to Domain, and London vs Classical in Practice
Testing & Quality PART 04

Outside-In TDD: The Double Loop, From Acceptance Test to Domain, and London vs Classical in Practice

Outside-in TDD builds an outer loop with an acceptance test that stays red until the feature is done, and an inner loop of unit tests that grow the pieces to make it pass. We start POST /api/cart/{id}/coupon as a walking skeleton with WebApplicationFactory, discover collaborators with mocks, test the same handler the classical way and compare, with real output, which tests break under a behavior-preserving refactoring.

14 Nov 2026 10 min 3
Practicing TDD with Katas: String Calculator, Bowling Game and Deliberate Repetition
Testing & Quality PART 03

Practicing TDD with Katas: String Calculator, Bowling Game and Deliberate Repetition

A kata is practicing the TDD rhythm through deliberate repetition, solving a small problem with a known answer many times; success means step quality, not finishing. We cover coding dojo, randori and ping-pong formats, and solve String Calculator with C# and xUnit v3 Theory and Bowling Game with TypeScript and Vitest, following the test list, the critical decision points and variations that make a kata harder, with real output.

14 Nov 2026 13 min 4
Red-Green-Refactor in Practice: Fake It, Triangulation, Obvious Implementation and Baby Steps
Testing & Quality PART 02

Red-Green-Refactor in Practice: Fake It, Triangulation, Obvious Implementation and Baby Steps

There are three ways to turn a red test green: obvious implementation when you know the code, fake it when you don't, triangulation when the design is unclear; and every surprising red means a smaller step. Growing CouponValidator live with xUnit v3, we see a banker's rounding surprise, a fake that breaks old tests, verifying a test that was green right away by breaking the code, an Istanbul-time expiry rule with TimeProvider and a small commit on every green, with real output.

14 Nov 2026 12 min 3
What Is TDD? Canon TDD, the Test List and the Real Purpose of Red-Green-Refactor
Testing & Quality PART 01

What Is TDD? Canon TDD, the Test List and the Real Purpose of Red-Green-Refactor

TDD is not writing lots of unit tests but a discipline of growing behavior in small steps while correcting the design all the time: a test list first, then one test from it, red, green, an optional refactor and an updated list. We look at Kent Beck's Canon TDD, how it differs from Uncle Bob's three laws, and how the list for Bookstore's CouponValidator changes over two loops, with real test output.

14 Nov 2026 13 min 4
Reading Old Integration and E2E Tests: WebApplicationFactory from .NET 6 to 11, Testcontainers 3 to 4, Protractor to Playwright
Testing & Quality PART 09

Reading Old Integration and E2E Tests: WebApplicationFactory from .NET 6 to 11, Testcontainers 3 to 4, Protractor to Playwright

When reading an old integration test, the first question is which application the factory brings up: a Startup-based factory can compile on .NET 10 and return 404 without ever running Bookstore. With real builds and runs we cover how WebApplicationFactory changed from .NET 6 to 11, .NET 11's ConfigureWebApplicationBuilder hook, the Testcontainers 4 changes, moving off Protractor, and the breaking changes in Playwright 1.58–1.65.

14 Nov 2026 11 min 2
Flaky E2E Tests: Isolation, Parallelism, Retries, Network Mocking and Visual Comparison
Testing & Quality PART 08

Flaky E2E Tests: Isolation, Parallelism, Retries, Network Mocking and Visual Comparison

A flaky E2E test often points to real nondeterminism in the application: Bookstore's search test was catching a race in which a late HTTP response overwrote the result. With real runs we cover shared data, time zones, page.clock, workers and sharding, the failures retries hide, legitimate uses of page.route, platform differences in toHaveScreenshot and accessibility checks with axe.

14 Nov 2026 14 min 2
End-to-End Testing Bookstore: Bringing Up the API, Angular and the Database Together
Testing & Quality PART 07

End-to-End Testing Bookstore: Bringing Up the API, Angular and the Database Together

Playwright's webServer starts two processes: a .NET host that opens the SQL Server container and runs the API on a real port with WebApplicationFactory.UseKestrel, and ng serve. With real runs we show three surprises in the host, signing in once with a setup project and storageState, preparing test data through the API, combining page objects with fixtures, and UseKestrel ignoring the port with WithWebHostBuilder.

14 Nov 2026 16 min 2
Getting Started with Playwright: Playwright Test or Playwright for .NET, Locators, Auto-Waiting and Trace Viewer
Testing & Quality PART 06

Getting Started with Playwright: Playwright Test or Playwright for .NET, Locators, Auto-Waiting and Trace Viewer

Playwright waits for the element before an action but not for the action's result; leave the result to web-first assertions built with expect(locator). For a .NET + Angular team we compare Playwright Test with Microsoft.Playwright and show with real runs how to write locators from the user's point of view with getByRole and getByLabel, strict mode, codegen, and reading a failed test in the trace viewer.

14 Nov 2026 14 min 2
The Contract Between Angular and the API: OpenAPI Documents, Breaking Change Detection and When to Use Pact
Testing & Quality PART 05

The Contract Between Angular and the API: OpenAPI Documents, Breaking Change Detection and When to Use Pact

The contract between Angular and the API is carried by an OpenAPI 3.1 document generated at build time and committed; in CI, oasdiff catches breaking changes, while TypeScript types generated from the document and tsc catch breakage in the fields actually used. With real output we explain why the document shows numbers as 'integer or string', the enum, nullable and required pitfalls, how to classify breaking changes and when Pact is needed.

14 Nov 2026 11 min 2
Blog Map