ruby - RSpec के विषय और चलो में क्या अंतर है? इन्हें कब इस्तेमाल किया जाना चाहिए या नहीं?




unit-testing (2)

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

विषय

यह काम किस प्रकार करता है

विषय वस्तु का परीक्षण किया जा रहा है। RSpec में विषय का एक स्पष्ट विचार है। यह परिभाषित किया जा सकता है या नहीं। यदि यह है, तो RSpec स्पष्ट रूप से संदर्भित किए बिना इस पर तरीके कह सकता है।

डिफ़ॉल्ट रूप से, यदि बाहरी उदाहरण समूह ( describe या context ब्लॉक) का पहला तर्क एक वर्ग है, तो RSpec उस वर्ग का एक उदाहरण बनाता है और उसे विषय पर असाइन करता है। उदाहरण के लिए, निम्नलिखित पास:

class A
end

describe A do
  it "is instantiated by RSpec" do
    expect(subject).to be_an(A)
  end
end

आप विषय को स्वयं subject साथ परिभाषित कर सकते हैं:

describe "anonymous subject" do
  subject { A.new }
  it "has been instantiated" do
    expect(subject).to be_an(A)
  end
end

जब आप इसे परिभाषित करते हैं तो आप विषय को एक नाम दे सकते हैं:

describe "named subject" do
  subject(:a) { A.new }
  it "has been instantiated" do
    expect(a).to be_an(A)
  end
end

यदि आप विषय का नाम रखते हैं, तो भी आप इसे गुमनाम रूप से संदर्भित कर सकते हैं:

describe "named subject" do
  subject(:a) { A.new }
  it "has been instantiated" do
    expect(subject).to be_an(A)
  end
end

आप एक से अधिक नामित विषय को परिभाषित कर सकते हैं। सबसे हाल ही में परिभाषित नाम विषय अनाम subject

हालाँकि विषय परिभाषित है,

  1. यह तात्कालिक रूप से आलसी है। यही है, वर्णित वर्ग के निहित तात्कालिकता या subject लिए पारित ब्लॉक का निष्पादन तब तक नहीं होता है जब तक कि subject या नामित विषय को एक उदाहरण में संदर्भित नहीं किया जाता है। यदि आप चाहते हैं कि आपका अन्वेषण विषय उत्सुकता से त्वरित रूप से (इसके समूह में एक उदाहरण से पहले) चलता है, तो subject! कहो subject! subject बजाय।

  2. इस पर उम्मीदें निहित की जा सकती हैं ( subject लिखे बिना या किसी नामित विषय के नाम के बिना):

    describe A do
      it { is_expected.to be_an(A) }
    end

    विषय इस एक-पंक्ति सिंटैक्स का समर्थन करने के लिए मौजूद है।

इसका उपयोग कब करना है

एक अंतर्निहित subject (उदाहरण समूह से अनुमानित) को समझना मुश्किल है क्योंकि

  • यह पर्दे के पीछे तात्कालिक है।
  • चाहे इसका स्पष्ट रूप से उपयोग किया जाता है (स्पष्ट रिसीवर के बिना is_expected रूप से कॉल is_expected ) या स्पष्ट रूप से ( subject रूप में), यह पाठक को उस वस्तु की भूमिका या प्रकृति के बारे में कोई जानकारी नहीं देता है जिस पर उम्मीद की जा रही है।
  • वन-लाइनर उदाहरण सिंटैक्स में उदाहरण विवरण (सामान्य उदाहरण सिंटैक्स में स्ट्रिंग तर्क) नहीं होता है, इसलिए पाठक को केवल उदाहरण के उद्देश्य के बारे में जानकारी की अपेक्षा ही होती है।

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

describe Article do
  it { is_expected.to validate_presence_of(:title) }
end

एक अनाम अनाम subject (एक नाम के बिना subject साथ परिभाषित) थोड़ा बेहतर है, क्योंकि पाठक देख सकता है कि यह कैसे त्वरित है, लेकिन

  • यह अभी भी उस विषय की तात्कालिकता को दूर रख सकता है जहाँ से इसका उपयोग किया जाता है (उदाहरण के लिए एक उदाहरण समूह के शीर्ष पर जो इसका उपयोग करते हैं), जिसका पालन करना अभी भी कठिन है, और
  • यह अन्य समस्याएं हैं जो अंतर्निहित विषय करता है।

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

तो, एक स्पष्ट अनाम subject या एक नामित विषय के वैध उपयोग बहुत दुर्लभ हैं

चर let

वे कैसे काम करते हैं

वैरिएबल दो नामों को छोड़कर नामांकित विषयों की तरह हैं:

  • वे let / let! परिभाषित होते हैं let! subject / subject! बजाय subject!
  • वे अनाम subject सेट नहीं करते हैं या अपेक्षाओं को इस पर कॉल करने की अनुमति नहीं देते हैं।

उनका उपयोग कब करना है

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

let! जोखिम भरा है, क्योंकि यह आलसी नहीं है। यदि कोई उदाहरण समूह में एक उदाहरण जोड़ता है जिसमें let! होता है let! , लेकिन उदाहरण की जरूरत नहीं है let! चर,

  • उस उदाहरण को समझना कठिन होगा, क्योंकि पाठक को let! देखने को मिलेगा let! चर और आश्चर्य है कि क्या और कैसे यह उदाहरण को प्रभावित करता है
  • उदाहरण की तुलना में धीमी गति से होगा, क्योंकि समय बनाने के लिए let! variablle

तो let! उपयोग करें let! , अगर सब पर, केवल छोटे, सरल उदाहरण समूहों में, जहां यह संभावना कम है कि भविष्य के उदाहरण लेखक उस जाल में पड़ जाएंगे।

एकल-अपेक्षा-प्रति-उदाहरण बुत

विषयों का एक आम उपयोग है या अलग-अलग चर्चा करने लायक है जो चर देते हैं। कुछ लोग उन्हें इस तरह से उपयोग करना पसंद करते हैं:

describe 'Calculator' do
  describe '#calculate' do
    subject { Calculator.calculate }
    it { is_expected.to be >= 0 }
    it { is_expected.to be <= 9 }
  end
end

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

लोग ऐसा इसलिए करते हैं क्योंकि उन्होंने सुना है कि प्रति उदाहरण के लिए केवल एक ही अपेक्षा होनी चाहिए (जो कि वैध नियम के साथ मिश्रित है कि किसी को प्रति उदाहरण केवल एक विधि कॉल का परीक्षण करना चाहिए) या क्योंकि वे RSpec चालबाजी के साथ प्यार करते हैं। अनाम या नामांकित विषय या let वेरिएबल के साथ ऐसा न करें! इस शैली में कई समस्याएं हैं:

  • अनाम विषय उदाहरणों का विषय नहीं है - विधि विषय है। परीक्षा को इस तरह से लिखने से भाषा खराब हो जाती है, जिसके बारे में सोचना मुश्किल हो जाता है।
  • हमेशा की तरह वन-लाइन उदाहरणों के साथ, उम्मीदों का अर्थ समझाने के लिए कोई जगह नहीं है।
  • प्रत्येक उदाहरण के लिए विषय का निर्माण किया जाना है, जो धीमा है।

इसके बजाय, एक एकल उदाहरण लिखें:

describe 'Calculator' do
  describe '#calculate' do
    it "returns a single-digit number" do
      result = Calculator.calculate
      expect(result).to be >= 0
      expect(result).to be <= 9
    end
  end
end

http://betterspecs.org/#subject में subject और let बारे में कुछ जानकारी है। हालाँकि, मैं अभी भी उनके बीच अंतर पर स्पष्ट नहीं हूँ। इसके अलावा, एसओ पोस्ट RSpec परीक्षणों में पहले, जाने और विषय का उपयोग करने के खिलाफ तर्क क्या है? यह बेहतर है कि या तो subject उपयोग न करें या करने let । मैं कहाँ जाऊँगा? मैं बहुत उलझा हुआ हूं।


Subject और let आपके परीक्षण को तेज करने और आपकी मदद करने के लिए बस उपकरण हैं। Rspec समुदाय के लोग इनका उपयोग करते हैं इसलिए मुझे इस बात की चिंता नहीं होगी कि उनका उपयोग करना ठीक है या नहीं। उनका उपयोग समान रूप से किया जा सकता है लेकिन थोड़े अलग उद्देश्यों के लिए

Subject आपको एक परीक्षण विषय घोषित करने की अनुमति देता है, और उसके बाद किसी भी निम्नलिखित परीक्षण मामलों के लिए इसका पुन: उपयोग करता है। यह कोड पुनरावृत्ति को कम करता है (अपने कोड को कम करके)

Let before: each का एक विकल्प है before: each ब्लॉक, जो उदाहरण के लिए चर का परीक्षण डेटा असाइन करते हैं। Let आपको कुछ फायदे देते हैं। सबसे पहले, यह एक उदाहरण चर को निर्दिष्ट किए बिना मूल्य को कैश करता है। दूसरा, यह आलसी रूप से मूल्यांकन किया गया है, जिसका अर्थ है कि इसका मूल्यांकन तब तक नहीं होता है जब तक कि इसके लिए एक कल्पना कॉल न हो। इस प्रकार आपको अपने परीक्षणों को गति let मदद करता है। मुझे भी लगता है कि let पढ़ने में आसान है







rspec