कैसे मैं सॉफ्टवेयर बनाता हूँ
क्यों मैं पिछले परीक्षाएँ लिखता हूँ-, और क्यों कि यह नहीं है क्या आप समझते हैं कि इसका मतलब
विवादास्पद लेन-देन परीक्षण-प्रचालित विकास एक शानदार अभ्यास है जो बहुत से रचनात्मक कार्य के लिए गलत समस्या को हल करता है
निर्माण सॉफ्टवेयर के तीन चरण
यह है कैसे मैं सॉफ्टवेयर बनाता हूँ
यह काम करें
इस क्रम में
इसलिए नहीं, क्योंकि मैं नहीं हूँ यह कैसे रचनात्मक कार्य वास्तव में होता है जब आप एक समस्या जगह खोज रहे हैं, आप नहीं कर सकते
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 वास्तव में Docs दावा की तरह काम करता है
- क्या मैं भी इस समस्या को मेरे उपकरणों के साथ हल कर सकता हूँ
- क्या मतलब है "correct
- क्या यह दो घंटे की समस्या है या एक दो सप्ताह की समस्या
यह आविष्कार है।
और आप जानते हैं जो जॉज को मारता है
क्यों अभी तक कोई परीक्षण नहीं है
क्योंकि आकार अभी भी तरल है
कल्पना कीजिए, आप एक शिल्पकार हैं. आप संगमर्मर का एक ब्लॉक और एक अस्पष्ट विचार रखते हैं.
टीडीडी कहता हैमुश्क0, मुश्क1, तुम उस संगमरमरमर को छूने से पहले यह लिख लो कि एक पक्षी किस तरह दिखता है, मुस्क3, इसकी पंख लम्बाई को परिभाषित करें, मुशक4, हर पंख की कोण को निर्दिष्ट करें,मुश्का5, अब उन विनिर्देशों के अनुसार काढ़ें
यह नहीं कि पक्षियों को कैसे गढ़ा जाता है
वास्तविक मूर्तिकार फ़ॉर्म को rough out पहले वे नक्काशी करते हैं। वे नक्शे बनाते हैं।
कोड एक ही है
चरण में 1, IM SK1m लेखन:
# 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
यह कोड है निजी. यह मेरे साथ एक वार्तालाप है।
इसके लिए परीक्षण लिखना बेकार से भी बुरा है सक्रिय रूप से हानिकारक क्योंकि हर बार मैं समझता हूँ "ओह प्रतीक्षा करता है।
यह, एमएसके0, कठोर नहीं है, एम्सके1, यह,एमएसके2, नौकरशाही
तेजी से असफल होने की स्वतंत्रता
चरण 1 के बारे में है सीखने की गति
मैं एक घंटे में पांच अलग दृष्टिकोणों का प्रयास करने की जरूरत है। होना चाहिए हल किया जा रहा है
परीक्षण इस को धीमा कर रहा है. नहीं क्योंकि परीक्षण धीमी है पूर्वनिर्धारित मृत्यु है
यदि मैं समस्या को समझने से पहले परीक्षण लिखें गलत बात तब मैं गलत बात में भावनात्मक रूप से निवेश करता हूँ
तेजी से असफल होने के लिए बेहतर है
क्या "Working" चरण में मतलब है
इसका मतलब है, मैं इसे चलाता हूँ, मैं उसे कुछ इनपुट देता हूँ, यह युक्तियुक्त प्रतीत होता है कि आउटपुट उत्पन्न करता है।
यह है
कोई किनारे केस नहीं. कोई त्रुटि प्रबंधन नहीं
सिर्फ एक स्पाइक
चरण 2: यह Pretty करता है (The refinement)
ठीक है, तो अब मैं समस्या को समझता हूँ।
अब मैं गुणवत्ता के बारे में ध्यान देना शुरू कर सकता हूँ
चरण 2 जहां मैं है
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')
]
उदाहरण
// 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);
}
बेहतर नाम. टाइप एनोटेशन्स
2. स्पेक्ट के साथ मिलाएँ
अब मैं जानता हूँ क्या मैं वास्तव में निर्माण कर रहा हूँ, मैं मूल आवश्यकताओं के लिए वापस जाना और सुनिश्चित करता हूँ कि मैं समाधान दाहिना समस्या एक समस्या.
प्रायः यह अंतरों को प्रकट करता है
- वो चाहते थे कि यह नकारात्मक संख्याओं को अलग से संभालें
- "Wait
- स्पेक्ट कहता है 'double' लेकिन मुझे लगता है कि वे मतलब था ' एक कॉन्फ़िगरेशन योग्य कारकों द्वारा माप
मैं इन को ठीक करता हूँ। कभी-कभी मैं स्पेक्ट पर वापस धकेलता हूँ।
3. API सतह को पोलिश करें
यहाँ मैं के बारे में सोचता हूँ कॉलर's अनुभव
पाइथोन
# 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
)
एमएसके0
// 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();
बेहतर नामकरण
यह है नौका यहीं से अच्छा सॉफ्टवेयर आता है
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
क्यों अभी भी कोई परीक्षण नहीं
मैं यह लगातार चला रहा हूँ मेरे पास एक REPL खुला है
लेकिन मैं नहीं हूँ उन प्रयोगों को औपचारिक परीक्षण के रूप में अभी तक लिखना
क्यों मैं अभी भी खोज रहा हूँ कि क्या परीक्षण करने के लिए योग्य है
चरण में 1, मैं नहीं जानता था कि यह फ़ंक्शन भी मौजूद है या नहीं
- "\Oh,\स्केल फ़ैक्टर ' negative नहीं हो सकता है
- "यदि सूची खाली है तो हमें खाली लौटाना चाहिए
- "हम गैर को संभालने की जरूरत है
ये अंतर्दृष्टि पुनरावलोकन से उत्पन्न होना वे”'”अभिमुख स्पष्ट नहीं हैं।
यदि I'd चरण में लिखित परीक्षणों को लिखा है 1, I 'd अब उन्हें पुनः लिखना होगा बाद मैंने क्रियान्वयन को संशोधित किया है
चरण 3: परीक्षणों के साथ इसे बंद करें
ठीक है
कोड साफ है
अब मैं परीक्षण लिखता हूँ। 0Testslotsoftests1As-close-to-full-coverage-as-possible tests.
अब क्यों?
क्योंकि परीक्षण एक साझा तंत्र है
वे अब मेरे लिए नहीं हैं. मैं पहले से ही इस कोड को गहराई से समझता हूँ.
परीक्षण के लिए हैं
- Future Me जो तीन महीनों में सब कुछ भूलेगा
- मेरी टीमmates (जो इस कोड को विश्वास करने के लिए काम करता है
- आईसी पाइपलाइन (which needs to prevent regressions
- भावी प्रबंधक (जिसको इस को सुरक्षित रूप से फिर से संशोधित करने की जरूरत है
परीक्षण हैं प्रस्तुतिकरण परत मेरे कार्यान्वयन के लिए
वे दस्तावेज़
- यह कोड क्या करता है
- क्या इनपुट वैध हैं
- क्या आउटपुट की आशा है
- क्या किनारे के मामले I' मैंने विचार किया है
- क्या अनुमान मैं करता हूँ I'
पूरा कवरेज, कोई समझौते नहीं
चरण में 3, मैं परीक्षण के लिए कड़ी कोशिश करता हूँ
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]
परीक्षण नहीं है'न झुठलाते हैं. वे कर सकते हैं 'न बहकाते हैं. यदि व्यवहार बदलता है, तो परीक्षण टूट जाता है
That's निष्पादनीय दस्तावेज़ कि क्या परीक्षण मूल्यवान करता है '
साझेदारी सीमा
यहाँ महत्वपूर्ण बिंदु है चरण 3 किसी अन्य को कोड को छूने से पहले होता है
मैं बिना परीक्षण के कोड साझा नहीं करता
लेकिन मैं भी नहीं लिखता Tests पहले कोड साझा करने के लिए तैयार है
चरण हैं
- निजी अन्वेषण (just me
- निजी परिष्करण अभी भी कोई परीक्षण नहीं है
- सार्वजनिक साझेदारी कोड समीक्षा
यह मेरे दोनों सृजनात्मकता की रक्षा करता है और मेरी टीम के साथियों
क्यों यह सृजनशीलता को सुरक्षित करता है
टीडीडी समर्थक कहते हैं "tests give you confidence to refactor
सही है, लेकिन सिर्फ अगर आप पहले से ही जानते हैं कि आप क्या बना रहे हैं
जब I'm चरण में 1, मैं नहीं है, ' मुझे सब कुछ फेंकने के लिए अनुमति की जरूरत है
परीक्षण मनोवैज्ञानिक ऋण पैदा करता है
चरण 3, तक परीक्षणों को टालने के द्वारा मैं चरण | 1 | और |2 | रखता हूँ मनोवैज्ञानिक रूप से सस्ता
मैं कर सकता हूँ
- जंगली विचारों की कोशिश करें
- पूर्ण दृष्टिकोण फेंकें
- डिज़ाइन को रेडिकल रूप से बदलें
- समस्या का पता लगाएँ I'm वास्तव में हल करना
सब बिना अपराध के "but मैं उन सभी परीक्षणों को लिखा है
सृजनशीलता इस प्रकार कार्य करती है
You sketch loosely first. You don't start with the details
यह कैसे Agile और XP के साथ फिट करता है (और जहाँ यह विभेद करता है
कुछ के बारे में स्पष्ट होना चाहिए यह नहीं है "test बाद के विकास
यह है विकास के दौरान परीक्षण
के समय जब इकाई परीक्षण जोड़ने के लिए महत्वपूर्ण है
एक्सपी अभ्यास जो मैं रखता हूँ
एक्सटेर्म प्रोग्रामिंग में निम्नलिखित उत्कृष्ट कार्यकलाप हैं
निरंतर एकीकरण
- सभी विशेषताओं को मिलाने से पहले आईसी के माध्यम से चला जाता है
- मुख्य में प्रत्येक कमिट पर स्वचालित परीक्षण चलाता है
- कोई टूटी इमारत सहन नहीं की जाती
युग्म प्रोग्रामिंग / कोड समीक्षा
- चरण 3 कोड को साझा करने से पहले समीक्षा की जाती है
- परीक्षण समीक्षा योग्य वास्तु का हिस्सा है
- सहयोगात्मक सुधार डिजाइन को बेहतर बनाता है
सरल डिजाइन
- चरण 2 है सभी के बारे में सरलीकरण
- क्या आप नहीं चाहते मिटाएँ
- इसे यथासंभव सरल बनाओ, अधिक सरल नहीं
रीफेक्टरिंग
- चरण 2 रीफेक्टरिंग समय समर्पित है
- कोड साफ करें पहले बंद करना
- परीक्षण रीफॅक्टरिंग को बचाते हैं (अंतिम चरण में 3+)
जहां मैं कठोर TDD से विभेद करता हूँ
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 | Three -Phase |-----|-------------| परीक्षण अंतरफलक को परिभाषित करता है | लालM SK1हरित-रिफेक्टर चक्र | | | खोजें |- | परिष्कृत करें | МSK5 | लॉक प्रगति क्रियान्वयन से पहले लिखा गया परीक्षण भागीदारी | सभी के लिए पहले परीक्षण करें |MicroM SK1साइकिलें (minutes) |MacroMSC5phases
समय महत्वपूर्ण है
यह महत्वपूर्ण अंतर्दृष्टि है यह नहीं है "tests last
गलत समयबद्धता (अधिक जल्दी
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
सही समय निर्धारण (Phase
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
समान गुणवत्ता परिणाम
यह एजील है
एजिल कहते हैं एक योजना के अनुसरण पर परिवर्तन का उत्तर दें
TDD अपनी योजना का अपना रूप बन सकता है
मेरा दृष्टिकोण परिवर्तन को अपनाता है
- चरण 1: तेजी से परिवर्तन करें, सही समाधान खोजें
- चरण 2: जानबूझकर परिवर्तन करें, elegance की ओर परिष्कृत
- चरण 3: सावधानी से परिवर्तन करें, जो काम करता है उसे सुरक्षित रखें
यह है अधिक कठोर TDD के बजाय गतिशील
विपरीत दृष्टिकोणों: A C# उदाहरण
कठोर टीडीडी दृष्टिकोण
// 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 }));
}
ध्यान दें churn? डिजाइन विकसित होने के साथ तीन परीक्षण पुनःलिखित
तीन-Phase Approach
// 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);
}
}
एक सेट के परीक्षण. एक बार लिखा गया
एजील मैनिफ़ेस्टो कनेक्शन
मानों को याद रखें
व्यापक दस्तावेज़ पर कार्य करने वाला सॉफ्टवेयर
- चरण 1 कार्यशील सॉफ्टवेयर को प्राप्त करता है तेजी से
- चरण 3 परीक्षण व्यापक दस्तावेज़ बनाता है
"एक योजना के अनुसरण पर परिवर्तन का उत्तर देना
- चरण 1-2 परिवर्तन को ग्रहण करें
- अंतिम डिजाइन में चरण 3 लॉक
प्रक्रियाओं और उपकरणों के ऊपर व्यक्तिगत और परस्पर क्रियाएँ
- टीडीडी सिद्धांत को अच्छे निर्णय से ऊपर नहीं रखना चाहिए
- जब यह मदद करता है सहकारिता करें
संविदा समझौते पर ग्राहक सहयोग
- चरण 2 स्पेक्ट के साथ मिलाता है बाद समस्या को समझना
- क्या वे विनिर्दिष्ट करने के बजाय उन्हें क्या की जरूरत प्रदान करना बेहतर है
क्यों यह बेकार चूर्ण को कम करता है
गन्दे रहस्य कार्यान्वयन से पहले लिखे गए अधिकांश परीक्षणों को पुनः लिखा या मिटाया जाता है
क्यों
- आपने आवश्यकताओं को गलत समझा है
- आप अभी तक edge केस नहीं जानते थे
- आप एक बेहतर API डिजाइन का पता चला
- आप इस विशेषता को महसूस किया था कि ' बिलकुल आवश्यक नहीं है
प्रत्येक परीक्षण आप चरण में लिखते हैं 1 शायद प्रयास बर्बाद है
लिखना अच्छा एक जब आप वास्तव में जानते हैं कि आप क्या बना रहे है
टीडीडी की प्रतिज्ञा और एमएसके0 वास्तविकता
टीडीडी वायदा करता है Tests drive your design ! They help you discover good APIs
वास्तविकता मैं एक API के लिए परीक्षणों को लिखा था मुझे लगता है कि तर्कसंगत है
यह design नहीं है thrashing
मेरा दृष्टिकोण कार्यान्वयन के माध्यम से डिजाइन
अंतिम परिणाम एक ही है
क्यों यह अभी भी अनुशासित सॉफ्टवेयर प्रदान करता है
यहाँ' यह दृष्टिकोण क्या है नहीं
- "Cowboy कोडिंग
- कोई परीक्षण नहीं
- "शिप और प्रार्थना
जब मैं चरण 3, के साथ कर रहा हूँ, मेरा कोड है
- व्यापक परीक्षण कवरेज
- किनारे केसों को संभाला गया
- साफ, पढ़ने योग्य कार्यान्वयन
- API डिजाइन साफ करें
- दस्तावेज़ (परीक्षाओं के माध्यम से
ठीक से TDD. के समान
अंतर है जब उन परीक्षणों को लिखा गया था
अनुशासन सीमा से आता है
नियम सरल है कोई कोड चरण 2 बिना चरण ≥3. छोड़ता है
मैं नहीं हूँ
- अप्रयोगित कोड कमिट करें
- परीक्षणों के बिना पीआर खोलें
- आईसी पासिंग के बिना मुख्य में मिलाएँ
- कवरेज रिपोर्टों के बिना तैनाती
अनुशासन में लिखित परीक्षाओं के आरंभिक समय में नहीं है परीक्षण के बिना कोड साझा नहीं करना.
द क्रैफ्ट मेटाफारस
यह कोई नया विचार नहीं है।
नक्काशी → परिष्कृत करें → रंगीन
चित्रकार अंतिम ब्रश स्ट्रोक से नहीं शुरू करते
वे
- नक्काशी संरचना (Phase 1)
- रंग परतें (Phase ≥2)
- वार्निशfrance. kgm संरक्षण और वर्तमान करने के लिए (Phase
रंग पहले नहीं आता है, लेकिन यह वैकल्पिक नहीं है
ड्राफ्ट → संपादित करें
लेखक अपने ड्राफ्ट के रूप में संपादन नहीं करते
वे
- ड्राफ्ट फ़ैस 1)
- संपादन निर्दयता से (Phase
- प्रकाशित करें विश्वास के साथ (Phase
शराबी लिखना।
लकड़ी → रूप | लकड़ा
Potters don't glaze before shaping
वे
- फेंकें मिट्टी (Phase 1)
- परिष्कृत करना फार्म (Phase 2)
- ग्लास और आग टिकाऊता के लिए (Phase
ग्लास बहुत महत्वपूर्ण है, लेकिन यह अंतिम होता है
यह कैसे DiSE कोडजन पाइपलाइन में मानचित्रित करता है
यहाँ यह दिलचस्प हो जाता है कार्यान्वित इस दर्शन में DiSE (निदेशित सिंथेटिक एवोल्यूशन
कोडजन पाइपलाइन स्पष्ट रूप से इन तीन चरणों को प्रतिरूपित करता है
चरण DiSE में 1
जब आप DiSE से एक समस्या को हल करने के लिए पूछते हैं
इसके बजाय जेनेरेटर (codellama या इसी तरह के ) एक स्पष्ट мандат प्राप्त करता है
"Write code that solves the specification.
Don't worry about perfection yet.
Just get it working."
सिस्टम खोज कोड उत्पन्न करता है
- सुखी मार्ग पर ध्यान केंद्रित
- न्यूनतम त्रुटि प्रबंधन
- कोई पहले से ही अनुकूलन नहीं
- सिर्फ दृष्टिकोण जाँचने के लिए पर्याप्त
फिर निष्पादक इसे चलाता है. औपचारिक इकाई परीक्षणों के साथ नहीं
अगर यह असफल है तो कोई समस्या नहीं सीखना
प्रणाली में एक 6-स्टेज अनुकूलन वृद्धि है
- एक तेजी से मॉडल के साथ प्रयास करें (low temperature)
- उच्च सर्जनात्मकता के साथ फिर से कोशिश करें (ऊँचे तापमानM SK1
- एक अधिक शक्तिशाली मॉडल में भागें
- त्रुटियों को समझने के लिए डिबग लॉगिंग जोड़ें
- शक्तिशाली मॉडल को पूरा संदर्भ दें
- अंतिम उपाय के रूप में "god
यह है ठीक से चरण 1. सिस्टम समाधान स्थान का अन्वेषण कर रहा है
इस चरण के दौरान कोई परीक्षण नहीं लिखा जाता है कोड जनन प्रक्रिया के लिए निजी है
चरण DiSE में 2
एक बार कोड मूल निष्पादन को पार करता है अनुकूलन
यह परिष्कृत चरण है
कार्यान्वयन को साफ करता है
- डिबग लॉगिंग को हटाता है जो असफलता के दौरान जोड़ा गया था
- अति जटिल कोड को सरल करता है
- नामकरण और संरचना में सुधार
स्थिर विश्लेषण चलाता है
- flake8 (style checking) - pylint (code quality) - mypy (type checking) - black (formatting) - radon (complexity analysis)पुनरावर्ती रूप से अनुकूलित करता है डिफ़ॉल्ट द्वारा (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
यह है ठीक से चरण 2. कोड अभी भी निजी है.
- अच्छे नाम
- टाइप संकेत
- स्वच्छ संरचना
- कम जटिलता
- बेहतर निष्पादन
आकार अब तरल नहीं है। अच्छा.
चरण DiSE में 3
सिर्फ बाद अनुकूलन DiSE उत्पन्न करता है और चलाता है औपचारिक इकाई परीक्षण
यहाँ-'-अत्यावश्यक भाग है-:-परीक्षाओं से उत्पन्न किए जाते हैं परिष्कृत विनिर्देशन और कार्यान्वयनआरंभिक खोज नहीं
# 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)
"""
)
परीक्षण कवर
- विनिर्दिष्टीकरण उदाहरण (शुद्धता
- चरण 2 के दौरान किनारे के मामलों का पता चला
- रीफ़िनमेंट के दौरान जोड़ा गया त्रुटि प्रबंधन
- मापन किए गए निष्पादन लक्षण
तब, केवल यदि परीक्षण पास होकोड है
- में भंडारित आरएजी स्मृति के साथ embeddings
- जोड़ा गया नोड रजिस्ट्री एक निष्पादनीय वस्तु के रूप में (
- के लिए उपलब्ध किया गया पुनः उपयोग भावी कार्यप्रवाहों में
- के साथ ट्रैक किया गया गुणवत्ता अंक और निष्पादन माप
यह साझेदारी चरण है कोड अब सार्वजनिक है (प्रणाली के लिए | ). | यह व्यापक परीक्षणों से युक्त है
एक कोड जनन प्रणाली में यह क्यों काम करता है
तीन '-' चरण दृष्टिकोण है अनिवार्य के लिए AI -driven कोड बनाने के कारण
चरण 1: मॉडलों में समस्या को पहले से नहीं समझते
- उन्हें समाधान स्थान खोजने की जरूरत है
- आरंभिक प्रयास अक्सर रोचक तरीके से असफल होते हैं
- असफलता बेहतर प्रयासों के लिए सूचना प्रदान करती है
- समयपूर्व परीक्षण समयपूर्व विनिर्दिष्टीकरण को बाध्य करेगा
चरण 2: मॉडल फीडबैक के साथ बेहतर अनुकूलन
- स्थिर विश्लेषण वास्तविक समस्याओं को प्रकट करता है
- निष्पादन मापन मार्गदर्शन सुधार
- जटिलता प्राप्तियों में सरलीकरण के अवसरों पर प्रकाश डाला गया है
- यहाँ पर गुणवत्ता पैदा होती है
चरण 3: परीक्षण जो सीखा गया था उसे दस्तावेज़ित करता है
- परीक्षण अभिग्रहण अंतिम समझ
- वे प्रतिबिंबित वास्तविक किनारा केस
- वे एनकोड परिष्कृत API डिजाइन
- वे पहली बार सही कर रहे हैं
प्रमाण-एमएसके0 यह वास्तव में काम करता है
यहाँ-' DiSE प्रणाली से एक वास्तविक उदाहरण है
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
अंतिम कोड है:
- अच्छी तरह से-tested (8tests,सभी पास)
- अच्छी तरह से-अनुसंयुक्त (15% आरंभिक संस्करण से बेहतर
- अच्छी तरह से documented (tests and type hints के माध्यम से
- रजिस्ट्री में साझा करने के लिए तैयार (
ठीक तरह से टीडीडी वादा करता है सिर्फ एक अधिक प्राकृतिक मार्ग के माध्यम से
मेटा0Level1The System Optimizes Itself
यहाँ यह वास्तव में दिलचस्प हो जाता है-' जहां यह है, : DiSE इस तीन चरण दृष्टिकोण लागू करता है खुद को
पुनरावर्ती सिस्टम ऑप्टिमाइजर स्तर है 4
- स्तर 0: कोड अवयवों को अनुकूलित करें
- स्तर 1: उन वस्तुओं का उपयोग करने वाले कार्यप्रवाहों को अनुकूलित करें
- स्तर 2: उपकरणों और चयन तर्क को अनुकूलित करें
- स्तर 3: अनुकूलक को स्वयं अनुकूलित करें (meta!)
हर स्तर पर : खोजें → परिष्कृत करें S→ परीक्षण M.
यह मंत्र है सब से नीचे
वास्तविक कारण यह काम करता है
यहाँ inconvenient truth है अधिकांश कोड उन लोगों द्वारा लिखा जाता है जो समस्या को अभी तक पूरी तरह नहीं समझते
यह एक असफलता नहीं है वास्तविकता
आवश्यकताएं अस्पष्ट हैं
आप ''' सही API आरंभ में डिजाइन नहीं कर सकते क्योंकि आपके पास पर्याप्त जानकारी नहीं है
तीन चरण इस को स्वीकार करते हैं
- चरण 1: आप क्या नहीं जानते सीखें
- चरण 2: जो आप सीखे हैं उसे लागू करें
- चरण 3: protect what you built
विनिर्देश से खोज को अलग करके मैं कर सकता हूँ
- परीक्षण ऋण के बिना मुक्त रूप से खोजें
- विश्वसनीय रूप से परिभाषित करें
- व्यापक परीक्षणों के साथ सुरक्षित साझा करें
यह कूट लिखने वाले मनुष्यों के लिए सच है भी कोड उत्पन्न करने वाले एलएलएम के लिए सही है
जब TDD वास्तव में समझ आता है
प्रतिरोधी नहीं हैअगली TDD.
TDD बहुत अच्छा काम करता है जब
समस्या अच्छी है
यदि मैं एक ज्ञात एल्गोरिथ्म को लागू करता हूँ, तो (सॉर्टिंग,पैर्सिंग
# 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]
आप एक बग को ठीक कर रहे हैं
अगर मैं एक रीग्रेसन, TDD है ठीक:
- एक परीक्षण लिखें जो बग को दोहराता है
- कोड को निश्चित करें (green)
- यदि आवश्यक हो तो रीफेक्टर (refactor)
पूर्ण
3. You're मौजूदा कोड को फिर से बदल रहा है
अगर मैं पहले से ही एक कार्यान्वयन है और अपने ढांचे को बदलना चाहते हैं (not behavior), परीक्षण अनिवार्य हैं पहले मैं शुरू करता हूँ
लेकिन यह चरण नहीं है।
सच्चे सत्य
यह है कैसे मैं वास्तव में काम करता हूँ अधिकतर डेवलपर्स वास्तव में काम करते हैं
क्योंकि सृजनशीलता अव्यवस्थित है
आप अज्ञान से स्वयं विनिर्दिष्ट नहीं कर सकते
You have to build the thing to understand the thing
तो मैं इसे बनाता हूँ।
इस क्रम में
और आप जानते हैं क्या
जैसे टीडीडी वादा करता है
मैं सिर्फ एक अलग रास्ते से वहाँ पहुँचा था, जो कि कैसे रचनात्मक काम वास्तव में होता है सम्मान करता है
क्या है आपका सॉफ्टवेयर निर्माण मन्त्र
यदि आप टीडीडी पुराणवादी हैं और इस पोस्ट ने आपको एक眉 उठाया है, तो यह अच्छा है।