Mert Özen Further With Every Line
Project Management Agile Mindset — #03

Extreme Programming (XP): The Engineering Side of Agile

Mert Özen Nov 8, 2026 8 min 3 views
Extreme Programming (XP): The Engineering Side of Agile

Extreme Programming (XP) is the side of Agile that lives inside the code: test-first, pair programming, continuous integration, small releases, refactoring and collective code ownership form a system that supports itself. Scrum doesn't define these practices, and Fowler's Flaccid Scrum warning describes exactly that gap; with real output we show a pair writing Bookstore's free shipping rule test-first and getting it onto trunk in small commits within minutes.

Version note: The code in this post was built and run with .NET 10 and xUnit v3 4.0.2; on the XP (Extreme Programming) side it is based on both editions of Kent Beck's "Extreme Programming Explained" (1999, and 2004 with Cynthia Andres) and Martin Fowler's 2009 article "Flaccid Scrum".

Guess First

The Bookstore team moved to Scrum a year ago. The first six months went well: regular sprints, enjoyable reviews, a happy Product Owner. In the next six months velocity slowly dropped. Every new feature takes longer than expected, two or three bugs show up after every release, and the team has started saying "let's not touch that module". Sprint Planning, the Daily Scrum, Review and Retrospective all happen without fail.

Guess: which Scrum event or artifact is missing? Or is the problem in a place Scrum never defines?

Where Did XP Come From?

Extreme Programming grew out of the practices Kent Beck applied with the team on Chrysler's C3 (Chrysler Comprehensive Compensation) payroll project in 1996. Beck collected this experience in the book "Extreme Programming Explained" in 1999; in the second edition, written with Cynthia Andres in 2004, he broadened the approach and reorganized the practices. Ward Cunningham and Ron Jeffries are also important names from XP's early days; both were among the 17 people at Snowbird in 2001.

The word "extreme" describes not the practices themselves but their dose. Beck's idea is simple: if code review is good, review code all the time, that is, pair program. If testing is good, write the test before the code. If integration is good, integrate many times a day. If short cycles are good, make releases as small as possible. Take well-known practices and turn the knob all the way up.

Values: From Communication to Respect

XP has five values. The first edition had four: communication, simplicity, feedback and courage. The fifth, respect, was added in the second edition.

Communication asks that knowledge in the team doesn't stay with a single person. Simplicity describes doing the simplest thing needed today, that is, the manifesto's tenth principle and YAGNI (You Aren't Gonna Need It). Feedback asks for fast feedback at every scale: test results within seconds, CI (Continuous Integration) results within minutes, user reaction within days. Courage covers throwing code away when needed, taking on a big refactoring and saying "this estimate isn't realistic". Respect is the ground for the other four: without team members respecting each other's work and contribution, neither communication nor courage works.

Practices: The Discipline Around the Code

What sets XP apart from other Agile methods is that most of its practices are directly about code. The most important ones for this series are these:

  • Test-first and TDD (Test-Driven Development): first a failing test, then the simplest code that makes it pass, then refactoring.
  • Pair programming: two developers work on one task at the same time; one types, the other thinks about direction and design, and the roles switch often. Mob programming, which spread later, extends the same idea to the whole team.
  • Continuous integration: everyone integrates their change into the mainline at least once a day, and an automated build and tests run on every integration.
  • Small releases: releasing the system to real users in small, frequent pieces.
  • Refactoring and simple design: continuously improving the design without changing behavior, and staying with the simplest design that meets today's needs.
  • Collective code ownership: anyone on the team can change any part of the code; there is no such thing as "this module is Ali's".
  • Sustainable pace: the practice called "40-hour week" in the first edition and "energized work" in the second; a tired team writes poor code.

None of these practices was new on its own. XP's contribution was presenting them as a system that supports itself: refactoring is dangerous without tests, collective ownership turns into chaos without tests and shared standards, and small releases aren't possible without continuous integration.

A Feature's Flow with XP

A new rule is coming to Bookstore: shipping is free for orders of 500 TL and above. The existing code charges a flat fee of 49.90 TL on every order. Ada and Alan take the work as a pair. Ada is at the keyboard, Alan next to her. The first step isn't code but a test:

public class ShippingFeeTests
{
    [Theory]
    [InlineData(499.99, 49.90)]
    [InlineData(500.00, 0)]
    public void For_AppliesFreeShippingThreshold(decimal subtotal, decimal expected) =>
        Assert.Equal(expected, ShippingFee.For(subtotal));
}

Alan's first question is about the boundary itself: "Is 500 included?" They message the Product Owner who wrote the requirement, the answer is "included", and the test is written accordingly. That is exactly the first benefit of test-first: ambiguity surfaces before code is written. They run the test:

failed Bookstore.Shipping.Tests.ShippingFeeTests.For_AppliesFreeShippingThreshold(subtotal: 500, expected: 0) (1ms)
  Assert.Equal() Failure: Values differ
  Expected: 0
  Actual:   49.90

Test run summary: Failed!
  total: 2
  failed: 1
  succeeded: 1

Red, as expected: the current behavior is already correct for 499.99 and wrong for 500. They write the simplest code that makes the test pass:

public static decimal For(decimal subtotal) => subtotal >= 500m ? 0m : 49.90m;

The tests turn green and the change is committed right away to the mainline, the trunk. Then Alan takes the keyboard and they name the magic numbers:

namespace Bookstore.Shipping;

public static class ShippingFee
{
    public const decimal FlatFee = 49.90m;
    public const decimal FreeShippingThreshold = 500m;

    public static decimal For(decimal subtotal) =>
        subtotal >= FreeShippingThreshold ? 0m : FlatFee;
}

The tests are still green; that's a separate commit. At the end of the session the trunk's history looks like this; the bottom commit is the existing code that calculates the flat fee:

$ git log --format='%h %ad %s%n        %(trailers:key=Co-authored-by,valueonly,separator=%x2C )' --date=format:'%H:%M'
e5df4ce 11:59 refactor(shipping): name fee constants
        Alan <alan@bookstore.test>
78d87ca 11:59 feat(shipping): free shipping from 500
        Alan <alan@bookstore.test>
5a5d539 11:58 feat(shipping): flat shipping fee

The second person of the pair is recorded through the Co-authored-by trailer in the commit message; GitHub recognizes this trailer and attributes the commit to both people. Every commit is small, every one passed the tests and every one can be reverted on its own. No feature branch was opened, no pull request waited two days; the review already happened during pair programming. The team still requires CI to be green for every push to trunk.

The flow is the same on the Angular side: the same pair first writes a component test for the component that shows the "Free shipping" label on the cart page, then the code. The detailed technique of TDD, katas and its limits are the subject of the upcoming TDD series; frequent merges to trunk and the pipeline are the subject of the CI/CD Fundamentals series post "CI, Continuous Delivery and Continuous Deployment: The Differences and Why They Matter".

Why It Matters: Flaccid Scrum

Let's go back to the question at the start. In January 2009 Martin Fowler described the same situation in his article "Flaccid Scrum": some teams that adopt Scrum slow down after a while because they don't pay attention to the internal quality of the codebase, and technical debt makes every new feature more expensive. Fowler's observation was that Scrum is a project management framework that deliberately doesn't define technical practices, and that this gap makes it easier to neglect internal quality. His advice was clear: teams starting with Scrum should adopt technical practices too, and XP's practices are a good starting point because they fit well with Scrum.

The Bookstore team's problem was also not in Scrum but in the place Scrum doesn't define: there were no tests, refactoring was always left for "the next sprint", integration happened once a week. The Scrum series post "Engineering Practices in Scrum: Branching, CI, Feature Flags and Technical Debt" addresses this gap from within Scrum.

When Not to Use It, When to Be Careful

Forcing pair programming onto every task is a bad idea. A complex design decision, a critical bug or the onboarding period of someone new to the team suit pairing very well. Two people looking at the same screen for a one-line change in a configuration file or a mechanical rename is waste. Pair programming is also tiring; pairing nonstop all day breaks sustainable pace.

Declaring collective code ownership without team maturity is dangerous too. In a team with weak tests, no coding standard and knowledge concentrated in a few people, the rule "anyone can change anything" means anyone can break anything. Build the safety net of tests and shared standards first, then widen ownership.

Test-first isn't the right approach in every situation either. In an exploratory spike where you don't know what the answer will be, writing the test first is hard and often pointless; the spike's code will be thrown away anyway. Return to test-first when you carry what you learned into production code.

Production Notes

The precondition for merging to trunk several times a day is a fast CI. If build and tests take 40 minutes, developers start accumulating their changes and continuous integration exists only in name. The Bookstore team tracks CI duration every sprint and takes it into the backlog as technical debt when it exceeds ten minutes.

Rotate pairs. Always pairing the same two people locks knowledge into two people; the benefit of collective ownership only comes as pairs change.

The way to keep unfinished work on trunk is a feature flag. The free shipping rule can be merged before the campaign starts and wait switched off behind a flag.

Common Pitfalls

Thinking XP is Scrum's rival is a common pitfall. The two work on different layers: Scrum describes how work is planned and inspected, XP how code is written and integrated. Many teams use Scrum's events together with XP's engineering practices.

The second is confusing test-first with a coverage target. The goal is not a high percentage but that every behavior change starts with a test. What coverage tells you and what it doesn't is in the coverage post of the Test Strategy series.

The third is measuring pair programming as "two people doing one job slowly". The pair's output isn't only code; it is the review itself, shared knowledge and fewer bugs. A productivity calculation that doesn't count these is misleading.

The fourth is picking practices one by one and breaking the system: refactoring without writing tests, or declaring collective ownership without doing continuous integration.

A Small Experiment

★☆☆ Set up the example above on your own machine and introduce a bug that moves the 500 TL boundary to 499.99. Which test breaks, and what does its message tell you?

★★☆ Build your next small feature as a pair with a teammate, test-first, committing to trunk after every green test. At the end of the session, how many commits are in the git log output, and how many lines is the largest one?

★★★ List the XP practices your team uses today and mark each as "full", "partial" or "none". Which missing practice prevents the others from working?

XP may be the least misunderstood side of Agile, because it lives inside the code. That is hard to say for the rest of the manifesto. In the next post we look at the most common misconceptions about Agile: no documentation, no planning, "Agile = Scrum" and rituals replacing values.