2009-04-27 15 views
13

वैसे मैं थोड़ी देर के लिए इस बारे में सोच रहा हूं, जब से मुझे टीडीडी से पेश किया गया था। "हैलो वर्ल्ड" एप्लिकेशन बनाने का सबसे अच्छा तरीका कौन सा होगा? जो टेस्ट संचालित विकास का उपयोग कर कंसोल पर "हैलो वर्ल्ड" प्रिंट करेगा।"हैलो वर्ल्ड" - टीडीडी रास्ता?

मेरे टेस्ट कैसा दिखेंगे? और किस वर्ग के आसपास?

अनुरोध: नहीं "विकिपीडिया की तरह" लिंक क्या TDD है, मैं TDD से परिचित हूँ। इस बारे में सिर्फ उत्सुक है कि इसे कैसे सुलझाया जा सकता है।

+19

मैं अंदर रो रहा हूँ। और बाहर पर। – TheTXI

+4

मुझे उम्मीद है कि आप यह नहीं पूछ रहे हैं ताकि आप किसी ऐसे व्यक्ति को टीडीडी प्रदर्शित करने के उत्तर का उपयोग कर सकें जो टीडीडी को समझ में नहीं आता है। मुझे पूरा यकीन है कि हालांकि आप जो अच्छा जवाब प्राप्त कर सकते हैं, वह टीडीडी को विचलित कर देगा और लक्षित दर्शकों को लगता है कि टीडीडी सरल चीजों को कठिन बनाने का एक तरीका है। –

+0

समस्या यह है कि "हैलो वर्ल्ड" टीडीडी के साथ उपयोग करने के लिए एक भयानक उदाहरण है। आपको वास्तव में कुछ ऐसा चाहिए जो परिवर्तनीय इनपुट के आधार पर परिवर्तनीय आउटपुट उत्पन्न करता हो। –

उत्तर

20

आपको इंटरफ़ेस के पीछे कंसोल को छिपाने की आवश्यकता है।(यह उपयोगी हो करने के लिए माना जा सकता है वैसे भी)

अधिक उपयोगी ;-)

कुछ करने के लिए एक टेस्ट

[TestMethod] 
public void HelloWorld_WritesHelloWorldToConsole() 
{ 
    // Arrange 
    IConsole consoleMock = MockRepository.CreateMock<IConsole>(); 

    // primitive injection of the console 
    Program.Console = consoleMock; 

    // Act 
    Program.HelloWorld(); 

    // Assert 
    consoleMock.AssertWasCalled(x => x.WriteLine("Hello World")); 
} 

लिखें कार्यक्रम

लिखें
public static class Program 
{ 
    public static IConsole Console { get; set; } 

    // method that does the "logic" 
    public static void HelloWorld() 
    { 
    Console.WriteLine("Hello World"); 
    } 

    // setup real environment 
    public static void Main() 
    { 
    Console = new RealConsoleImplementation(); 
    HelloWorld(); 
    } 
} 

Refactor

+1

मैं बस System.IO.TextWriter इंजेक्ट और नकल करता हूं, जो 'System.Console.Out' द्वारा लागू एक सार प्रकार है। –

+1

इस तरह से निर्भर करता है कि 'आईसीओनसोल' और 'रियलकंसोल इम्प्लिमेंटेशन' लिखने की कोई आवश्यकता नहीं है। मैं इंटरफेस के खिलाफ लागू करना पसंद करता हूं। यदि कोई नहीं है, तो मैं कभी-कभी खुद को लिखता हूं, जितना छोटा मुझे चाहिए। यदि आपको केवल कुछ सरल तरीकों की आवश्यकता है, तो बड़े, सामान्य उद्देश्य इंटरफ़ेस का उपयोग क्यों करें? और सार आधार कक्षाओं में तर्क शामिल हैं। कॉलर को वास्तव में परवाह नहीं करना चाहिए कि "WriteLine" को कार्यान्वित कौन कर रहा है। –

+0

क्षमा, 'IConsole' कहां परिभाषित किया गया है? क्या यह एक नेट फ्रेमवर्क क्लास है जिसे मैं याद कर रहा हूं? –

0

मैं कुछ इस तरह लगता है:

using NUnit.Framework; 
using System.Diagnostics; 

[TestFixture] 
public class MyTestClass { 
    [Test] 
    public void SayHello() { 
     string greet = "Hello World!"; 
     Debug.WriteLine(greet); 
     Assert.AreEqual("Hello World!", greet); 
    } 
} 
+0

उत्तर के लिए धन्यवाद। लेकिन क्या होगा यदि कक्षाएं और परीक्षण अलग थे? और मैं स्ट्रिंग समानता परीक्षण से परे जाना चाहता हूं? – abhilash

+0

आप वास्तव में क्या हासिल करना चाहते हैं? –

5

खैर ... मैं हैलो दुनिया की एक TDD संस्करण नहीं देखा है। लेकिन, एक समान सरल समस्या को देखने के लिए जिसे टीडीडी और प्रबंधन में दिमाग में देखा गया है, आप Enterprise FizzBuzz (code) पर एक नज़र डाल सकते हैं। कम से कम यह आपको उच्च-इंजीनियरिंग के स्तर को देखने की अनुमति देगा जो आप संभवतः एक हैलो दुनिया में प्राप्त कर सकते हैं।

+0

धन्यवाद ascalonx, ठीक है, इसके बारे में सोचते हुए, मुझे अभी तक हैलो वर्ल्ड का टीडीडी संस्करण नहीं मिला है। – abhilash

+0

वह ब्लॉग अब ऑफलाइन है लेकिन गिटूब पर एक [फिजबज़ एंटरप्राइज़ संस्करण] (https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition/blob/master/src/test/java/FizzBuzzTest.java) है। ओह। हैलो वर्ल्ड के लिए –

5

प्रस्तुतकर्ता-दृश्य? (मॉडल अत्यंत आवश्यक होता प्रतीत नहीं होता)

देखें एक वर्ग है कि कंसोल के लिए निर्गम (सरल एकल लाइन विधि)

प्रस्तुतकर्ता इंटरफ़ेस view.ShowText कॉल ("हैलो दुनिया" है गुजरता होगा), आप स्टब व्यू प्रदान करके इसका परीक्षण कर सकते हैं।

उत्पादकता के लिए हालांकि, मैं सिर्फ लानत कार्यक्रम :)

एक एकल परीक्षण (स्यूडोकोड में) पर्याप्त होना चाहिए लिखना चाहते हैं:

IView view = Stub<IView>(); 
Expect(view.ShowText("Hello World")); 

Presenter p = new Presenter(view); 
p.Show(); 

Assert.IsTrue(view.MethodsCalled); 
+0

एमवीपी? Overkill! – Gishu

+0

अरे, वह चाहता था कि यह इकाई परीक्षण करे, क्यों नहीं चलते? ;) – Lennaert

+0

क्योंकि सभी तरह से टीडीडी एक उपयोगी तकनीक के बजाय अकादमिक अभ्यास की तरह दिखता है। रुको, मुझे विश्वास नहीं है कि मैं वास्तव में "हैलो वर्ल्ड, टीडीडी वे" पर शैक्षिक मूल्य पर बहस कर रहा हूं –

2

जावा आप ले सकता है में ("redirect") System.out स्ट्रीम और इसकी सामग्री पढ़ें। मुझे यकीन है कि सी # में भी किया जा सकता है। यह केवल जावा में कोड की कुछ लाइनें है, तो मुझे यकीन है कि यह बहुत अधिक नहीं होगा सी #

+1

आप आउटपुट स्ट्रीम को किसी भी टेक्स्टवाइटर पर सेट कर सकते हैं ताकि निम्नलिखित कार्य करना चाहिए। टेक्स्टवाइटर आउटपुट = नया स्ट्रिंगवाइटर(); कंसोल.SetOut (आउटपुट); // यहां अपनी हैलो वर्ल्ड विधि को कॉल करें जोर दें ("हैलो वर्ल्ड", output.ToString()); –

+0

धन्यवाद। यह एक परीक्षण स्थिरता का अधिक नहीं है;) – krosenvold

4

छद्म कोड में हूँ:

  • कुछ है कि एक धारा को स्वीकार करता है की एक नकली बनाएँ।
  • कुछ प्रकार के निर्भरता इंजेक्शन (एक कन्स्ट्रक्टर तर्क की तरह) के माध्यम से इस मॉक पर नरकॉर्ल्ड को आमंत्रित करें।
  • सत्यापित करें कि "हैलो वर्ल्ड" स्ट्रिंग आपके नकली में स्ट्रीम की गई थी।

उत्पादन कोड में, आप नकली के बजाय प्रॉम्प्ट का उपयोग करते हैं।

सामान्य नि:

  • कैसे घटक अन्य सामान है, यह न सिर्फ तुम कैसे साथ सूचना का आदान साथ सूचना का आदान में अपनी सफलता मापदंड परिभाषित करें। टीडीडी बाहरी व्यवहार पर केंद्रित है।
  • घटनाओं की श्रृंखला को संभालने के लिए पर्यावरण (मैक्स) सेट अप करें।
  • इसे चलाएं।
  • सत्यापित करें।
2

एक बहुत ही रोचक सवाल। मैं एक बड़ा टीडीडी उपयोगकर्ता नहीं हूं, लेकिन मैं कुछ विचार फेंक दूंगा। ,

public static void Main() 
{ 
    Console.WriteLine("Hello World"); 
} 

अब के बाद से मैं इस परीक्षण सीधे मैं लेखन कार्य को तोड़ने चाहते हैं के किसी भी अच्छा तरीका है के बारे में सोच नहीं सकते हैं:

मैं मान लेंगे कि आवेदन आप परीक्षण करना चाहते हैं कि यह एक इंटरफेस में।

public interface IOutputWriter 
{ 
    void WriteLine(string line); 
} 

public class ConsoleWriter : IOutputWriter 
{ 
    public void WriteLine(string line) 
    { 
     Console.WriteLine(line); 
    } 
} 

और यह

public static void Main() 
{ 
    IOutputWriter consoleOut = new ConsoleWriter(); 
    WriteHelloWorldToOutput(consoleOut); 
} 

public static void WriteHelloWorldToOutput(IOutputWriter output) 
{ 
    output.WriteLine("Hello World"); 
} 

अब आप विधि है कि आप बात पर जोर देना है कि WriteLine विधि के साथ कहा जाता है अपनी पसंद का मजाक ढांचे का उपयोग करने की अनुमति देता करने के लिए एक इंजेक्शन बिंदु है की तरह नीचे आवेदन को तोड़ने "हैलो वर्ल्ड" पैरामीटर।

समस्याएं है कि मैं अनसुलझा छोड़ दिया है (और मैं इनपुट में रुचि होगी):

  1. कैसे ConsoleWriter वर्ग परीक्षण करने के लिए, मैं तुम्हें अब भी कुछ यूआई परीक्षण ढांचे की जरूरत है इस लक्ष्य को हासिल करने के लिए लगता है, और अगर आप तब भी पूरी समस्या को म्यूट में रखते थे ...

  2. मुख्य विधि का परीक्षण करना।

  3. मैं क्यों लगता है कि मैं कोड के सात लाइनों, केवल एक जिनमें से वास्तव में परीक्षण किया जाता है में अपरीक्षित कोड की एक पंक्ति को बदलकर कुछ हासिल कर लिया है (हालांकि मुझे लगता है कि कवरेज बढ़ गई है)

2

मुझे वास्तव में इस सवाल पर ऑब्जेक्ट करना है! सभी पद्धतियों में उनकी जगह है, और टीडीडी बहुत से स्थानों में अच्छा है। लेकिन यूजर इंटरफेस पहली जगह है जिसे मैं वास्तव में टीडीडी से पीछे छोड़ देता हूं। यह, मेरी विनम्र राय में एमवीसी डिजाइन पैटर्न के सर्वोत्तम औचित्य में से एक है: अपने मॉडल और नियंत्रक प्रोग्रामेटिक रूप से हेक का परीक्षण करें; अपने विचार का निरीक्षण करें। आप किस बारे में बात कर रहे हैं वह "हैलो वर्ल्ड" डेटा को कड़ी-कोडिंग कर रहा है और परीक्षण करता है कि यह इसे कंसोल पर बनाता है। इस परीक्षा को एक ही स्रोत भाषा में करने के लिए, आपको कंसोल ऑब्जेक्ट को डमी करना होगा, जो एकमात्र ऑब्जेक्ट है जो पर कुछ भी करता है।

वैकल्पिक रूप से, आप स्क्रिप्ट बैश में अपने परीक्षण कर सकते हैं:

echo `java HelloWorldProgram`|grep -c "^Hello World$" 

मुश्किल थोड़ा एक JUnit टेस्ट स्वीट में जोड़ने के लिए है, लेकिन कुछ मुझसे कहता है कि योजना कभी नहीं था ....

1

मैं डेविड बर्गर से सहमत हैं; इंटरफ़ेस को अलग करें, और मॉडल का परीक्षण करें। ऐसा लगता है कि इस मामले में "मॉडल" एक साधारण वर्ग है जो "हैलो, दुनिया!" देता है।परीक्षण (जावा में) इस प्रकार दिखाई देगा:

Greeter greeter = new Greeter(); 
    assertEquals("Hello World!", greeter.greet()); 

मैं http://ziroby.wordpress.com/2010/04/18/tdd_hello_world/ पर Hello World TDD शैली के हल के लिए एक ऊपर लिखने बना लिया है।

3

मान लें कि आप इकाई परीक्षण जानते हैं, और यह समझते हुए कि आप "लाल हरे रंग की रिफैक्टर प्रक्रिया" को समझते हैं (क्योंकि आपने कहा था कि आप टीडीडी से परिचित हैं) बीमार जल्दी से एक सामान्य विचित्र विचार प्रक्रिया की व्याख्या करता है।

यदि आप किसी विशेष इकाई की समस्या के बारे में सोचते हैं और अन्य सभी जुड़ी चीजों को निर्भरताओं के संदर्भ में सोचा जाना चाहिए तो आपका टीडीडी जीवन बहुत आसान हो जाएगा। यहां एक नमूना

परिदृश्य: - मैं चाहता हूं कि मेरा प्रोग्राम कंसोल पर हैलो वर्ल्ड प्रदर्शित करे।

TDD विचार प्रक्रिया: -

"मुझे लगता है मेरा कार्यक्रम तो यह करने के लिए मेरा संदेश गुजर सांत्वना कार्यक्रम फोन और उसके बाद मैं अपने सांत्वना कार्यक्रम स्क्रीन पर प्रदर्शित करने के लिए उम्मीद प्रदर्शन शुरू हो जाएगा"

" इसलिए मुझे यह जांचने की ज़रूरत है कि जब मैं अपना प्रोग्राम चलाता हूं, तो उसे कंसोल प्रोग्राम "

" अब निर्भरताएं क्या हैं? हम्म मुझे पता है कि कंसोल प्रोग्राम उनमें से एक है। मुझे चिंता करने की आवश्यकता नहीं है कंसोल को स्क्रीन पर संदेश कैसे मिलेगा (आईओ डिवाइस, प्रिंटिंग और यह सब कॉल करना) मुझे बस इतना ही पता होना चाहिए कि मेरा प्रोग्राम सफलतापूर्वक कंसोल कार्यक्रम कहा जाता है। मुझे विश्वास करना होगा कि कंसोल प्रोग्राम काम करता है और यदि ऐसा नहीं होता है, तो फिलहाल मैं परीक्षण के लिए ज़िम्मेदार नहीं हूं और यह सुनिश्चित करता हूं कि यह काम करता है। जिस जिम्मेदारी का मैं परीक्षण करना चाहता हूं वह यह है कि जब मेरा प्रोग्राम शुरू होता है तो कंसोल प्रोग्राम को कॉल करता है। "

" लेकिन मुझे यह भी नहीं पता कि कंसोल प्रोग्राम किस कॉल को कॉल कर सकता है। अच्छी तरह से मैं System.console.Writeline (कंक्रीट कार्यान्वयन) के बारे में जानता हूं लेकिन फिर यह भविष्य में बदलावों के कारण भविष्य में बदल सकता है, तो मैं क्या करूँ? "

" ठीक है, मैं इंटरफ़ेस (या अमूर्तता) पर निर्भर करता हूं ठोस कार्यान्वयन की तुलना में, तो मैं इंटरफ़ेस जो मैं के खिलाफ परीक्षण कर सकते हैं राज्य "

public interface Iconsole 
    { 
     void WriteToConsole(string msg); 
    } 



public class FakeConsole : Iconsole 
    { 
     public bool IsCalled = false; 

     public void WriteToConsole(string msg) 
     { 
      IsCalled = true; 
     } 
    } 

मैं IsCalled सदस्य जिसका डाल दिया है" को लागू करने के लिए एक नकली सांत्वना बना सकते हैं "में बदल जाएगा यदि whe कभी सांत्वना कार्यक्रम कहा जाता है

ठीक है, मुझे पता है कि यह एक लंबी विचार प्रक्रिया की तरह लगता है लेकिन यह भुगतान करता है। टीडी आपको कोडिंग से पहले सोचने के लिए मजबूर करता है जो शर्त है

var console = new FakeConsole(); 
    console.IsCalled = false; 
    my_program program = new my_program(console); 
    program.greet(); 

मैं सांत्वना पारित कर दिया my_program चाहते हैं ताकि my_program कंसोल का उपयोग करेगा: एर तो सोच

दिन के अंत में पहले कोडिंग, आप तो ऊपर नीचे दिए तरीक़े की तरह कुछ के साथ अपने कार्यक्रम को लागू करने की आ सकती है स्क्रीन पर हमारा संदेश लिखने के लिए।

और मेरे my_program कुछ ऐसा दिखाई देगा:

public class my_program 
    { 

     Iconsole _consol; 
     public my_program(Iconsole consol) 
     { 
      if (consol != null) 
       _consol = consol; 
     } 
     public void greet() 
     { 
      _consol.WriteToConsole("Hello world"); 
     } 
    } 

अंतिम इकाई परीक्षण तो हो जाएगा: -

[TestMethod] 
     public void myProgramShouldDisplayHelloWorldToTheConsole() 
     { 
      //arrange 

      var console = new FakeConsole(); 
      console.IsCalled = false; 
      my_program program = new my_program(console); 
      //act 
      program.greet(); 

      //assert 
      Assert.AreEqual(true, console.IsCalled, " console was not called to display the greeting"); 



     } 
संबंधित मुद्दे