परीक्षण अधिकांश अच्छी तरह से काम करने वाले Rails एप्लिकेशन का एक अभिन्न अंग हैं जहां रखरखाव एक बुरा सपना नहीं है और नई सुविधाएं लगातार जोड़ी जाती हैं, या मौजूदा में सुधार किया जाता है। दुर्भाग्य से, कई एप्लिकेशन के लिए, एक उत्पादन वातावरण वह जगह है जहां उन्हें पहली बार भारी कार्यभार या महत्वपूर्ण ट्रैफिक के तहत रखा जाता है। यह समझ में आता है क्योंकि ऐसे परीक्षण महंगे हैं।
शुक्र है, Rails में न केवल यूनिट, एंड-टू-एंड, और इंटीग्रेशन टेस्ट के लिए अच्छा समर्थन है, बल्कि प्रदर्शन और लोडिंग से संबंधित परीक्षणों के लिए भी है। मैं इस लेख में उन सभी को कवर करूंगा और कुछ व्यावहारिक उदाहरण दिखाऊंगा जो आपको यह समझने में मदद करेंगे कि आपके एप्लिकेशन के प्रदर्शन स्तर का परीक्षण करने वाले टूल का कुशलतापूर्वक उपयोग कैसे करें।
लेख दो खंडों में विभाजित है:
सैद्धांतिक — मैं आपको दिखाऊंगा कि परीक्षण क्यों आवश्यक है, हम किस प्रकार के परीक्षण कर सकते हैं और एप्लिकेशन पर परीक्षण करते समय कौन से मेट्रिक्स आवश्यक हैं
व्यावहारिक — हम अपने हाथ गंदे करेंगे और एक वास्तविक एप्लिकेशन के लिए टेस्ट लिखकर आउटपुट प्राप्त करेंगे
दोनों खंडों को पढ़ने के बाद, आपको विभिन्न प्रकार के परीक्षणों की गहरी समझ होगी और उन्हें अपने Rails एप्लिकेशन पर कैसे करना है। दिलचस्प लगता है? तो आइए टेस्ट के बारे में थोड़े सिद्धांत के साथ शुरू करते हैं।
सिद्धांत में परीक्षण
परीक्षण हमेशा किसी भी प्रकार के एप्लिकेशन के विकास का एक अंतर्निहित हिस्सा होना चाहिए। यदि आप अभी भी इसके बारे में आश्वस्त नहीं हैं या अभी तक कोई टेस्ट नहीं लिखा है, तो यहां परीक्षण के लिए कुछ तर्क दिए गए हैं जो आपकी मदद करेंगे:
- कुछ टूटने की चिंता के बिना बदलाव पेश करें — यह टेस्ट आवश्यक होने का प्रमुख कारण है। एक विशाल ऐप पर काम करने की कल्पना करें जहां आपको हर बार कुछ बदलाव पेश करने पर, यहां तक कि एक छोटे से बदलाव पर, पूरे ऐप के माध्यम से क्लिक करना पड़ता है ताकि यह सुनिश्चित हो सके कि कुछ भी टूटा नहीं है। टेस्ट के साथ, आप बस एक कमांड निष्पादित करते हैं और सत्यापन प्रक्रिया स्वचालित और तेज होती है।
- आसान रिफैक्टरिंग प्रक्रिया — मैंने ऊपर उल्लेख किया है कि नई सुविधाएं जोड़ते समय या बदलाव करते समय टेस्ट आवश्यक हैं। परीक्षण के साथ, आप अपने मौजूदा कोड को सुधारने में भी अधिक सहज होते हैं।
- टेस्ट दस्तावेज़ीकरण का एक रूप हैं — अच्छी तरह से लिखे गए टेस्ट एप्लिकेशन में सुविधाओं के विभिन्न सेट के लिए दस्तावेज़ीकरण का एक रूप हो सकते हैं। वे न केवल यह वर्णन करते हैं कि सुविधा क्या है बल्कि यह भी कि इसे कैसे काम करना चाहिए।
- कार्यान्वयन पर पुनर्विचार करने का अवसर — जब आप एक टेस्ट लिखते हैं, तो आपके पास फिर से सोचने का मौका होता है कि क्या आप कोड को लागू करने का तरीका सही और उचित है। साथ ही, आप बस जांचते हैं कि आपका कोड उस तरह से काम कर रहा है जैसा आप उम्मीद करते हैं।
मुझे उम्मीद है कि उपरोक्त तर्कों ने आपको किसी भी ऐप के विकास के दौरान टेस्ट का उपयोग करने के लिए आश्वस्त किया। यह जानना कि कोड का परीक्षण क्यों करना आवश्यक है, यह भी महत्वपूर्ण है कि विभिन्न प्रकार के टेस्ट के बारे में जानें।
विभिन्न प्रकार के टेस्ट
तीन प्राथमिक प्रकार के टेस्ट हैं जिन्हें आप यह सुनिश्चित करने के लिए लिख सकते हैं कि आपके Rails एप्लिकेशन का प्रदर्शन सही है और बुनियादी ढांचा भारी कार्यभार के तहत अच्छी तरह से काम कर रहा है। वे प्रकार निम्नलिखित हैं:
- लोड टेस्टिंग — इस प्रकार का टेस्ट निम्नलिखित प्रश्न का उत्तर देता है: एक दी गई अवधि के लिए सिस्टम कितने समवर्ती उपयोगकर्ताओं को संभाल सकता है। कल्पना करें कि आप अपनी वेबसाइट पर एक टॉप-रेटेड उत्पाद लॉन्च करते हैं और हजारों उपयोगकर्ता एक ही समय में ऑर्डर देना चाहते हैं। उचित लोड टेस्ट के बिना, आप सबसे महत्वपूर्ण समय में क्रैश का जोखिम उठाते हैं।
- स्ट्रेस टेस्टिंग — इस प्रकार के टेस्ट के साथ, आप सिस्टम द्वारा एक साथ संभाले जा सकने वाले उपयोगकर्ताओं की संख्या को सत्यापित करने पर ध्यान केंद्रित नहीं करते हैं, बल्कि इस पर कि जब उपयोगकर्ताओं की सीमा पूरी हो जाती है तो सिस्टम कैसे व्यवहार करेगा।
- प्रदर्शन परीक्षण — मैं कहूंगा कि इस प्रकार का टेस्ट स्ट्रेस और लोड टेस्टिंग का जनक है। ऐसे टेस्ट का प्राथमिक उद्देश्य मेट्रिक्स का एक विशिष्ट सेट प्राप्त करना है जिस आधार पर हम एप्लिकेशन के कोड को बेहतर बनाने के लिए कुछ कार्रवाई कर सकते हैं। मैं उन मेट्रिक्स के बारे में थोड़ी देर में बात करूंगा।
यह कहने के बाद, हम अब सिद्धांत भाग के अंतिम चरण के लिए तैयार हैं: यह सीखना कि Rails एप्लिकेशन पर प्रदर्शन परीक्षण करते समय कौन से मेट्रिक्स आवश्यक हैं। उस ज्ञान के बिना, हम टेस्ट आउटपुट की सही व्याख्या नहीं कर पाएंगे और यह तय नहीं कर पाएंगे कि हमें कोड बदलना चाहिए या नहीं।
महत्वपूर्ण मेट्रिक्स
आपको प्राप्त होने वाले मेट्रिक्स का प्रकार आपके द्वारा परीक्षण के लिए उपयोग किए जाने वाले टूल के आधार पर भिन्न हो सकता है, लेकिन आम तौर पर, हम उन्हें मेट्रिक्स के एक सेट में समूहित कर सकते हैं जो काफी सामान्य हैं:
- प्रतिक्रिया समय — अनुरोध किए जाने और ब्राउज़र में प्रतिक्रिया प्रस्तुत होने के बीच का समय। यह मेट्रिक हमें दिखाता है कि उपयोगकर्ता को उसके द्वारा अनुरोधित जानकारी प्राप्त करने से पहले कितने समय तक इंतजार करना पड़ता है। इसे कभी-कभी प्रोसेस समय भी कहा जाता है।
- मेमोरी उपयोग — दिए गए अनुरोध के लिए खपत की गई मेमोरी की मात्रा। यह आवश्यक जानकारी है क्योंकि यह आपको उस स्थान की ओर इंगित करता है जहां आप कोड को सुधार सकते हैं ताकि सिस्टम तेजी से प्रतिक्रिया दे सके और कम संसाधनों का उपयोग कर सके।
- ऑब्जेक्ट आवंटन — उच्च मेमोरी आवंटन उच्च मेमोरी उपयोग और लंबे प्रतिक्रिया समय का कारण बनता है। यह मेट्रिक आपको कोड में उस सटीक स्थान पर ले जा सकता है जहां कई ऑब्जेक्ट आवंटित किए जाते हैं, ताकि आप तुरंत उसका निरीक्षण कर सकें।
परीक्षण करते समय आपके पास अधिक मेट्रिक्स हो सकते हैं, लेकिन वे तीन सबसे महत्वपूर्ण हैं और आपके द्वारा परीक्षण किए जाने वाले किसी भी एप्लिकेशन के लिए मान्य होंगे। अब हम अपने हाथ गंदे कर सकते हैं और वास्तविक टेस्ट लिख सकते हैं।
अभ्यास
हम कुछ टेस्ट करने के लिए कुछ होने के बिना टेस्ट नहीं लिख सकते। इसलिए अभ्यास भाग में पहला कदम एक साधारण Rails एप्लिकेशन लिखना है जिसके लिए हम टेस्ट लिख सकें।
नमूना Rails एप्लिकेशन
मैं Ruby 3.0.1 और Rails 6.1.3.1 का उपयोग करूंगा लेकिन बेझिझक किसी भी संस्करण का उपयोग करें जिसके साथ आप सहज हैं। यदि आपके पास Ruby और Rails इंस्टॉल हैं, तो अगला कदम एप्लिकेशन का स्केलेटन बनाना है:
rails new simpleapp -d=postgresql
लेख के उद्देश्य के लिए, मैं एक ऐसा ऐप बनाऊंगा जहां उपयोगकर्ताओं की सूची उनके पालतू जानवरों के नामों के साथ प्रस्तुत की जाती है। ऐसी संरचना हमें N+1 क्वेरी आसानी से बनाने की अनुमति देगी जो प्रदर्शन परीक्षण करते समय गति और अन्य मेट्रिक्स पर परिवर्तनों के प्रभाव की जांच करने में अधिक मज़ा देंगी।
मॉडल उत्पन्न करने से पहले, आइए पहले डेटाबेस बनाएं:
cd simpleapp/ bin/rails db:create
अब, हम मॉडल उत्पन्न कर सकते हैं:
rails g model User name:string rails g model Animal name:string user:references bin/rails db:migrate
सिर्फ User मॉडल में एक छोटा अपडेट Animal मॉडल के साथ संबंध को प्रतिबिंबित करने के लिए:
class User < ApplicationRecord has_many :animals end
अब हम db/seeds.rb फ़ाइल में कुछ सीड जोड़ सकते हैं:
people = { 'Tim' => ['Pinky', 'Rick'], 'Martha' => ['Rudolph'], 'Mark' => ['Niki', 'Miki', 'Bella'], 'Tina' => ['Tom', 'Luna'] } people.each_pair do |name, pets| user = User.create(name: name) pets.each do |pet_name| user.animals.create(name: pet_name) end end
और डेटा को डेटाबेस में लोड करें:
bin/rails db:seed
मैं उपयोगकर्ताओं के असाइनमेंट के साथ एक कंट्रोलर बनाऊंगा, और फिर व्यू में, मैं सभी उपयोगकर्ताओं को उनके पालतू जानवरों के नामों के साथ सूचीबद्ध करूंगा। मैं जानबूझकर ऐसा कोड उपयोग कर रहा हूं जो प्रदर्शन समस्याएं पैदा करता है ताकि आप बाद में सुधारों को माप सकें।
touch app/controllers/home_controller.rb mkdir app/views/home touch app/views/home/index.html.erb
कंट्रोलर सरल है:
class HomeController < ApplicationController def index @users = User.all end end
और व्यू भी:
<h1>List</h1> <ul> <% @users.each do |user| %> <li><%= user.name %> (<%= user.animals.count %>) <ul> <% user.animals.each do |animal| %> <li><%= animal.name %></li> <% end %> </ul> </li> <% end %> </ul>
अंतिम चरण config/routes.rb फ़ाइल को अपडेट करना है ताकि Rails को पता चले कि हम मुख्य URL पर जाने पर क्या देखना चाहते हैं:
Rails.application.routes.draw do root to: 'home#index' end
JMeter के साथ लोड टेस्ट
JMeter अपाचे सॉफ्टवेयर फाउंडेशन द्वारा बनाया गया एक ओपन-सोर्स सॉफ्टवेयर है, जिसे कार्यात्मक व्यवहार का लोड टेस्ट करने के लिए डिज़ाइन किया गया है। चूंकि यह जावा के साथ बनाया गया एक प्रोग्राम है, आप इसे किसी भी ऑपरेटिंग सिस्टम पर इंस्टॉल कर सकते हैं। आप यहां फाइलें डाउनलोड कर सकते हैं: https://jmeter.apache.org/download_jmeter.cgi
यदि आप macOS सिस्टम पर काम कर रहे हैं, तो आप Homebrew के साथ JMeter को आसानी से इंस्टॉल कर सकते हैं:
brew install jmeter
इंस्टॉलेशन के बाद, आप निम्न कमांड के साथ प्रोग्राम चला सकते हैं:
jmeter
टेस्ट कॉन्फ़िगर करना
कॉन्फ़िगरेशन प्रक्रिया में निम्नलिखित चरण होते हैं:
- थ्रेड ग्रुप जोड़ना — उपयोगकर्ताओं की संख्या और प्रत्येक आपकी वेबसाइट पर कितनी देर तक विज़िट करेगा, निर्दिष्ट करना
- HTTP अनुरोध कॉन्फ़िगर करना — वह एंडपॉइंट निर्दिष्ट करना जिसे JMeter को हिट करना चाहिए
- उन मेट्रिक्स को सेट करना जिनमें हम रुचि रखते हैं
आइए हमारे द्वारा पहले बनाए गए सरल ऐप के मुख्य पृष्ठ पर एकल उपयोगकर्ता अनुरोध का अनुकरण करने के लिए एक साधारण टेस्ट कॉन्फ़िगरेशन के माध्यम से चरण-दर-चरण चलते हैं।
थ्रेड ग्रुप जोड़ें
"टेस्ट प्लान" पर राइट-क्लिक करने के बाद विस्तारित होने वाले मेनू से Add -> Threads (Users) -> Thread Group चुनें:
उपयोगकर्ताओं की संख्या और अतिरिक्त विशेषताएं निर्दिष्ट करें:
HTTP अनुरोध कॉन्फ़िगर करें
पिछले चरण में बनाए गए थ्रेड पर राइट-क्लिक करें और Add -> Sampler -> HTTP Request चुनें:
प्रोटोकॉल, सर्वर नाम, पोर्ट, और अनुरोध का पथ कॉन्फ़िगर करें:
परिणाम दृश्य निर्दिष्ट करें
HTTP अनुरोध पर राइट-क्लिक करें और Add -> Listener -> View Results Tree चुनें:
टेस्ट चलाना
टेस्ट अब कॉन्फ़िगर किया गया है, और हम इसे ट्रिगर कर सकते हैं। ऐसा करने के लिए, बस हरे प्ले बटन पर क्लिक करें:
जैसा कि आप देख सकते हैं, एप्लिकेशन ने टेस्ट पास कर दिया, लेकिन यह सिर्फ एक अनुरोध था, इसलिए परिणाम स्पष्ट था। अब आप उपयोगकर्ताओं की संख्या और अन्य कॉन्फ़िगरेशन विकल्पों के साथ प्रयोग कर सकते हैं यह देखने के लिए कि एप्लिकेशन कैसे व्यवहार करेगा। मेरे टेस्ट से, सरल ऐप तब क्रैश होने लगा जब लगभग 200 उपयोगकर्ता एक साथ इसे एक्सेस करने लगे।
अगले कदम
लोड टेस्ट करने के बाद, आप अपने एप्लिकेशन के दर्द बिंदुओं को जान जाएंगे। उपयोगकर्ता सीमा को समझकर, अब आप यह देखने के लिए स्ट्रेस टेस्ट कर सकते हैं कि एप्लिकेशन कैसे व्यवहार करेगा।
ruby-prof के साथ प्रदर्शन टेस्ट
प्रदर्शन टेस्ट सुविधा Rails में संस्करण 3 तक अंतर्निहित थी, और फिर इसे अलग जेम https://github.com/rails/rails-perftest में निकाला गया। चूंकि मुझे नवीनतम संस्करण के साथ इसका उपयोग करने में कुछ समस्याएं थीं, इसलिए मैंने इसे इस लेख में शामिल नहीं करने का फैसला किया। इसके बजाय, मैं ruby-prof लाइब्रेरी का उपयोग करूंगा जो बहुत अच्छी तरह से काम करती है।
हमेशा की तरह, पहला कदम हमारे एप्लिकेशन में एक जेम जोड़ना है:
bundle add ruby-prof
कॉन्फ़िगरेशन प्रक्रिया का दूसरा और अंतिम चरण config/application.rb को अपडेट करना और जेम के लिए मिडलवेयर का उपयोग करना है ताकि लाइब्रेरी स्वचालित रूप से हमारे अनुरोधों का निरीक्षण कर सके और उन पर आधारित रिपोर्ट तैयार कर सके:
module Simpleapp class Application < Rails::Application config.middleware.use Rack::RubyProf, :path => './tmp/profile' end end
अब आप ऐप एक्सेस कर सकते हैं, और हर बार जब आप एक अनुरोध करते हैं, तो जेम एक नई रिपोर्ट उत्पन्न करेगा। यह ऐसा दिखता है:
आप इसे कॉन्फ़िगर किए गए पथ के तहत पा सकते हैं, जो हमारे मामले में tmp/profile है। दूसरी रिपोर्ट भी उत्पन्न होती है, और यह कॉल स्टैक दिखाती है, जो Rails एप्लिकेशन में प्रदर्शन समस्याओं को डीबग करते समय भी एक बहुत उपयोगी मेट्रिक है।
यह याद रखना महत्वपूर्ण है कि cache_classes और cache_template_loading सेटिंग्स को true पर सेट करने से एप्लिकेशन धीमा हो जाएगा और एप्लिकेशन मेट्रिक्स पर हावी हो जाएगा क्योंकि Rails आवश्यक फ़ाइलों को लोड करने का प्रयास करेगा।
सारांश
परीक्षण हर विकास प्रक्रिया का एक अनिवार्य हिस्सा है। यह जांचना कि कोड वैसा ही व्यवहार करता है जैसा हम चाहते हैं, यह सत्यापित करने जितना ही महत्वपूर्ण है कि हमारे समाधानों का प्रदर्शन अच्छा है। टेस्ट छोड़ने से गंभीर समस्याएं होती हैं जो ऐप के प्रदर्शन और आपके उपयोगकर्ताओं के विश्वास को प्रभावित करती हैं। उम्मीद है, परीक्षण इतना कठिन नहीं है।
इस लेख में, हमने परीक्षण के निम्नलिखित महत्वपूर्ण पहलुओं को कवर किया:
- आपको अपना कोड क्यों टेस्ट करना चाहिए
- प्रदर्शन टेस्ट के विभिन्न प्रकार
- अपने Rails ऐप के प्रदर्शन का परीक्षण करने का तरीका
मुझे आशा है कि अब आप इस बात से अधिक आश्वस्त हैं कि टेस्ट लिखना महत्वपूर्ण है क्योंकि आप जानते हैं कि क्यों और कैसे।
यदि आप अपने ऐप के प्रदर्शन की निगरानी न केवल स्थानीय रूप से बल्कि उत्पादन या स्टेजिंग वातावरण में भी करना चाहते हैं, तो आपको AppSignal भी देखना चाहिए।
P.S. यदि आप Ruby Magic पोस्ट को प्रेस से निकलते ही पढ़ना चाहते हैं, तो हमारे Ruby Magic न्यूज़लेटर की सदस्यता लें और कभी भी एक भी पोस्ट मिस न करें!