TDD में मुझे पहले टेस्ट या इंटरफ़ेस लिखना होगा?


23

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

लेकिन यह भी कहा जाता है कि " प्रोग्राम टू इंटरफ़ेस, इंप्लीमेंटेशन नहीं ", इसलिए पहले एक इंटरफ़ेस लिखें । यहीं से मेरा भ्रम शुरू होता है, अगर मैं पहले इंटरफ़ेस लिख रहा हूं तो यह दो चीजों का उल्लंघन कर रहा है

  1. कोड जो इंटरफ़ेस के लिए लिखा गया है वह परीक्षण द्वारा संचालित नहीं है

  2. यह नंगे न्यूनतम नहीं है जाहिर है मैं इसे एक साधारण वर्ग के साथ लिख सकता हूं।

क्या मुझे इंटरफ़ेस के लिए परीक्षण लिखकर भी शुरू करना चाहिए? किसी भी कार्यान्वयन के बिना मैं क्या परीक्षण करने जा रहा हूं?

अगर यह सवाल मूर्खतापूर्ण लगता है तो उसके लिए खेद है, लेकिन मैं पूरी तरह से भ्रमित हूं। हो सकता है मैं चीजों को सचमुच ले जा रहा हूं।


8
"एक इंटरफ़ेस के लिए कार्यक्रम" का अर्थ है कि आपको कोड के एक टुकड़े से अलग करने की आवश्यकता है कि यह कैसे किया जाता है। इसका शाब्दिक अर्थ interfaceहर चीज के लिए उपयोग करना नहीं है । ए classभी एक इंटरफ़ेस प्रदान करता है, क्योंकि आप privateचर में कार्यान्वयन विवरण छिपा सकते हैं ।
डोभाल

@ डोभाल, हां, आपको हर चीज के लिए एक इंटरफेस की जरूरत नहीं है, बस इसे क्या कहा जाता है contract। यह एक अमूर्त वर्ग के रूप में हो सकता है, उदाहरण के लिए, हालांकि यह एक आभासी वर्ग / तरीका नहीं होना चाहिए क्योंकि आप इसे तुरंत करने में सक्षम नहीं होना चाहिए।
trysis

2
टीडीडी कहता है, "एक परीक्षण लिखें जो विफल हो।" कुछ सख्त TDDers का कहना है कि यह "विफल" के रूप में गिना जाता है यदि आप परीक्षण को संकलित नहीं कर सकते क्योंकि जिस डेटा प्रकार पर यह संचालित होता है वह अभी तक घोषित नहीं किया गया है।
सोलोमन स्लो

जवाबों:


29

आपका पहला उल्लंघन ("इंटरफ़ेस के लिए लिखा गया कोड परीक्षण द्वारा संचालित नहीं है") मान्य नहीं है। आइए एक तुच्छ उदाहरण का उपयोग करें। मान लीजिए कि आप एक कैलकुलेटर क्लास लिख रहे हैं, और आप एक अतिरिक्त ऑपरेशन लिख रहे हैं। आप कौन सी परीक्षा लिख ​​सकते हैं?

public class CalculatorTest {
    @Test
    public void testAddTwoIntegers() {
        Calculator calc = new Calculator();
        int result = calc.add(2, 2)
        Assert.assertEquals(4, result);
    }
}

आपके परीक्षण ने केवल इंटरफ़ेस को परिभाषित किया है। यह addविधि है, देखें? addदो तर्क लेता है और उनकी राशि लौटाता है। आप बाद में यह निर्धारित कर सकते हैं कि आपको कई कैलकुलेटर की आवश्यकता है, और उस समय (इस मामले में) जावा इंटरफ़ेस निकालें। आपका परीक्षण तब नहीं बदलना चाहिए, जब से आपने उस वर्ग के सार्वजनिक इंटरफ़ेस का परीक्षण किया हो

अधिक सैद्धांतिक स्तर पर, परीक्षण एक प्रणाली के लिए निष्पादन योग्य विनिर्देश हैं। किसी सिस्टम के इंटरफेस को उस सिस्टम के उपयोगकर्ताओं द्वारा संचालित किया जाना चाहिए, और परीक्षण पहली विधि है जिसे आपको इंटरैक्शन को परिभाषित करना होगा।

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


2
+1 " मुझे नहीं लगता कि आप इंटरफ़ेस डिज़ाइन को टेस्ट डिज़ाइन से अलग कर सकते हैं " बोल्ड में होना चाहिए, IMHO :)
बाइनरी वॉरियर

एक्सएमएल इंपोर्ट और सीएसवी इंपोर्ट कहते हैं, अगर आप किसी फंक्शननलिटी के एक से ज्यादा इंप्लीमेंटेशन को टेस्ट करना चाहते हैं, तो दिखाना और भी आसान है, आप इन्हें उसी इंटरफेस से बिल्कुल उसी तरीके से टेस्ट कर सकते हैं, हालांकि इंप्लीमेंटेशन बदल जाएगा। इसके अलावा, परीक्षण में अक्सर कुछ नकली शामिल होते हैं, और इसके लिए इंटरफ़ेस आवश्यक हैं।
वालफ्रैट

आप कहते हैं कि परीक्षण को बदलने की आवश्यकता नहीं है, लेकिन new Calculator()क्या कार्यान्वयन सही है? यदि कोई नया कार्यान्वयन आवश्यक है, तो शायद आप एक MultiplicationCalculator करेंगे, और आपको new AdditionCalculator()इसे अभी भी पास करने के लिए परीक्षण को बदलने की आवश्यकता होगी ? या क्या मैं कुछ न कुछ भूल रहा हूं ?
स्टीव चामिलार्ड

3
@SteveChamaillard ज़रूर, अगर आपके डिज़ाइन ने आपको क्लास का नाम कैलकुलेटर से एडिशनकैलकुलर में बदल दिया है तो टेस्ट को मैच में बदलना होगा। बेशक, TDD करने से वास्तव में क्या होगा आप पहले टेस्ट को बदल देंगे, और टेस्ट पास करने के लिए कक्षा में बदलाव का पालन करेंगे।
एरिक किंग

5

जब हम लिखते हैं तो हम क्या कर रहे हैं interface? क्या हम कोड लिख रहे हैं , या हम डिजाइन कर रहे हैं?

मैं टेस्ट ड्रिवेन डिज़ाइन की धारणा का प्रशंसक नहीं हूं, लेकिन मुझे टेस्ट ड्रिवेन डेवलपमेंट बहुत पसंद है । व्यक्तिगत रूप से, मैंने अपना सर्वश्रेष्ठ परिणाम प्राप्त किया है जब मैं परीक्षण लिखने से पहले इंटरफ़ेस को डिज़ाइन करके कक्षा को आगे बढ़ाता हूं। मैं कोड के रूप में इंटरफ़ेस की गणना नहीं करता हूं। इंटरफ़ेस एक डिज़ाइन है जिसे मैं टीडीडी का उपयोग करके लागू किया जाएगा। जैसा कि मैं काम करता हूं, एक विकसित होने की संभावना है, लेकिन यह मेरा रोडमैप है (मेरी परीक्षण सूची के साथ)।

मैं शेख़ी शुरू करने से पहले रुक जाऊंगा, लेकिन उम्मीद है कि आपके लिए इसके बारे में सोचने का एक उपयोगी तरीका है।


4

TDD में मुझे पहले टेस्ट या इंटरफ़ेस लिखना होगा?

यह सब इस बात पर निर्भर करता है कि आप रूढ़िवादी / धार्मिक कैसे TDD करना चाहते हैं ।

मैं TDD सीख रहा हूं

चूंकि आप सीख रहे हैं, तो आपको एक व्यक्तिगत वर्कफ़्लो प्राप्त करने के लिए प्रयोग करना चाहिए, जो आपके लिए काम करता है।

  1. यदि आप इसे पुस्तकों के अनुसार करना चाहते हैं , तो आप पहले एक परीक्षण में लिखते हैं, जो स्पष्ट रूप से विफल हो जाएगा, क्योंकि आप बिना किसी कोड के शुरू कर रहे हैं। फिर आप टेस्ट पास करने के लिए कुछ कोड लिखते हैं। यदि ऐसा किया जाता है, तो आप मौजूदा कोड को फिर से भरने के लिए स्वतंत्र हैं, क्योंकि आपके पास एक परीक्षण है जो रिफ्लेक्टरिंग के लिए किसी प्रकार का सुरक्षा-जाल प्रदान करता है। इंटरफ़ेस का उपयोग करने का निर्णय लेना किसी तरह का रिफलेक्ट करना है।

  2. TDD या नहीं के अलावा: पहली जगह में एक इंटरफ़ेस का उपयोग करें या नहीं, यह सवाल दिलचस्प नहीं है। बेशक, यदि आप सुनिश्चित हैं, आपके पास अलग-अलग व्यवहार है जिसे आप कई वस्तुओं में फैलाना चाहते हैं, तो इंटरफ़ेस का उपयोग करने के बारे में सोचने के लिए यह समझ में आता है: उदाहरण के लिए, यदि आपके पास विभिन्न स्थानों पर किसी प्रकार का आउटपुट है, तो इसे लागू करने के लिए समझ में आता है एक इंटरफ़ेस लेखक और आउटपुट के लिए अलग-अलग कक्षाएं हैं ( FileWriter , प्रिंटर आदि)। हालाँकि यह एक इंटरफ़ेस के लिए लिखने के लिए एक आम कहावत है , लेकिन इसका मतलब यह नहीं है: सब कुछ के लिए एक इंटरफ़ेस का उपयोग करें । कभी-कभी यह बहुत हद तक अप्रत्यक्ष का एक स्तर होता है। Btw। वही सेवाओं के लिए जाता है। लेकिन यह एक अलग विषय है।

  3. दूसरी ओर, आप दूसरे तरीके से संचालित परीक्षण विकसित कर सकते हैं: परीक्षण के लिए अपना कोड डिज़ाइन करें। इसका मतलब है, आप कोड लिखते हैं, जो परीक्षण करना आसान है - हालांकि आप बाद में परीक्षण लिखते हैं । इससे कोई फर्क नहीं पड़ता कि आप पहले से या बाद में परीक्षण लिखते हैं, जब तक आप वैसे भी परीक्षण करते हैं।


5
अंतिम बिंदु से सहमत नहीं हो सकते हैं "इससे कोई फर्क नहीं पड़ता कि आप पहले से परीक्षण करते हैं या बाद में, जब तक आप वैसे भी परीक्षण करते हैं"। यदि आप परीक्षण लिखने के लिए होते हैं तो आप सुनिश्चित नहीं हो सकते हैं कि परीक्षण सही चीज़ का परीक्षण कर रहा है या नहीं।
194 पर k4vin

4
जैसा कि मैंने कहा ... यह इस बात पर निर्भर करता है कि आप कैसे रूढ़िवादी हैं ...
थॉमस जंक

2

टीडीडी या बीडीडी का अर्थ होगा कि पहले अपने डोमेन इंटरफेस करना और फिर मेरी व्याख्या द्वारा उनके खिलाफ परीक्षण लिखना। एक इंटरफ़ेस के कार्यान्वयन में एक अपेक्षित व्यवहार होता है।

यह अभी भी कोड से पहले परीक्षण है क्योंकि एक इंटरफ़ेस में कोई परीक्षण योग्य तर्क नहीं है यह वह संरचना है जिसके खिलाफ आप एक परीक्षण लिखते हैं।

मैं इसे निम्नानुसार करूंगा

  1. अर्ध औपचारिक व्यवहार लिखें (दिया गया: जब: तब :)

  2. इंटरफ़ेस लिखें (व्यवहार एनकैप्सुलेटिंग पद्धति को होस्ट करने के लिए)

  3. वह परीक्षण लिखें जिसे वह पहचानता है (इनपुट दिया गया है, जब कॉल करें, तब परीक्षण करें)

  4. टेस्ट पास करने के लिए कंक्रीट (क्लास जो इंटरफ़ेस को लागू करता है) लिखें / अलर्ट करें


0

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

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


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

@gnat मेरा मानना ​​है कि निस्साम यहाँ C # interfaceकीवर्ड की बात कर रहा है , सामान्य शब्द "इंटरफ़ेस" की नहीं।
रबरडक

@ रबडकॉक मुझे भी ऐसा लगता है और मेरा मानना ​​है कि यह एक खराब दृष्टिकोण है। "जब तक आप ऐसा कर चुके हैं तब तक आपको परीक्षणों के बारे में सोचना शुरू नहीं करना चाहिए ..." जैसा कि मैंने लिखा था, शीर्ष उत्तर में तर्क अधिक सम्मोहक लगता है, दोनों सामान्य ज्ञान के अर्थ में और ठोस कीवर्ड के अर्थ में
gnat

काफी हद तक @gnat जो आपकी टिप्पणी से स्पष्ट नहीं था। व्यक्तिगत रूप से, मैं यहाँ निस्म से सहमत हूँ। मुझे लगता है कि यह TDD का उपयोग करने से लोगों को रोकने के लिए एक बहाने के रूप में डिजाइन नहीं करता है। YMMV।
रबरडक

-2

जब तक परियोजना में उनका समावेश परमाणु नहीं हो जाता है, तब तक इंटरफ़ेस / कोड / टेस्ट लिखना ठीक है।

जब तक आपका बॉस टीडीडी के बारे में धार्मिक नहीं है, उस स्थिति में आपको संभवतः खाली इंटरफ़ेस लिखना होगा -> परीक्षण -> न्यूनतम कोड (व्यर्थ चरण) -> अधिक परीक्षण -> अधिक व्यर्थ कोड -> अधिक परीक्षण -> अंत में वास्तविक कोड लिखें - > हो गया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.