Як я будую програмне забезпечення. (Українська (Ukrainian))

Як я будую програмне забезпечення.

Wednesday, 19 November 2025

//

21 minute read

Чому я пишу тести на останніх, і чому це не те, що ви думаєте це означає

**Суперечний вибір:**Тестовий розвиток - це блискуча практика, яка вирішує невірну проблему для більшості творчих робіт.

Ось що працює краще.

Три фази будівельного програмного забезпечення (насправді це працює)

Ось так я створюю програмне забезпечення.

Це просто, це ефективно, і це змушує ТДД пундиків ввічливо борознити їхні брови:

Зроби це працювати.*Зробимо її красивою.*Заблокуй його тестами.

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

У цьому порядку.*Завжди.*Не тому, що я ледачий.

Не тому, що я не ціную тестування.

Але тому, що

Ось як насправді відбувається творча робота.

Коли ви досліджуєте проблемний простір, ви ще не повністю розумієте.

  • Не тому, що я ледачий.
  • Не тому, що я не ціную тестування.
  • Але тому, що
  • Ось як насправді відбувається творча робота.

Коли ви досліджуєте проблемний простір, ви ще не повністю розумієте.

Дозвольте розповісти.

Фаза 1: запрацюйте (приватний ескіз)

Це заплутана частина.Часть, где я понятия не имею, что делаю.

Я намагаюся зрозуміти:

Чи цей API дійсно працює так, як стверджують докторини?

Чи можу я взагалі вирішити цю проблему за допомогою інструментів, які у мене є?

Що означає "правильне" навіть у цьому контексті?*Це двогодинна проблема чи двотижнева проблема?*Це винахід.

Це дослідження.

Це джаз.

# 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

І знаєте, що вбиває джаз?**Кто-то стоял над твоим плечо и говорил "Спершу напишите тест."**Чому досі немає випробувань?

Тому що*форма до сих пор жидкость.*Уявіть, що ви скульптор.

У вас є блок мармуру і туманна ідея: "Я хочу вирізати птаха."

ТДД говорить: " Перш ніж доторкнутися до мармуру, запиши, як саме виглядає птах.

Визначте його розмах крил.Вкажіть кут кожної пір'їни.

Тепер напишіть на ці специфікації."*Це... не те, як вирізали птахів (Або програмне забезпечення пишеться, як виявляється.)*Справжні скульптори

спочатку перекрий форму.Вони малюють.

Вони роблять макет.*Щоб знайти загальну форму, вони відрізають великі брили каменю.*Тільки пізніше вони уточнюють деталі.

Код такий самий.

У фазі 1 я пишу:

Цей код

рядовий.

Це розмова сама з собою.

Саме так я розумію, що таке "працездатність."

Записування для цього є гіршим, ніж марнота

активно шкідлива для здоров'я.

Тому що кожного разу, коли я розумію "очекайте, цей підхід хибний," мені також доведеться переписати тести.

Це не суворо.

Це бюрократія.

Свобода швидко зазнає невдачі

# 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')
    ]

Про фазу 1

// 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);
}

швидкість навчання.

Мені потрібно спробувати п'ять різних підходів за годину.

Мне нужно выяснить, что библиотека третьей части, которую я хотел использовать... не такая, как объявление.*Я маю зрозуміти, що проблема, яку я вирішую, це не та проблема, яку я маю вирішити.маєрешать.*Тесты уповільнюют это.

Не тому, що тестування є повільним, а тому, що

  • передчасна специфікація - це смерть.
  • Якщо я пишу тести перед тим, як зрозуміти проблему, я пишу тести для
  • неправильно.

Тогда я эмоционально инвестирована в не то, что нужно.

Тоді я захищаю неправильну річ в аналізі коду.

Краще швидко, на самоті, без тестів, щоб підтримувати і без его, щоб захистити.Що означає " праця " в фазі 1Це означає: "Я її проїхав.

Я дал ему некоторые входы.

# 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
)

Він видавався досить розумним.

// 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();

Я в 60% впевнений, що розумію цю проблему зараз."

Ось так.**Никаких мерзавых дел.**Без обробки помилок.

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

Ніякої елегантності.

*Просто шип.*Доказ концепції.

Малюнок.Фаза 2: зробити її пристойною (удосконалення)

Гаразд, тепер я розумію проблему.У мене є щось, що працює, принаймні для щасливого шляху.

Тепер я можу почати турбуватися про якість.

  • Фаза 2 - це моя фаза:
  • Очищення Меси

Приклад Python:*Приклад C#:*Краще ім'я.

Надрукувати анотації.*Документація XML.*Реалізація чистішого LINQ.

2.

Вирівняти за спектром

Тепер, коли я знаю, що я насправді будую, я повертаюся до початкових вимог і впевнюся, що я вирішую

праворуч

проблема, не тільки

апроблема.

Часто це виявляє прогалини:

"О, вони хотіли інакше впоратися з від'ємними числами."

  1. **"Стривай, тут є випадок межі, де значення може бути None vs. 0."**Специфікація каже "подвійно," але я думаю, вони мали на увазі "масштаб з конструктивним множником."
  2. **Я це виправляю.**Іноді я відходжу від специфікації: "Насправді, ми повинні зробити X замість Y."
  3. **3.**Польська поверхня API
  4. Ось тут я думаю проcaller's

досвід.**Python:**C#:

Лучше название.

  • Примітивні типові значення.
  • Настройство, которое имеет значение.
  • Простійний API, якщо потрібно.
  • Це
  • Робітник.

Ось звідки походить хороше програмне забезпечення.

Чому досі немає випробувань?

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)

О, я постоянно его проверяю.

У меня открытый фантастик.

  • Я пробую різні входи.
  • Я тренуюся всіма шляхами.
  • Але я не
  • Записуйте ці експерименти як формальні тести.

Чому?

Тому що

# 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]

Я до сих пор выявляю, что стоит проверки.

У фазі 1, я не знав, чи існує ця функція.У другій фазі я знаходжу:"О, коефіцієнт масштабу не може бути негативним.

Це перевірка."

"Якщо список порожній, ми повинні повернути порожній, а не None.""Ми повинні з приємністю ставитися до нецифрічних цінностей."

Ці розуміння

виходить з реорганізації.

Вони не є очевидними на передньому плані.

  1. **Якби я написав тести у фазі 1, я б переписав їх зараз.**Якщо я їх напишу
  2. післяЯ вдосконалив реалізацію, і вона буде правильною вперше.
  3. **Фаза 3: Заблокуйте її за допомогою тестів ( Фаза спільного використання)**Ладно, теперь он настоящий.

Код чистий.*API має сенс.*Я раскрою дела.

Я впевнений у тому, що я збудував.

Тепер я пишу тести.

Багато тестів.

У якості тестів на повну роботу.Чому зараз?

Тому що

тести - це механізм спільного використання.Вони більше не для мене.

Я вже розумію цей код тісно.

  • Я живу в ньому кілька годин або днів.
  • Тести призначено для:
  • Майбутній я
  • (который забудет все за 3 месяца)Мої однокласники(треба довіряти цьому коду працює)

Канальна лінія CI

(що має запобігти регресії)

Майбутні супровідники

(треба безпечно реорганізувати це)

Тести є тестамишар презентації

для моєї реалізації.Они документируют:

Що робить цей кодЯкі вхідні дані є коректнимиЯкі вихідні дані слід очікувати

Які найгірші справи я розглядав

Які припущення я роблю

Повна обкладинка без компромісів

  • У 3-ій фазі я йду до тестування:
  • Это сеть безопасности.
  • Тепер мої колеги з команди можуть:

Змінити цю функцію з упевненістю

  • Зрозуміти справи на краю
  • Негайно ловити регресію
  • Реорганізувати без страху

Тести як документація

  • Правильні тести є кращою документацією, ніж коментарі:*Тести не брешуть.*Вони не можуть дрейфувати.
  • Якщо поведінка змінюється, тест ламається.
  • Це

Документація програми.

  • Ось що робить тести цінними.
  • Межа спільного використання*Ось критичний момент:*Фаза 3 відбувається до того, як хтось інший торкнеться коду.
  • Я не поділяю код без тестів.

Ніколи.

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

**Но я также не пишу тесты, пока код не готов делиться.**Фази такі:

Особисте дослідження(Лише я, без тестів)

Особисте вдосконалення

(Тільки я, все одно ніяких тестів) |-----|-------------| Публічний спільний доступ (Перевірка коду, аналіз коду, всі дев'ять ярдів) Це захищає обидва мої творчі здібностіі | моя одноклассница. Чому це захищає від м'яса

Захисники ТДД кажуть, що "тести дають вам впевненість у рефакторі."

Правда!Но только если ты уже знаешь, что ты строишь.

Коли я в першій фазі, мені не потрібна впевненість для реорганізації.

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

Мне нужно разрешение, чтобы всё выбросить.

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

Аналізи створюють психологічний борг.

Як тільки я їх пишу, я не хочу їх видалити.

Навіть якщо вони випробовують неправильну річ.Аналізи до 3-ї фази я зберігаю фазу 1 і 2

психологічно дешевий.

Я можу:

  • Спробувати дикі ідеї
  • Викинути цілі підходи
  • Радикальна зміна дизайну

Відкрий мою проблемунасправдірозв' язання

Все без вины "но я написал все эти тесты..."

Ось як працює креативність.

// 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 }));
}

Ты нарисовал первым.

Ви не починаєте з деталей.

// 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);
    }
}

Як це підходить до агресивних і XP (І де вона розходиться)

Давайте прояснимо дещо:

це не "протест пізніший розвиток."

Це

  • "Проверьте, когда развиваются, но вовремя."Час
  • коли

щоб додати одиникові тести є критичними.

  • Зарано і ви визначаєте невідоме.
  • Слишком поздно, и вы добираетесь без сети безопасности.

Вправи XP, які я зберіг

  • Екстреммінг має блискучі методи, які варто застосувати:
  • Безперервне інтеграція

Кожна можливість проходить через CI перед об' єднанням

  • Автоматизована перевірка виконується при кожному внеску до головногоНе було порушено збирання з терпимістюПерегляд парної програми / коду
  • Код фази 3 перед тим, як поділитися

Тести є частиною рецензованого артефакту.

Співпрацездатне вдосконалення покращує дизайнПростий дизайн

Фаза 2 є

  • все про
  • спрощення
  • Вилучити те, що вам не потрібно
  • Зробити це якомога простішим, не простішим

Реорганізація

Фаза 2 є відведеною часом реорганізаціїОчистити коддо

блокування

**Тестування захищає реорганізацію (у фазі 3+)**У чому я відрізняюсь від стриманого TDD

ТДД каже:"Спочатку тести.

Завжди.Ред-Зелёный-Рефактор - единственный способ."

Я кажу:"Тести, когда ты знаешь, что ты проверяешь.

Екскурс-Рефа-Лок є більш природним."

Ключова відмінність:

ДзЗУПІТЬ ТРИ-СЕШАтяте визначає інтерфейс }Видлат визначає інтерфейс ♪

  • ♪ Red- Green-Refact цикл ♪ [Перетворення]
                    • .
  • спільне користування

♪ Test first for everything ♪ Test at the right time for every thing ♪

  • Д- дІ- цикли (хв- милях)} + +- fas (години)) ♪
  • Відлік є критичним
  • Ось ключове розуміння:
  • Это не "проверка последних." Это "тести, прежде чем делиться."
  • Неправильний час (зарано):

Саме час (Фаза):

Той же якісний результат.*Половина відтіку.*Це АзільAdvanced URLs: description or category

Аджіле каже:

"Поміркуй, як зміниться план."ТДД може стати власною формою плану.

Як тільки ви записуєте тести, ви психологічно зобов'язані цьому дизайну.

  • Мій підхід включає в себе зміну:
  • Фаза 1.
  • Фаза 2: зміна свідомо, покращення до елегантності
  • Фаза 3. Змініться обережно, оберігайте те, що працює

Цебільше

Швидка, ніж строга ТДД, тому що відкладає зобов'язання, поки у вас не буде інформації.

Контрастливі підходи: приклад C#

Строга підхід TDD:

Помните отрыв?

Три тестові переписи у процесі розвитку дизайну.

  1. **Прихід з трьома фазами:**Один набір тестів.
  2. **Написано одного разу.**Виправте перший раз.
  3. **Бо я знав, що будую.**Азільне маніфестне з'єднання

Запам' ятайте значення:

"Робота програмного забезпечення над всебічною документацією"

Фаза 1 потрапляє до програмного забезпечення для роботи

швидкий

  1. Фаза 3 робить перевірку всебічною документацією"Поміркую над зміною згідно плану"
  2. Зміна етапів 1- 2@ item: inlistboxЗамкнення фази 3 у кінцевому дизайні
  3. **"Інтеграти та взаємодіяти з процесами та інструментами"**Не дозволяйте догмату TDD перевищити розсудливість

Кооперувати, якщо допомагає (Фраза 2-3), досліджувати наодинці, якщо це не (Фраза 1)

"Кооперативна співпраця через контрактні переговори"

Фаза 2 вирівнює параметри

після

  1. розуміння проблемиКраще передати все, що їм потрібно, ніж вказали.
  2. Чому це зменшує непотрібний кар'єрБрудна таємниця TDD:
  3. **більшість тестів, записаних перед впровадженням, буде перезаписано або вилучено.**Чому?

Тому що:

Ви неправильно зрозуміли вимоги

Ти ще не знав, що таке крайня справа.Ви відкрили кращий дизайн APIВи зрозуміли, що функція взагалі не потрібна

Кожна спроба, яку ви пишете у фазі 1, ймовірно, марнується.

Краще писати

перший

набір тестів у фазі 3, коли ви насправді знаєте, що ви будуєте, ніж переписування під час дослідження.Обіцянка TDD проти реальностіОбіцянка ТДД:

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

"Напруження впливають на твій дизайн!

  • Вони допомагають вам відкрити хороший API!"
  • Дійсність ТДД:
  • "Я написав тести для API, я думав, має сенс.
  • Потім я вдосконалив її і зрозумів, що API був незграбним.

Тепер я переписую і тести, і код."**Це не дизайн.**Це

Бурчання.Мій підхід:

Розробка через реалізацію, а потім блокування тестами.

  1. Останній результат такий самий, добре перевірений код.
  2. Але я приїхав туди з половиною відтіку.
  3. Чому це досі дає програмне забезпечення
  4. Ось який підхід
  5. не:
  6. "Ковбойське кодування"

Без тестів*"Стривай і молися"*Коли я закінчу з 3-ю фазою мій код має:

Пробне покриттяОбробка випадків ребра

Чиста, придатна для читання реалізація

Очистити дизайн APIДокументація (через тести)

Точно то же, что и ТДД.

  1. Різниця в тому, що

    • коли
    • Эти тесты были написаны.
    • Картання походить з межі
  2. Правило просте:

    - flake8 (style checking)
    - pylint (code quality)
    - mypy (type checking)
    - black (formatting)
    - radon (complexity analysis)
    
  3. **Жоден код не залишає фази 2 без фази 3.**Я не:

    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
    

Передати неперевірений кодВідкрити PR без перевіркиОб' єднати у головне без передачі CI

  • Впорядковувати без звітів щодо покриття
  • Дисципліна не пише тести раніше.
  • Він у
  • не ділиться кодом без тестів.
  • Метафори - виріб

Це не нова ідея.Ось як творча робота завжди працювала:

Sketch → Перевищення → Варніш

Маляри не починаються з фінальних мазків пензля.*Вони:*Sketchкомпозиція (Фаза 1)

Малювати*шари (Фаза 2)*ВарнішCity in Germany

# 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)
"""
    )

для захисту і присутності (Фаза 3)

  • Варлиша не на першому місці.
  • Але це не факультативно.
  • Чернетка → Правка → Опублікувати
  • Письменники не редагують як чернетку.

Вони:Чернеткаmoodly (Fase 1)

  1. Змінити**Безжальна (Фаза 2)**Опублікувати
  2. з довір'ям (Фаза 3)**"Напиши п'яну, тверезу" - жахлива життєва порада, але чудова порада.**Глей → Форма → Глаз
  3. Гончарі не глазурують перед формуванням.**Вони:**Кинути
  4. глина (Фаза 1)Обрізати і уточнитиформа (Фаза 2)Глаз і вогонь

**для міцності (Pase 3)**Плавлення дуже важливе.

Але воно наступає останнім.

Як це зробити з коденими лініями DiSE*Ось тут стає цікаво:*реалізовано

ця філософія в системі ДіСЕ (прямій синтетичній еволюції).

  • Канальна труба з кодовим кодом явно містить ці три фази:
  • Фаза 1 в тумані: стадія дослідження
  • Коли ви просите ДіАЕ розв'язати проблему, вона не стрибає прямо до написання досконалого перевіреного коду.
  • Замість цього,

Генератор

  • (codellama або щось подібне) отримує чітке доручення:
  • Система створює застарілий код:
  • Зосереджений на щасливому шляху
  • Мінімальна обробка помилок

Не існує передчасної оптимізації

  • Лише для перевірки підходуПотімВиконавець
  • Пропусти.*Не на формальних одиницях тести просто з вхідними даними з специфікації.*Якщо ні?
  • Без проблем.Цевчитися.
  • Система має 6- ступінку адаптивної ескалації:

Спробуйте за швидкою моделлю (низька температура)

Спробувати знов з вищою креативністю (підвищення температури)

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

Переміститися на більш потужну модель

  • Додати журнал зневаджування для розуміння помилок
  • Повноцінний контекст потужної моделі
  • Використовувати модель " Божий рівень " як останній захід
  • Це

точноФаза 1.

Система вивчає простір розв'язання, вивчаючи, що працює, що швидко не працює, і пристосовується.

Ніяких тестів не написано протягом цього етапу.Код приватний до процесу створення.

Фаза 2 у DiSE: стадія ОптимізаціїПісля того, як код перейде до базової виконання, DiSE переходитиме доОптимізація.

  1. **Це фаза вдосконалення.**Система:
  2. Очищує реалізаціюВилучає журнал зневаджування, який було додано під час помилок
  3. Спростити занадто складний кодПокращує ім' я і структуру
  4. Виконує статичний аналізІтеративні оптимальні особливості

(типово ітерацій)

Цеточно

Фаза 2.

Код все ще є приватним (не у списку), але ми його поліруємо:Кращі назви

Підказки типуЧиста структура

Нижча складність

Краща швидкодіяЦя форма вже не є рідиною.

Ми знаємо, що ми будуємо.

  1. Тепер ми це робимоХорошо.
  2. Фаза 3 у діСЕ: стадія випробувань і зберігання данихТільки
  3. післяОптимізація робить DiSE створення і запуск

формальні тести одиниць.

  • Ось ключова частина: тести створюються з
  • удосконалена специфікація і впровадження
  • , не початкове дослідження.

Обкладинка тестів:*Приклади специфікації (правильність)*Виявлені випадки ребра під час фази 2

Обробка помилок, яку було додано під час уточнення

Параметри швидкодії, які було вимірено*Тоді,*лише якщо пропущено тести

Код такий:

Збережені в

Пам' ять RAG

# 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]

(з вбудовуванням)

Доданий доРеєстр вузла:

  1. (як виконуваний артефакт)
  2. Є доступним для
  3. repeat

у майбутніх роботах

Доріжка з

оцінки якості

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.