क्या आप RSpec का उपयोग करके अपने Ruby एप्लिकेशन्स के लिए टेस्ट लिखना सीखना चाहेंगे?
तो आप सही जगह पर हैं!
इस ट्यूटोरियल में मैं आपको दिखाऊंगा कि यह कैसे करना है।
विषय सूची
- 1 टेस्ट क्यों लिखें?
- 1.0.1 यह त्रुटियों के खिलाफ एक सुरक्षा जाल बनाता है (विशेष रूप से रिफैक्टरिंग के लिए उपयोगी)
- 1.0.2 यह आपके कोड को दस्तावेज़ करने में मदद करता है
- 1.0.3 यह आपको एक फीडबैक लूप देता है
- 1.0.4 यह सुनिश्चित करने में मदद करता है कि आपका कोड अपेक्षित परिणाम दे रहा है
- 1.0.5 यह आपको Ruby जॉब पाने में मदद करता है
- 2 RSpec के साथ शुरुआत
- 3 RSpec टेस्टिंग उदाहरण
- 4 RSpec Let मेथड
- 5 Subject मेथड का उपयोग कैसे करें
- 6 अपने सभी टेस्ट्स से पहले कोड कैसे चलाएं
- 7 टेस्टिंग सबग्रुप कैसे बनाएं
- 8 टेस्ट को अस्थायी रूप से कैसे अक्षम करें
- 9 नाम से उदाहरण चलाएं
- 10 RSpec अपेक्षाएं और मैचर्स
- 11 RSpec फॉर्मेटर्स
- 12 धीमे टेस्ट्स कैसे खोजें
- 13 RSpec वीडियो ट्यूटोरियल
- 14 सारांश
- 14.1 संबंधित
टेस्ट क्यों लिखें?
यहां कारण हैं:
यह त्रुटियों के खिलाफ एक सुरक्षा जाल बनाता है (विशेष रूप से रिफैक्टरिंग के लिए उपयोगी)
यदि आपके पास टेस्ट सूट नहीं है तो आप अपने कोड को छूना नहीं चाहते, क्योंकि कुछ टूटने का डर...
...टेस्ट होने से आपका आत्मविश्वास बढ़ता है!
यह आपके कोड को दस्तावेज़ करने में मदद करता है
आपके टेस्ट वर्णन करते हैं कि आपका एप्लिकेशन क्या करना चाहिए।
यह आपको एक फीडबैक लूप देता है
जब आप TDD कर रहे होते हैं आपको एक फीडबैक लूप मिलता है जो आपको बताता है कि आगे किस पर ध्यान केंद्रित करना है, उपयोगी यदि आप आसानी से विचलित हो जाते हैं।
यह सुनिश्चित करने में मदद करता है कि आपका कोड अपेक्षित परिणाम दे रहा है
यह वाला महत्वपूर्ण है!
यदि आप कुछ जटिल तर्क लिख रहे हैं, तो आप यह सुनिश्चित करना चाहते हैं कि यह कई अलग-अलग इनपुट्स के साथ काम कर रहा है और सिर्फ उस एक उदाहरण के साथ नहीं जो आप लेकर आए थे।
टेस्ट आपको कॉर्नर केसेज को उजागर करने और उन्हें दस्तावेज़ करने में मदद कर सकते हैं।
यह आपको Ruby जॉब पाने में मदद करता है
अधिकांश जॉब एप्लिकेशन्स आपके टेस्टिंग कौशल की सराहना करेंगे, जिससे जॉब पाने की संभावना बढ़ जाएगी।
RSpec के साथ शुरुआत
RSpec कैसे काम करता है यह समझने के लिए आइए एक उदाहरण चरण-दर-चरण देखते हैं।
हम एक सरल एप्लिकेशन लिखने जा रहे हैं जो फैक्टोरियल नंबर ढूंढता है।
पहला चरण:
require 'rspec/autorun' describe Factorial do # ... end
यह आपका पहला RSpec टेस्ट लिखने के लिए प्रारंभिक कोड है।
आपको rspec जेम require करने की आवश्यकता है।
फिर आपको एक describe ब्लॉक बनाने की आवश्यकता है ताकि अपने सभी टेस्ट्स को एक साथ ग्रुप करें और RSpec को बताएं कि आप किस क्लास का टेस्ट कर रहे हैं।
अगला है it ब्लॉक:
describe Factorial do it "does something" do # ... end end
यह टेस्ट नाम है, साथ ही टेस्ट के सभी घटकों को एक साथ ग्रुप करने का एक तरीका।
घटक हैं:
- सेटअप
- एक्सरसाइज़
- वेरिफाई
सेटअप वह जगह है जहां आप कोई भी ऑब्जेक्ट बनाते हैं जिन्हें आपको बनाने की आवश्यकता है।
यह तैयारी चरण है।
फिर आप जिस मेथड को एक्सरसाइज़ करना चाहते हैं उसे कॉल करके उसका रिटर्न मान प्राप्त करते हैं।
अंत में, आप एक अपेक्षा (RSpec) या असर्शन (Minitest) के साथ परिणाम को वेरिफाई करते हैं।
RSpec टेस्टिंग उदाहरण
अब यदि हम फैक्टोरियल मेथड लिखना चाहते हैं, तो हमें ऑनलाइन या मैन्युअल गणना द्वारा कुछ वैध मान ढूंढने होंगे।
फिर हम उन्हें अपने टेस्ट्स के साथ उपयोग करते हैं।
इस तरह:
describe Factorial do it "finds the factorial of 5" do calculator = Factorial.new expect(calculator.factorial_of(5)).to eq(120) end end
जब आप इस कोड को चलाते हैं (एक नियमित Ruby प्रोग्राम की तरह) तो आपको यह मिलेगा:
uninitialized constant Factorial (NameError)
यह सामान्य है क्योंकि हमारे पास अभी तक Factorial क्लास नहीं है।
आइए एक बनाते हैं:
class Factorial end
अगली त्रुटि होगी:
undefined method 'factorial_of'
मैं factorial_of मेथड बनाकर इसे ठीक करता हूँ:
class Factorial def factorial_of end end
फिर कोड को फिर से चलाएं:
wrong number of arguments (given 1, expected 0)
एक और त्रुटि! लेकिन क्या आप जानते हैं?
यह एक अच्छी बात है 🙂
त्रुटियां किसी चीज से निराश होने की नहीं हैं।
वे फीडबैक हैं।
अब:
factorial_of मेथड में एक मेथड आर्गुमेंट जोड़ें:
class Factorial def factorial_of(n) end end
अब आपको टेस्ट फेल्योर मिलता है:
expected: 120 got: nil
यही वह बिंदु है जहां आप इस बिंदु पर होना चाहते हैं!
अगला कार्य मेथड को लागू करना है:
class Factorial def factorial_of(n) (1..n).inject(:*) end end
और आपको अपना पहला पासिंग टेस्ट मिलेगा:
. Finished in 0.00315 seconds (files took 0.09083 seconds to load) 1 example, 0 failures
इसे हम टेस्ट-ड्रिवन डेवलपमेंट (TDD) कहते हैं।
आप पहले टेस्ट लिखते हैं, फिर टेस्ट्स को आपको मार्गदर्शन करने दें कि आगे क्या करना है।
RSpec Let मेथड
यदि आप कई टेस्ट लिखना चाहते हैं और उसी ऑब्जेक्ट्स का पुनः उपयोग करना चाहते हैं तो आप इन ऑब्जेक्ट्स को let स्टेटमेंट्स के साथ परिभाषित कर सकते हैं।
यह ऐसा दिखता है:
describe Factorial do let(:calculator) { Factorial.new } it "finds the factorial of 5" do expect(calculator.factorial_of(5)).to eq(120) end end
अब आप उसी describe ब्लॉक के तहत अपने सभी टेस्ट्स में calculator का पुनः उपयोग कर सकते हैं।
एक बात जो आपको let के बारे में पता होनी चाहिए वह यह है कि यह "लेज़ी" है।
मेरा मतलब क्या है?
ऑब्जेक्ट पहली बार उपयोग किए जाने तक नहीं बनाया जाएगा।
यदि इस ऑब्जेक्ट को बनाने के साइड-इफेक्ट्स हैं, जैसे डेटाबेस एंट्रीज बनाना, या फाइल लिखना तो यह अंतर पैदा कर सकता है।
इन साइड-इफेक्ट्स से बचना सबसे अच्छा होगा, लेकिन यदि आप ऐसा नहीं कर सकते तो let! मेथड का उपयोग करें।
उदाहरण:
let!(:user) { User.create("rspec@rubyguides.com") }
let! मेथड नॉन-लेज़ी है, इसलिए ऑब्जेक्ट किसी भी टेस्ट के चलने से पहले बनाया जाएगा।
Subject मेथड का उपयोग कैसे करें
let का एक और संस्करण subject है।
एकमात्र अंतर यह है कि आपके पास केवल एक subject हो सकता है, और इसका मतलब मुख्य ऑब्जेक्ट का एक इंस्टेंस होना है जिसका आप टेस्ट कर रहे हैं।
RSpec पहले से ही एक डिफ़ॉल्ट subject इस तरह बनाता है:
subject { Factorial.new }
इसे "इम्प्लिसिट सब्जेक्ट" कहा जाता है।
आप इसका उपयोग इस तरह कर सकते हैं:
describe Factorial do it "finds the factorial of 5" do expect(subject.factorial_of(5)).to eq(120) end end
आप अपने सब्जेक्ट को नाम दे सकते हैं:
subject(:calculator) { Factorial.new }
यह let का उपयोग करने की तरह ही व्यवहार करता है, लेकिन यह वन-लाइन अपेक्षाओं के उपयोग को सक्षम करता है:
it { should be_empty }
अपने सभी टेस्ट्स से पहले कोड कैसे चलाएं
RSpec में एक्जीक्यूशन हुक्स हैं जिनका उपयोग आप हर टेस्ट से पहले और बाद में, या टेस्ट्स के पूरे ग्रुप के लिए कुछ चलाने के लिए कर सकते हैं।
उदाहरण के लिए:
describe Shop do before(:all) { Shop.prepare_database } after (:all) { Shop.cleanup_database } end
यदि आप प्रत्येक उदाहरण के लिए इस कोड को चलाना चाहते हैं (उदाहरण = RSpec में टेस्ट) तो आप :all के बजाय :each का उपयोग कर सकते हैं।
टेस्टिंग सबग्रुप कैसे बनाएं
यदि आप अपने ऐप में विभिन्न परिदृश्यों का टेस्ट कर रहे हैं तो संबंधित टेस्ट्स को एक साथ ग्रुप करना मददगार हो सकता है।
आप RSpec में कॉन्टेक्स्ट ब्लॉक का उपयोग करके ऐसा कर सकते हैं।
यहां एक उदाहरण है:
describe Course do context "when user is logged in" do it "displays the course lessons" do end it "displays the course description" do end end context "when user it NOT logged in" do it "redirects to login page" do end it "it shows a message" do end end end
टेस्ट को अस्थायी रूप से कैसे अक्षम करें
डीबगिंग उद्देश्यों के लिए टेस्ट को अक्षम करना संभव है।
आपको बस उन टेस्ट्स के लिए it को xit में बदलना है जिन्हें आप अक्षम करना चाहते हैं।
उदाहरण:
xit "eats lots of bacon" do end
जब आप काम पूरा कर लें तो x को हटाना न भूलें!
नाम से उदाहरण चलाएं
टेस्ट्स को अक्षम करने के बजाय, आप -e फ्लैग के साथ चलाने के लिए टेस्ट्स को फ़िल्टर कर सकते हैं।
उदाहरण:
> ruby person.rb -e bacon
यह फ़िल्टरिंग टेस्ट नाम पर आधारित है, इसलिए उपरोक्त उदाहरण "bacon" शब्द वाले किसी भी टेस्ट से मेल खाएगा।
RSpec अपेक्षाएं और मैचर्स
आपको याद हो सकता है कि हम जिस उदाहरण का उपयोग कर रहे थे:
expect(calculator.factorial_of(5)).to eq(120)
लेकिन यह eq(120) भाग क्या है?
खैर, 120 वह मान है जिसकी हम अपेक्षा कर रहे हैं...
...और eq वह है जिसे हम मैचर कहते हैं।
मैचर्स हैं कि RSpec कैसे आपके मेथड के आउटपुट की तुलना आपकी अपेक्षित मान से करता है।
eq के मामले में, RSpec == ऑपरेटर का उपयोग करता है (Ruby ऑपरेटर्स के बारे में और पढ़ें)।
लेकिन अन्य मैचर्स हैं जिनका आप उपयोग कर सकते हैं।
उदाहरण के लिए, be_something मैचर:
expect(nil).to be_nil
जहां something एक प्रेडिकेट मेथड है (जैसे empty?) जिसे टेस्ट परिणामों पर कॉल किया जाएगा।
अन्य उपयोगी मैचर्स:
- include (सरणियों और हैश के लिए)
- start_with
- end_with
- match (रेगुलर एक्सप्रेशन मिलान के लिए)
- be_between
- have_key / have_value (हैश के लिए)
- be_instance_of
- respond_to
- have_attributes (इंस्टेंस वेरिएबल्स टेस्ट करने के लिए)
एक मैचर जिसे विशेष ध्यान देने की आवश्यकता है वह है raise_error मैचर।
इसका कारण यह है कि इसका उपयोग करने के लिए आपको अपनी अपेक्षा को एक ब्लॉक के भीतर लपेटना होगा।
इस तरह:
expect{ :x.count }.to raise_error(NoMethodError)
change मैचर भी इसी तरह काम करता है:
expect{ stock.increment }.to change(stock, :value).by(100)
RSpec फॉर्मेटर्स
डिफ़ॉल्ट RSpec आउटपुट "प्रोग्रेस" फॉर्मेट में है।
इस फॉर्मेट के साथ आप डॉट्स (.) देखते हैं जो 1 पासिंग टेस्ट का प्रतिनिधित्व करते हैं, फेल टेस्ट के लिए F (अपेक्षित और वास्तविक मेल नहीं खाते), या त्रुटि के लिए E।
लेकिन वैकल्पिक फॉर्मेटिंग विकल्प हैं जिनका आप उपयोग कर सकते हैं।
यहां एक सूची है:
- progress
- documentation
- json
- html
आप उन्हें -f फ्लैग के साथ सक्षम कर सकते हैं:
> ruby factorial.rb -f d Person eats lots of healthy food writes many articles Finished in 0.00154 seconds (files took 0.09898 seconds to load) 2 examples, 0 failures
डॉक्यूमेंटेशन फॉर्मेट आपके टेस्ट विवरणों का उपयोग करके आउटपुट उत्पन्न करता है।
धीमे टेस्ट्स कैसे खोजें
RSpec आपके टेस्ट्स को प्रोफाइल करने के लिए एक बहुत ही आसान विकल्प के साथ आता है।
बस --profile फ्लैग पास करके आप देख पाएंगे कि प्रत्येक टेस्ट को चलने में कितना समय लगता है और वास्तव में धीमे वाले को ठीक कर पाएंगे।
यहां एक उदाहरण है:
> ruby factorial.rb --profile Factorial finds the factorial of 5 0.00043 seconds
RSpec वीडियो ट्यूटोरियल
सारांश
आपने RSpec टेस्टिंग फ्रेमवर्क का उपयोग करके टेस्ट लिखना सीखा।
अब आपकी बारी है अपने खुद के टेस्ट लिखना शुरू करने की!