# Hur jag bygger mjukvara

<datetime class="hidden">2025-11-19T10:00</datetime>

<!-- category -- Software Development, Testing, TDD, Craftsmanship, Best Practices -->
**Varför skriver jag test i sista gången och varför det inte är vad du tror att det betyder**

> **Kontroversella antaganden:** Testing-Driven Development är en lysande praxis som löser det felaktiga problemet för de flesta kreativa projekten.

## De tre stadierna i byggandet av mjukvara ( som faktiskt fungerar)

Det är så jag bygger mjukvaran.

**Få den att fungera . Få den till att vara vacker. Sluka ner den med tester**

I den ordningen

Inte för att jag är lata. *det här är hur kreativt arbete faktiskt sker* när du utforskar ett problem som du inte förstår ännu

```mermaid
graph TB
    Start[New Feature Request] --> P1[Phase 1: Make It Work]

    P1 --> P1_Private[Private Exploration]
    P1_Private --> P1_Sketch["Sketch the solution<br/>Messy code OK<br/>No tests yet<br/>Focus on learning"]
    P1_Sketch --> P1_Run["Run it manually<br/>Try different inputs<br/>See what breaks<br/>Understand the problem"]
    P1_Run --> P1_Decision{Does it work<br/>basically?}
    P1_Decision -->|No| P1_Iterate[Try different approach]
    P1_Iterate --> P1_Sketch
    P1_Decision -->|Yes| P2

    P2[Phase 2: Make It Pretty] --> P2_Refine[Private Refinement]
    P2_Refine --> P2_Clean["Clean up the code<br/>Better names<br/>Type hints/annotations<br/>Clear structure"]
    P2_Clean --> P2_Align["Align with spec<br/>Cover all requirements<br/>Handle edge cases<br/>Polish API surface"]
    P2_Align --> P2_Optimise["Optimise<br/>Performance<br/>Readability<br/>Maintainability"]
    P2_Optimise --> P3

    P3[Phase 3: Lock It Down] --> P3_Share[Public Sharing]
    P3_Share --> P3_Tests["Write comprehensive tests<br/>Full coverage<br/>Edge cases<br/>Error conditions"]
    P3_Tests --> P3_CI["CI/CD Integration<br/>Automated testing<br/>Code review<br/>Documentation"]
    P3_CI --> P3_Deploy["Ready to Share<br/>Commit to main<br/>Deploy to prod<br/>Other devs can use it"]

    P3_Deploy --> Done[Well-Tested,<br/>Well-Designed Code]

    style P1 stroke:#ff6b6b,stroke-width:3px
    style P2 stroke:#4ecdc4,stroke-width:3px
    style P3 stroke:#95e1d3,stroke-width:3px
    style Done stroke:#38ada9,stroke-width:4px
```

Inte för att jag är lata. *det här är hur kreativt arbete faktiskt sker* när du utforskar ett problem som du inte förstår ännu

Låt mig förklara

[TOC]

## Fasen 1: Få det att fungera (Privatskivan | )

Det här är den röriga delen, där jag inte har någon aning om vad jag gör.

I'Jag försöker förstå

- Fungerar denna API faktiskt på samma sätt som dokumenten säger
- Kan jag till och med lösa problemet med de verktyg jag har?
- Vad betyder "korrigt
- Är det ett två timmars problem eller ett två veckors problem?

**Det här är uppfinning.**

Och du vet vad som dödar jazz.

### Varför inga tester än?

För att **formen är fortfarande flytande.**

Föreställ dig att du är en skulptör. Du har ett block av marmor och en vag idé.

TDD säger: "" Before you touch that marble, write down exactly what a bird looks like. "" "" Define its wingspan, ., Specify the angle of each feather, ., Now carve to those specifications."

Att det inte är så att fågel är graverade, utan att mjukvaran blir skriven, som det visar sig.

Verkliga skulptörer *rough out the form first.* De skissar.

**Kod är densamma.**

I fasen 1, I' m skrivande :

```python
# Ugly, exploratory code
def process_thing(data):
    # TODO: This is terrible, fix later
    result = []
    for item in data:
        # Not sure if this is the right approach...
        x = item.get('value')
        if x:  # Is this even the right condition?
            result.append(x * 2)  # Why multiply by 2? Testing something...
    return result
```

Den här koden är **privat.** Det är ett samtal med mig själv. Det är hur jag listar ut vad det betyder att arbeta

Att skriva tester för detta är värre än värdelöst. *kraftigt skadlig.* För varje gång jag inser """, "" Åh, vänta! "" ",, hela den här metoden är fel!"

Att "'" inte är rigoröst , ".", och att МSK 2 är byråkratiskt ,

### friheten att misslyckas snabbt

Fasen 1 är ungefär **lärandehastighet.**

Jag måste pröva fem olika sätt på en timme. *borde* att lösa

Tester saktar ner det här.. Inte för att tester är långsamma, **för tidigt specifikation är död.**

Om jag skriver tester innan jag förstår problemet *fel sak.* Sedan investerar jag känslomässigt i det felaktiga. Sedan bekämpar jag det felliga med kodbevakning.

Bättre att misslyckas snabbt, i privatt, utan att göra några test för att hålla kvar och utan ego för att skydda

### Vad betyder "Arbeting" i fas 1

Det betyder: :, " Jag körde den. ., jag gav den några intryck.., den gav ett rimligt uttryck.

Det är det.

Inga randkoster. Inga felbehandlingar . Ingen elegans

Bara en pisk. Ett bevis på konceptet. En skiss .

## Fasen 2: Gör det vackert | ( | Utfinning |)

Okej, så nu förstår jag problemet. Jag har något som fungerar, åtminstone för den lyckliga vägen.

**Nu kan jag börja bry mig om kvalitet**

Fasen 2 är där

### 1. Skolla upp meddelandet

**Python exempel:**

```python
# Before (Phase 1) - Exploratory code
def process_thing(data):
    result = []
    for item in data:
        x = item.get('value')
        if x:
            result.append(x * 2)
    return result

# After (Phase 2) - Refined code
def extract_doubled_values(items: list[dict]) -> list[int]:
    """Extract 'value' field from items and double each one.

    Only includes items where 'value' is present and truthy.
    """
    return [
        item['value'] * 2
        for item in items
        if item.get('value')
    ]
```

**C# exempel :**

```csharp
// Before (Phase 1) - Exploratory code
public List<int> ProcessThing(List<Dictionary<string, object>> data)
{
    var result = new List<int>();
    foreach (var item in data)
    {
        if (item.ContainsKey("value"))
        {
            var x = item["value"];
            if (x != null)
            {
                result.Add(Convert.ToInt32(x) * 2);
            }
        }
    }
    return result;
}

// After (Phase 2) - Refined code
/// <summary>
/// Extracts 'value' field from items and doubles each one.
/// Only includes items where 'value' is present and non-null.
/// </summary>

public IEnumerable<int> ExtractDoubledValues(IEnumerable<IDictionary<string, object>> items)
{
    return items
        .Where(item => item.ContainsKey("value") && item["value"] != null)
        .Select(item => Convert.ToInt32(item["value"]) * 2);
}
```

Bättre namn. Typbeteckningar . XML-dokumentationen. En renare LINQ-implementering

### 2. Lika ihop med Specen

Nu när jag vet vad jag faktiskt bygger, går jag tillbaka till de ursprungliga kraven och ser till att jag löser *högra* problem, inte bara *a* problem.

Det visar ofta luckor

- De ville att detta skulle hantera negativa siffror annorlunda.
- " Vänta, , det finns ' som är ett marginalfall där värdet kan vara Ingen mot
- Specen säger "" ', dubbelt, ' "", men jag tror att det betydde "', skala med en konfigurerad faktor."

Jag fixar dessa. Ibland trycker jag tillbaka på specifikationen.

### 3. Polisera API: s yta

Det är här jag tänker på *ringare's* erfarenhet.

**Python:**

```python
# Phase 1: Works, but awkward to use
process_thing(data)

# Phase 2: Clear, flexible, composable
extract_doubled_values(
    items,
    scale_factor=2.0,
    include_zeros=False
)
```

**C#:**

```csharp
// Phase 1: Works, but awkward to use
ProcessThing(data);

// Phase 2: Clear, flexible, composable
ExtractDoubledValues(
    items,
    scaleFactor: 2.0,
    includeZeros: false
);

// Or even better with a fluent API
items.ExtractValues()
     .Scale(by: 2.0)
     .ExcludingZeros()
     .ToList();
```

Bättre namngening. Uppmärksama standarder . Konfiguration där det spelar roll

Det här är **craft.** Det är här som bra mjukvara kommer ifrån

```mermaid
graph LR
    subgraph "Phase 2 Refinement Process"
        A[Rough Code] --> B[Clean Structure]
        B --> C[Add Types]
        C --> D[Polish API]
        D --> E[Static Analysis]
        E --> F{Quality Gates Pass?}
        F -->|No| G[Fix Issues]
        G --> B
        F -->|Yes| H[Ready for Phase 3]
    end

    style A stroke:#ff6b6b,stroke-width:3px
    style H stroke:#95e1d3,stroke-width:3px
```

### Varför finns det fortfarande inga tester?

*Oh, JagM SK1 Jag kör den hela tiden .* Jag har en REPL öppen.

Men det är inte så. *skriva ner dessa experiment som formella tester än*

Varför? Eftersom **Jag upptäcker fortfarande vad som är värt att testa.**

I Fasen 1, visste jag inte ' om denna funktion skulle existera.

- ", oh, ,, skalfaktorn kan inte vara negativ.
- "Om listan är tomt , så borde vi ge tillbaka tomt
- " Vi måste hantera icke-

Dessa insikter *dyker upp från att återformera* De är inte uppenbara från början.

Om jag skrev tester i fas 1,, skulle jag skriva om dem nu. *efter* I' har förfinat implementeringen , de M SK2 kommer att vara korrekt den första gången

## Fasen 3: låsa ner den med tester (Springfasen | )

Ok, nu är det ', det riktiga

Koden är ren.

**Nu skriver jag tester.**

### Varför nu?

För att **tester är en samarbetsmekanism.**

De är inte längre för mig. Jag förstår redan den här koden på ett nära sätt. Jag har levt i den i timmar eller dagar.

Test är för:

1. **Framtiden för mig** (som kommer glömma allt inom tre månader )
2. **Mina lagkamrater** (som behöver lita på att den här koden fungerar
3. **CI-tunneln** ( som behöver förhindra regressioner )
4. **Framtidens underhållare** (som behöver bygga om det här på ett säkert sätt

Tester är **presentationslayer** för min realisation.

De dokumenterar:

- Vad den här koden gör
- Vilka ingångar är korrekta
- Vilka resultat ska man förvänta sig
- Vilka marginalfall har jag tänkt på
- Vilka antaganden gör jag?

### Full Coverage, Inga kompromisser

I fasen 3, går jag hårt på att testa

```python
def test_extract_doubled_values_basic():
    items = [{'value': 5}, {'value': 10}]
    assert extract_doubled_values(items) == [10, 20]

def test_extract_doubled_values_skips_missing_values():
    items = [{'value': 5}, {'name': 'foo'}, {'value': 3}]
    assert extract_doubled_values(items) == [10, 6]

def test_extract_doubled_values_handles_zeros():
    items = [{'value': 0}, {'value': 5}]
    # By default, zeros are excluded (falsy)
    assert extract_doubled_values(items) == [10]

def test_extract_doubled_values_includes_zeros_when_configured():
    items = [{'value': 0}, {'value': 5}]
    assert extract_doubled_values(items, include_zeros=True) == [0, 10]

def test_extract_doubled_values_custom_scale_factor():
    items = [{'value': 5}]
    assert extract_doubled_values(items, scale_factor=3.0) == [15.0]

def test_extract_doubled_values_rejects_negative_scale_factor():
    with pytest.raises(ValueError):
        extract_doubled_values([], scale_factor=-1.0)

def test_extract_doubled_values_handles_empty_list():
    assert extract_doubled_values([]) == []

def test_extract_doubled_values_handles_non_numeric_values():
    items = [{'value': 'not a number'}]
    with pytest.raises(TypeError):
        extract_doubled_values(items)
```

**Det här är säkerhetsnätet**

Nu kan mina lagkamrater

- Modifiera denna funktion självsäkrat
- Understand the edge cases
- Att fånga återfall omedelbart
- Refaktor utan rädsla

### Test som dokumentation

Bra tester är bättre dokumentation än kommentarer:

```python
# This comment will drift from reality:
# Doubles all numeric values, skipping None

# This test will fail if reality changes:
def test_extract_doubled_values_skips_none_values():
    items = [{'value': None}, {'value': 5}]
    assert extract_doubled_values(items) == [10]
```

Testar inte ljuger. De kan drifta. Om beteendet ändras.

Det's **utförbar dokumentation.** Det är det som gör tester värdefulla

### Det delade gränsen

Här är det kritiska: **Fasen 3 händer innan någon annan rör vid koden .**

Jag delar inte koden utan att göra tester.

Men jag skriver inte heller tester innan koden är redo att dela.

De stadierna är:

1. **Privatexploration** ( bara mig , inga tester
2. **Privat raffinering** ( bara mig , fortfarande inga tester
3. **Öffentligt dela** (tester

Det skyddar både min kreativitet *och* mina lagkamrater

## Varför detta skyddar kreativiteten

TDD-aktivister säger: "" Testar ger dig självförtroende till att rekonstruera "".

Verkligen, men bara om du redan vet vad du bygger.

När I'm är i fas 1, behöver jag inte confidence för att göra om **Jag behöver tillåtelse att kasta allt bort**

Test skapar psykologisk skuld.

Genom att skjuta upp tester till Fasen 3, så håller jag Fasen *psykologiskt billigt.*

Jag kan

- Försök vilda idéer
- Släng bort hela angrepp
- ändra designen på ett radikalt sätt
- Ta reda på problemet I'm *faktiskt* att lösa

Allt utan skuldbekännelsen för """, men jag skrev alla dessa tester.

**Det är så kreativitet fungerar.**

Du skissar loosen först. Du gör det inte

## Hur det passar med Agile och XP ( Och vart det skiljer sig

Låt oss vara tydliga med något. **det här är inte "test senare utveckling**

Det här är **"test medan man håller på med utvecklingen , men vid rätt tidpunkt**

Timing av *när* att lägga till enhetens tester är kritiskt.

### XP-metoderna jag håller på med

Extreme Programming har fantastiska metoder värda att följa:

**Kontinuös integrering**

- Varje egenskap går igenom CI innan de går samman
- Automatiserad test drivs på varje kommando till huvud
- Inga brutna byggnader toleras

**Par programmering / Kodexbevakning**

- Fasen 3 kod blir överprüft innan du delar den
- Tester är en del av den överprüfbara artefakten
- Kollaborativ raffinering förbättrar designen

**Enkel design**

- Fasen 2 är *allt om* förenkling
- Ta bort vad du inte behöver
- Gör det så enkelt som möjligt, inte enklare

**Refactoring**

- Fasen 2 är en dedikerad reafaktoreringstid
- Skoda koden *före* att låsa ner den
- Test skyddar omformeringen ( i fas 3+)

### Var jag skiljer mig från strikt TDD

```mermaid
graph TB
    subgraph "Traditional TDD (Red-Green-Refactor)"
        TDD1[Write Failing Test] --> TDD2[Write Minimal Code to Pass]
        TDD2 --> TDD3[Refactor]
        TDD3 --> TDD1
    end

    subgraph "Three-Phase Approach (Explore-Refine-Lock)"
        P1[Explore Solution Space] --> P2[Refine Implementation]
        P2 --> P3[Write Comprehensive Tests]
        P3 --> P4[Share With Team]
    end

    style TDD1 stroke:#ffaa00,stroke-width:2px
    style TDD2 stroke:#ffaa00,stroke-width:2px
    style TDD3 stroke:#ffaa00,stroke-width:2px
    style P1 stroke:#ff6b6b,stroke-width:3px
    style P2 stroke:#4ecdc4,stroke-width:3px
    style P3 stroke:#95e1d3,stroke-width:3px
```

**TDD säger:  :** " Testar först . Särskilt . Röd M SK3 Grönt MSC4 Refaktorn är det enda sättet

**Jag säger:".** "Tester när du vet vad du testar 'testar du. UtforskaM SK3Rexifiera

Den viktiga skillnaden:

| TDD
|-----|-------------|
| Test definierar gränssnittet ♫ | ♫ Exploration definierargränssnittet
| Röd-GrönM SK2Refaktorcycling | Utforska
| Test skrivna innan implementering | Test skriven innan *att dela* |
| Testa först för allting ♫ | ♫ Testa i rätt tid för varje sak ♫
| Mikro, -cykler, minuter, M SK3, | | | Makro, - | stadier,

### Timeringen är kritisk

Här är den avgörande insikten. **Det' är inte M SK1testar sist." Det 's "tester innan du delar ut**

**Verklig timing (för tidigt**

```
Hour 1: Write test for API I haven't designed yet
Hour 2: Realize the API is wrong, rewrite test
Hour 3: Discover a better approach, rewrite both
Hour 4: Finally get it working
Hour 5: Rewrite tests to match what actually works
```

**Rätt tidning (Phasen 3):**

```
Hour 1: Explore 3 different APIs, settle on the best one
Hour 2: Refine the implementation, handle edge cases
Hour 3: Write comprehensive tests for what I built
Hour 4: All tests pass, commit with confidence
```

Samma kvalitet i resultat

### Detta är Agile

Agile säger:". **" Svara på förändring efter en plan**

TDD kan bli sin egen form av plan.

Min metod omfamnar förändring

- Fas 1: ändra snabbt , hitta rätt lösning
- Fas 2: ändrad avsiktligt , raffineras mot elegans
- Fas 3: ändra försiktigt , skydda vad som fungerar

Det här är *mer* agiler än strikt TDD, eftersom det skjuter upp engagemang tills du har information.

### Motsägelsefulla tillvägagångssätt : A C# exempel

**Strak TDD-metod:**

```csharp
// Test 1: Write test first (but I don't know the right API yet)
[Test]
public void TestProcessData()
{
    var processor = new DataProcessor();
    var result = processor.Process(new[] { 1, 2, 3 });
    Assert.That(result, Is.EqualTo(new[] { 2, 4, 6 }));
}

// Implementation 1: Make it pass
public class DataProcessor
{
    public int[] Process(int[] data) => data.Select(x => x * 2).ToArray();
}

// Later: Realize I need configurability, rewrite test
[Test]
public void TestProcessDataWithFactor()
{
    var processor = new DataProcessor();
    var result = processor.Process(new[] { 1, 2, 3 }, factor: 3);
    Assert.That(result, Is.EqualTo(new[] { 3, 6, 9 }));
}

// Later: Realize I should use IEnumerable, rewrite test again
[Test]
public void TestProcessDataEnumerable()
{
    var processor = new DataProcessor();
    var data = GetLargeDataset(); // This should be lazy
    var result = processor.Process(data, factor: 3);
    Assert.That(result.Take(3), Is.EqualTo(new[] { 3, 6, 9 }));
}
```

Notera gungen? Tre omskrivna tester medan designen utvecklades

**Tre-Phas Approach:**

```csharp
// Phase 1: Explore (no tests yet)
public int[] ProcessThing(int[] data)
{
    return data.Select(x => x * 2).ToArray();
}
// Try it: var result = ProcessThing(new[] { 1, 2, 3 });
// Hmm, what about configurability? What about lazy evaluation?

// Phase 2: Refine (still no tests)
public static class DataProcessorExtensions
{
    public static IEnumerable<int> Scale(
        this IEnumerable<int> source,
        int factor = 2)
    {
        return source.Select(x => x * factor);
    }
}
// Try it: var result = data.Scale(factor: 3).ToList();
// Much better API!

// Phase 3: Lock it down (NOW write tests, correctly)
[TestFixture]
public class DataProcessorTests
{
    [Test]
    public void Scale_DefaultFactor_DoublesValues()
    {
        var result = new[] { 1, 2, 3 }.Scale();
        Assert.That(result, Is.EqualTo(new[] { 2, 4, 6 }));
    }

    [Test]
    public void Scale_CustomFactor_ScalesCorrectly()
    {
        var result = new[] { 1, 2, 3 }.Scale(factor: 3);
        Assert.That(result, Is.EqualTo(new[] { 3, 6, 9 }));
    }

    [Test]
    public void Scale_LazyEvaluation_DoesNotEnumerateImmediately()
    {
        var enumerated = false;
        var data = GetTestData(() => enumerated = true);
        var scaled = data.Scale(factor: 2);

        Assert.That(enumerated, Is.False, "Should not enumerate yet");

        scaled.ToList();
        Assert.That(enumerated, Is.True, "Should enumerate on materialization");
    }

    [Test]
    public void Scale_EmptySequence_ReturnsEmpty()
    {
        var result = Enumerable.Empty<int>().Scale();
        Assert.That(result, Is.Empty);
    }
}
```

Ett testsystem . En gång skrivet. Korrigera första gången. Eftersom jag visste vad jag byggde

### Agile Manifesto Connection

Kom ihåg värdena:

**"Working software over comprehensive documentation**

- Fasen 1 får igång mjukvara *fort*
- Fasen 3 gör tester av den kompletta dokumentationen

**"Atbild till förändring efter en plan**

- Faser 1-2 omfamnar förändring
- Fasen 3 låser i den slutgiltiga designen

**"Individueller och interaktioner över processer och verktyg"**

- Låt inte TDDs dogma överrösta gott omdöme
- Samarbeta när det hjälper

**"Kunssamarbete över kontraktförhandlingar "**

- Fasen 2 följer specifikationen *efter* att förstå problemet
- Det är bättre att leverera vad de behöver än vad de specifikerade

## Varför reducerar detta värdelösa knapr

TDD's smutsiga hemlighet **de flesta tester som skrevs innan implementeringen är omskrivna eller lösda.**

Varför?

- Du missförstod kraven
- Du visste inte edge cases än
- Du upptäckte en bättre API-design
- Du insåg att funktionen inte alls behövdes

Varje test du skriver i Fasen 1 är antagligen slösaktigt

Bättre att skriva *ett* uppsättning test i Fasen 3, när du faktiskt vet vad du bygger '

### TDDs löfte mot verkligheten

**TDD lovar** "Prätestar driver din design ! De hjälper dig att upptäcka bra APIs

**TDD verkligheten:** " Jag skrev tester för en API som jag tyckte var vettigt, . Sedan implementerade jag den och insåg att APIn var obekväm, ♫ . ♫ Nu skriver jag om både testerna och koden ♫

Att "'" inte är design. *thrashing.*

**Mitt tillvägagångssätt:** Design genom att implementera

Slutresultatet är samma.

## Varför detta fortfarande tillhandahåller disciplinerad mjukvara

Här är vad den här ansatsen är *inte:*

- "Cowboykodering
- " Inga tester
- "Såge och ber

Vid den tid jag ' gör med Fasen 3, har min kod

- Omgripande testbeläggning
- Edge fall hanterade
- Clean, läsbar implementering
- Klara API-design
- Dokumentation (med hjälp av tester)

*Precis samma sak som TDD.*

Skillnaden är *när* dessa tester skrevs

### Disciplinen kommer från gränserna

Reglerna är enkla: **Ingen kod lämnar Fasen 2 utan Fasen**

Jag tror inte

- Stuur in otestad kod
- Att öppna PR utan att göra tester
- Merge till huvuden utan att skicka CI
- Deploy utan rapporter om skydd

Disiplinen är: "'t i skrivandetests tidigt. *att inte dela koden utan att göra tester.*

## Craft-metaforerna

Det här är ingen ny idé, det är hur kreativt arbete alltid har fungerat.

### Sketch → Refinera → Varnish

Malare kan inte börja med de slutgiltiga pensels strokerna.

De:

1. **Sketch** sammansättning (Phasen  1)
2. **Färg** lagerna (Phasen  2)
3. **Varnish** för att skydda och presentera (Phasen 3)

Varnishmen kommer inte först, men det är optionellt.

### ritning → redigera → publicera

Redare kan inte redigera när de skriver.

De:

1. **ritning** otäckt (Phasen  1)
2. **Reda** grymt (Phasen  2)
3. **publicera** med självförtroende (

"skriv drunken, , redigera nykter, " är en hemsk livsrådet men bra när det gäller att skriva.

### Plast → Form → Glazier

Potterer använder inte glasier innan de formar sig.

De:

1. **Slänga** lera (Phasen  1)
2. **Förbrylla och raffinera** formen (Phasen  2)
3. **Glazier och eld** för hållbarhet (Phasen 3)

Glazjan är avgörande. Men den kommer sista.

## Hur det här kartläggs till DiSE-kodgen-pingelin

Här är "'", där det blir intressant. *implementerad* denna filosofi i DiSE: s system

Koderingskedjan förkroppsligar explicit dessa tre faser:

### Fas 1 i DiSE: Explorationsfasen

När du frågar DiSE om att lösa ett problem

Istället **Generator** (codellama eller liknande ) får ett tydligt mandat

```
"Write code that solves the specification.
Don't worry about perfection yet.
Just get it working."
```

Systemet genererar utforskningskod:

- Fokuserad på den lyckliga vägen
- Minimalt felbehandling
- Ingen för tidig optimering
- Bara tillräckligt för att testa angreppet

Sedan **Operatör** kör den. Inte med formella enhetens tester — bara med intrycken från specifikationen

Om det misslyckas? Inga problem **lärande.**

Systemet har en 6- stegad adaptiv upphöjning

1. Försök det med en snabb modell ( låg temperatur
2. Försök igen med större kreativitet ( högre temperaturM SK1
3. Spring till en mer kraftfull modell
4. Lägg till debug-loggning för att förstå fel
5. Ge hela sammanhanget till den kraftfulla modellen
6. Använd "god-levelM SK2 modellen som sista tillvägagångssättet

Det här är *precis* Fasen 1. Systemet utforskar lösningsrummet , lär sig vad som fungerar M SK2 misslyckas snabbt , och anpassar sig

**Inga tester skrivs under den här fasen.** Koden är privat för genereeringsprocessen.

### Fas 2 i DiSE: Optimeringsfasen

När koden passerar grundoperationen, flyttar DiSE till **optimering.**

Detta är raffineringsfasen

1. **Tvättar upp implementeringen**
   
   - Ta bort debug-loggen som lagts till under misslyckanden
   - Förenklar för komplicerad kod
   - Försämrar namn och struktur

2. **kör statisk analys**
   
   ```
   - flake8 (style checking)
   - pylint (code quality)
   - mypy (type checking)
   - black (formatting)
   - radon (complexity analysis)
   ```

3. **Optimerar om och om igen** (3 repetitioner standardmässigt
   
   ```python
   for iteration in range(3):
       # Measure current performance
       metrics = measure_performance(code)
   
       # Generate improved version
       better_code = optimise(code, metrics)
   
       # Keep if better, discard if worse
       if better_code.score > code.score:
           code = better_code
   ```

Det här är *precis* Fasen 2. Koden är fortfarande privat ♫ ( ♫ är inte i registret än ♫ ), ♫ men vi ♫' ♫ polerar den ♫ : ♫

- Bättre namn
- Typa ledtrådar
- renare struktur
- lägre komplexitet
- Bättre resultat

Formen är inte längre flytande. *bra.*

### Fas 3 i DiSE: Test- och lagerfasen

Bara *efter* optimering gör DiSE generera och köra **formella unittestar.**

Här ' är den avgörande delen: skapas testerna från *raffinerad specifikation och implementation*, inte den ursprungliga utforskningen

```python
# Test generation happens AFTER optimisation
def generate_unit_tests(specification, optimized_code):
    """Generate comprehensive tests for refined code.

    This happens in Phase 3, after we know:
    - What the code actually does
    - What edge cases exist
    - What the API surface looks like
    """
    return llm.generate(
        f"""Generate comprehensive unit tests for this code.

Specification: {specification}
Implementation: {optimized_code}

Include tests for:
- Happy path (from spec examples)
- Edge cases (discovered during optimisation)
- Error conditions (based on actual error handling)
- Performance bounds (based on measured metrics)
"""
    )
```

Testen täcker::

- Spesifikationsexempler ( korrekthet)
- Randfall upptäckta under fas 2
- Ett handlingsfel som lagts till under förfinning
- Förmågor som mätts

Sedan, *endast om tester går*, koden är:

1. Bevarad i **RAG minne** (med inbäddar
2. Läggs till **noderregistret** ( som en utförbar artefakt
3. Made available for **återanvända** i framtida arbetsflöden
4. spårad med **kvalitetscore** och **prestationsmått**

**Detta är delafasen.** Koden är nu offentlig. ( till systemet ). Den har komplexa tester M SK2 Den ' är låst ned

### Varför det fungerar i en kodskapande system

Den tre-MSK-phasen-metoden är *nödvändigt* för AI-driven kod generering eftersom

**Fas 1: Modeller förstår inte problemet från början**

- De behöver utforska lösningsområdet
- Börjande försök misslyckas ofta på intressanta sätt.
- Misslyckanden ger information för bättre försök
- Framtidstest skulle tvinga framdröjda specifikationer

**Fas 2: Modell optimerar bättre med feedback**

- Statisk analys visar på verkliga problem
- Performance metrics guida för förbättringar
- Kompleksitetstest visar på möjligheter att förenkla
- Det är här som kvalitet uppstår

**Fas 3: Testdokumenterar vad som lärts**

- Test fångar *slutgiltiga* förståelse
- De reflekterar *verkliga* Kantfall
- De koder *raffinerad* API-design
- De korrigerar första gången

### Evidens: ":" Det fungerar faktiskt

Här är ett verkligt exempel från DiSE-systemet

```
User: "Calculate fibonacci numbers"

[Phase 1: Exploration - 3 attempts]
  Attempt 1: Works for small inputs, explodes on large ones (no safety limit)
  Attempt 2: Adds safety limit, but inefficient recursive approach
  Attempt 3: Switches to iterative DP (PASS)

[Phase 2: Optimization - 3 iterations]
  Iteration 1: Add type hints, improve naming (Score: 1.05)
  Iteration 2: Optimize memory usage with generator (Score: 1.10)
  Iteration 3: Add input validation (Score: 1.15)

[Phase 3: Testing and Storage]
  Generated 8 unit tests covering:
    - Basic cases (n=0, n=1, n=5, n=10)
    - Edge cases (n=negative, n=100, n=None)
    - Type validation

  All tests pass ✓

  Stored in RAG with quality score: 1.15
  Available for reuse: YES
```

Den slutgiltiga koden är:

- Bra -testat (8 tester, alla passerar
- Bra-optimiserad (15% bättre än den ursprungliga versionen
- Bra-dokumenterad (med hjälp av tester och typstipplar
- Klara att dela ( i registret)

*Precis som TDD lovar* Bara genom en mer naturlig väg.

### Systemet optimerar sig själv

Här är "'", där det blir riktigt intressant. DiSE använder den här tre stadia-metoden *till sig själv.*

Den **Rekursiv systemoptimisator** har 4 nivåer

1. **Pozition 0:** Optimera ko-artefakter ( få dem att fungera , göra dem vackra
2. **Pozition 1:** Optimera arbetsflöden som använder dessa artefakter.
3. **Pozition 2:** Optimera verktygen och urvalslogiken ( du gissade det )
4. **Pozition 3:** Optimera optimeringen själv (meta!)

På varje nivå: utforska M SK1 raffinera → testa

Det här är mantran *hela vägen ner.*

## Den verkliga anledningen till att det fungerar

Här är den obehagliga sanningen. **De flesta kod är skriven av människor som inte riktigt förstår problemet ännu.**

Det är inte ett misslyckande *verkligheten.*

Benötningarna är tvetydiga . Spektionerna är ofullständiga. Trede- Parties APIs är dåligt dokumenteradeM SK3 Randfall dyker upp från ingenstans

Du kan inte designa den perfekta API: n från början eftersom **du har inte tillräckligt med information**

De tre faserna erkänner detta

1. **Fas 1:** Lär dig vad du inte vet
2. **Fas 2:** tillämpa vad du lärt dig
3. **Fas 3:** Protect vad du byggt

Genom att separera utforskning från specifikationen

- Utforska fritt (utan att testa skuldenM SK1
- Definiera självförtroendet (med kunskap om vad som är viktigtM SK1
- dela på säkert (med omfattande tester)

Detta gäller för människor som skriver kod. *också* sant för LLM som genererar kod. Och för system som optimerar sig själva.

## När TDD faktiskt verkar vettigt

I'm inte mot -TDD*för tidigt* TDD.

TDD fungerar bra när:

### 1. Problemet är bra

Om jag implementerar en känd algoritm

```python
# I know what sort() should do. Tests first? Sure!
def test_sort_empty_list():
    assert sort([]) == []

def test_sort_single_element():
    assert sort([5]) == [5]

def test_sort_multiple_elements():
    assert sort([3, 1, 2]) == [1, 2, 3]
```

### 2. Du ' löser en bug

Om jag har en regression *precis rätt*:

1. skriva en test som återskapar buggen (red)
2. Fixera koden (green)
3. Refaktor om nödvändigt (refactor)

Perfekt.

### 3. Du ' gör om den existerande koden

Om jag redan har en implementering och vill ändra dess struktur (niet beteendeM SK1 tester är nödvändiga *före* Jag börjar.

Men att "'" är inte Fasen "1.", That 's ' , Fasen 4: Maintenance , .

## Den ärliga sanningen

Det här är hur jag faktiskt jobbar. *mest* utvecklare faktiskt arbetar, till och med de som hävdar att göra strikta TDD

För kreativiteten är rörig.

Du kan inte specifikera dig själv ur okunnighet.

**Man måste bygga upp saken för att förstå den.**

Så jag bygger den (Phasen 1), raffinerar den ♫ (Phase ♫2), ♫ sen låser jag ner den

I den ordningen

Och du vet vad

*Precis som TDD lovar*

Jag kom dit genom en annan väg, den som respekterar hur kreativt arbete faktiskt sker.

---


**Vad är ditt mantra för att skapa mjukvara?**

*P.SM SK1 - Om du är en TDD-purister och detta läget fick dig att lyfta ögonbrynen, så är det bra. , bra.*