রুবি/রেল বিকাশকারী হিসাবে, আমরা পরীক্ষা লিখতে পছন্দ করি। পরীক্ষা সফ্টওয়্যার বিকাশের একটি অবিচ্ছেদ্য অংশ। ভাল পরীক্ষা আমাদের উচ্চ-মানের কোড লিখতে সাহায্য করে। তারা সামগ্রিক উন্নয়ন প্রক্রিয়ায় মূল্য যোগ করে, কিন্তু আমরা যদি পরীক্ষাটি ভালভাবে পরিচালনা না করি তবে তারা আমাদের ধীর করে দিতে পারে। এখানে পরীক্ষার কিছু লক্ষণ রয়েছে যা ভুলভাবে পরিচালিত হয়:
- পরীক্ষা চালাতে অনেক সময় লাগে।
- পরীক্ষাগুলি অবিশ্বস্ত এবং এলোমেলোভাবে ব্যর্থ হয়৷ ৷
- বিভিন্ন মেশিনে পরীক্ষাগুলো ভিন্নভাবে আচরণ করে।
- সমস্ত টেস্ট স্যুট চালানো আপনার সিআইকে ধীর করে দেয়।
এই ব্লগ পোস্টে, আমরা কভার করব কিভাবে কন্টেইনারগুলি পরীক্ষাকে নির্ভরযোগ্য করতে ব্যবহার করা যেতে পারে, যা উচ্চ-মানের সফ্টওয়্যার সরবরাহ করতে সহায়ক৷
একীকরণ পরীক্ষা এবং ইউনিট পরীক্ষা
কনটেইনারগুলির বিষয়ে ঝাঁপিয়ে পড়ার আগে, আসুন আমরা প্রথমে বুঝতে পারি এবং একক এবং ইন্টিগ্রেশন পরীক্ষার মধ্যে পার্থক্য সম্পর্কে একই পৃষ্ঠায় থাকি৷
ইউনিট পরীক্ষাগুলি বিচ্ছিন্নভাবে কোডের ব্লক পরীক্ষা করার একটি উপায়। তারা কোড ব্লকের কার্যকারিতা পরীক্ষা করতে সাহায্য করে কিন্তু নির্ভরতা নয়। উদাহরণস্বরূপ, এখানে একটি সহজ পদ্ধতি:
def sum(a, b)
a + b
end
এটি একটি ফাংশন যা দুটি সংখ্যা যোগ করে, যা খুবই সহজ। এই ফাংশন পরীক্ষা করা সুপার সহজ হবে. কিন্তু যদি এই ফাংশনটির একটি বহিরাগত পরিষেবার উপর নির্ভরতা থাকে তবে কী হবে। এই পদ্ধতিটি যোগফল সম্পূর্ণ করার পরে ডাটাবেসে লিখতে হবে।
def sum!(a, b)
c = a + b
Sum.create(value: c)
end
কোডের এই ব্লকে, মানগুলি যোগ করা হয় এবং একটি ডাটাবেসে সংরক্ষিত হয়। কোডের এই ব্লকটি পরীক্ষা করার জন্য, আমাদের একটি ডাটাবেস সার্ভার চালু থাকতে হবে। যদি আমরা ডাটাবেস সার্ভারের সাথে এটি পরীক্ষা করি তবে এটি আর একটি ইউনিট পরীক্ষা নয়। এর জন্য বাহ্যিক নির্ভরতা প্রয়োজন, এবং আমরা ডাটাবেস সংযোগ পরীক্ষা করব এবং ডাটাবেসে রেকর্ড সংরক্ষণ করা হয়েছে কিনা। এই ক্ষেত্রে, এই পরীক্ষাটি একটি ইন্টিগ্রেশন পরীক্ষা।
ইউনিট পরীক্ষা একক ইউনিট পরীক্ষা হতে পারে (মক/স্টাব সমস্ত নির্ভরতা) অথবা সমাজযোগ্য ইউনিট পরীক্ষা (অন্যান্য নির্ভরতার সাথে কথা বলার অনুমতি দিন)। লোকেরা ইউনিট পরীক্ষার বিভিন্ন সংজ্ঞা প্রস্তাব করেছে। এই ব্লগের প্রেক্ষাপটে, আমরা যে ধরনের ইউনিট পরীক্ষার কথা বলছি তা হল সলিটারি ইউনিট টেস্ট।
মক দিয়ে বাহ্যিক নির্ভরতা দূর করা পরীক্ষাগুলিকে দ্রুত চালাতে সাহায্য করে। ইউনিট পরীক্ষাগুলি ব্যবহার করার সময়, আমরা এই নির্ভরতাগুলি ত্যাগ করি, তবে অ্যাপ্লিকেশনটি প্রত্যাশিত হিসাবে কাজ করে তা নিশ্চিত করার জন্য, নির্ভরতা পরীক্ষা করা সমান গুরুত্বপূর্ণ। ডাটাবেস, নেটওয়ার্ক কল এবং ফাইলের মতো এই বাহ্যিক নির্ভরতাগুলি পরীক্ষা করার জন্য আমরা যে পরীক্ষাগুলি লিখি তা হল ইন্টিগ্রেশন পরীক্ষা .
ইউনিট পরীক্ষার মতো, লোকেরা ইন্টিগ্রেশন পরীক্ষার বিভিন্ন সংজ্ঞা প্রস্তাব করেছে। যাইহোক, মৌলিক ধারণা একই। পার্থক্য শুধু পরিধিতে। একটি ডাটাবেসে লেখা একটি ছোট ফাংশন একটি ইন্টিগ্রেশন পরীক্ষা হতে পারে। একটি বিস্তৃত কার্যকারিতা যা সিস্টেমের একাধিক অংশকে সংযুক্ত করে সেটিও একটি ইন্টিগ্রেশন পরীক্ষা। আমরা এখানে যে পরীক্ষাটির কথা বলছি তা সংকীর্ণ অংশের উপর বেশি মনোযোগী। পরীক্ষা যত সংকীর্ণ হবে, তত বেশি পরীক্ষা আমাদের লিখতে হবে। বৃহত্তর পরীক্ষার সাথে, তবে, প্রয়োজনীয় পরীক্ষার সংখ্যা হ্রাস পায়।
একটি ইন্টিগ্রেশন পরীক্ষা চালানোর সময়, আমাদের অ্যাপ্লিকেশন এবং নির্ভরতা, যেমন ডাটাবেস এবং বহিরাগত পরিষেবাগুলি চালানোর প্রয়োজন হয়৷ এই নির্ভরতাগুলি পরিচালনা করা চ্যালেঞ্জিং হতে পারে৷
ডকারের মৌলিক বিষয়গুলি
ডকার একটি প্রযুক্তি যা একটি অ্যাপ্লিকেশনকে এর পরিবেশ (অপারেটিং সিস্টেম) থেকে বিমূর্ত করতে এবং হোস্টের সাথে বিচ্ছিন্নভাবে চালাতে সহায়তা করে। এটি একটি ভার্চুয়াল মেশিনের মতো তবে দ্রুত এবং আরও দক্ষ। ডকার আমাদের অ্যাপ্লিকেশন কোড এবং এর নির্ভরতাগুলিকে একটি একক পাত্রে প্যাকেজ করার অনুমতি দেয়। এটি কোডটিকে পোর্টেবল করতে সাহায্য করে এবং এর মানে হল যে ডেভেলপমেন্ট, টেস্টিং এবং প্রোডাকশনের সময় আমাদের একই ডকার ইমেজ চলতে পারে। এটি অ্যাপ্লিকেশনটি চালানোর পরিবেশের সামঞ্জস্যতা নিশ্চিত করবে। যেহেতু এটি হোস্ট সার্ভারের উপর নির্ভরশীল নয়, এটি সমস্ত পরিবেশে অ্যাপ্লিকেশনের আচরণকে অনুমানযোগ্য করে তোলে। ডকার ডেভেলপারদের সহজ কমান্ড ব্যবহার করে বিল্ডিং, রানিং, ডিপ্লোয়িং এবং আপডেট সহ অ্যাপ্লিকেশন এবং এর পরিবেশ চালাতে এবং পরিচালনা করতে সহায়তা করে৷
আসুন কিছু গুরুত্বপূর্ণ পরিভাষা বুঝি:
-
ডকারফাইল - একটি ডকারফাইল হল একটি ফাইল যেখানে আমরা অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় নির্ভরতা সংজ্ঞায়িত করি। আমরা এটির প্রয়োজনীয় অপারেটিং সিস্টেম, ডাটাবেস ক্লায়েন্ট লাইব্রেরি বা অ্যাপ্লিকেশনের জন্য প্রয়োজনীয় যে কোনও প্যাকেজ নির্দিষ্ট করতে পারি। এখানে, আমরা অ্যাপ্লিকেশন চালানোর জন্য প্রয়োজনীয় কমান্ডটিও সংজ্ঞায়িত করি। একটি ডকারফাইল একটি বেস ইমেজ থেকে শুরু হয়। এই বেস ইমেজ একটি অপারেটিং সিস্টেম বা একটি প্রোগ্রামিং ভাষা হতে পারে.
-
ছবি - চিত্রগুলি একটি ব্লুপ্রিন্ট যা একটি কন্টেইনার চালানোর জন্য প্রয়োজনীয় পদক্ষেপগুলি বর্ণনা করে৷ ইমেজ বিভিন্ন স্তর সঙ্গে নির্মিত হয়. একটি ডকারফাইলে সংজ্ঞায়িত প্রতিটি পদক্ষেপ চিত্রের মধ্যে একটি স্তর। এটি পুনঃব্যবহারযোগ্যতা বাড়ায় এবং দ্রুত ইমেজ তৈরি করতে মধ্যবর্তী স্তর ক্যাশে করতে সাহায্য করে৷
-
পাত্রে - কন্টেইনার হল আসল ছবি। এগুলি থেমে থাকা অবস্থায়ও হতে পারে। ধারক একটি ডকার ইমেজ থেকে শুরু করা যেতে পারে. একটি একক ডকার ইমেজ একাধিক ডকার কন্টেইনার শুরু করতে পারে। ধারকগুলি চিত্র দ্বারা নির্দিষ্ট করা তথ্য ধারণ করে৷ একটি পাতলা পাত্রের স্তর রয়েছে যেখানে অ্যাপ্লিকেশনটি চলাকালীন ছবিতে করা সমস্ত পরিবর্তন সংরক্ষণ করা হয়৷
-
ডকার রচনা - ডকার কম্পোজ একটি ভিন্ন টুল যা একাধিক কন্টেইনার পরিচালনা করতে সাহায্য করে। আমাদের একই ডকার ইমেজ থেকে একাধিক পাত্র থাকতে পারে। আমাদের বিভিন্ন ডকার ইমেজ থেকে একাধিক পাত্রের প্রয়োজন হতে পারে, এবং এই পাত্রগুলির একে অপরের সাথে যোগাযোগ করতে হবে। ডকার কম্পোজ পাত্রে পরিচালনা করে। অন্যান্য টুল উপলব্ধ আছে, কিন্তু এই প্রসঙ্গে, আমরা শুধুমাত্র ডকার কম্পোজ ব্যবহার করব কারণ এর সরলতার জন্য।
ভার্চুয়াল মেশিনগুলি হোস্ট হাইপারভাইজারের উপরে থাকে এবং একটি পৃথক অপারেটিং সিস্টেম ইনস্টল করা প্রয়োজন, তাই আরও হোস্ট সংস্থান ব্যবহার করা হয়। যাইহোক, ডকারের সাথে, আমাদের শুধুমাত্র হোস্ট অপারেটিং সিস্টেমে একটি ডকার ইঞ্জিন ইনস্টল করতে হবে এবং হোস্ট রিসোর্স ম্যানেজমেন্ট ডকার দ্বারা করা হয়। ডকার ডেভেলপার এবং সিসপ উভয়ের জন্যই জীবনকে সহজ করতে সাহায্য করে, তাই এটি DevOps সংস্কৃতিতে খুবই জনপ্রিয়।
পরীক্ষার জন্য ডকার কেন ব্যবহার করবেন
ডকার চলমান অ্যাপ্লিকেশন বা পরীক্ষাটিকে তার হোস্ট পরিবেশ থেকে ন্যূনতম সম্পদ খরচের সাথে বিচ্ছিন্ন করে। এখানে পরীক্ষার জন্য ডকার ব্যবহার করার কিছু সুবিধা রয়েছে:
-
হালকা: ডকার পাত্রে হালকা হয়. এটি একই সময়ে একাধিক কন্টেইনার চালাতে সাহায্য করে এবং একটি পরীক্ষা প্রক্রিয়া ছাড়াই অন্য পরীক্ষার প্রক্রিয়ায় সমস্যা সৃষ্টি করে।
-
পোর্টেবল: ডকার ইমেজ পোর্টেবল এবং যেকোনো পরিবেশে চলতে পারে। এটি CI-তে সাহায্য করে, কারণ আমরা স্থানীয় এবং CI পরিবেশে পরীক্ষা চালানোর জন্য একই চিত্র পুনরায় ব্যবহার করতে পারি।
-
সংস্করণ: একাধিক অ্যাপ্লিকেশন ব্যবহার বা আমাদের নির্ভরতা আপগ্রেড করার জন্য আমাদের স্থানীয় মেশিনে আমাদের নির্ভরতাগুলির বিভিন্ন সংস্করণ প্রয়োজন। ডকার ছাড়া এটি পরিচালনা করা খুব কঠিন হবে। ডকারের সাথে, আমাদের কাছে ভিন্ন সংস্করণের সাথে চলমান বিভিন্ন পাত্র থাকতে পারে। আমরা বিভিন্ন সংস্করণে পরীক্ষা চালাতে পারি এবং জিনিসগুলি যাচাই করতে পারি।
-
মাইক্রোসার্ভিসের সহজ ব্যবস্থাপনা :মাইক্রোসার্ভিসের সাথে, পরীক্ষাও বিতরণ করা হয় এবং জটিল হয়। এর মানে আমাদের নির্ভরশীল মাইক্রোসার্ভিস পরিচালনা করতে হবে। ডকার এবং ডকার কম্পোজ এই পরিষেবা নির্ভরতাগুলি পরিচালনা করতে সহায়তা করে৷
প্রাক-প্রয়োজনীয়
এটি চেষ্টা করার জন্য, আসুন নিশ্চিত করি যে নিম্নলিখিতগুলি সেট আপ করা হয়েছে:
- ডকার
- ডকার-কম্পোজ
- রুবি 2.7 (ঐচ্ছিক, যেহেতু আমরা রুবিকে ডকার কন্টেইনারে যুক্ত করব, তবে এটি পরীক্ষার জন্য সহায়ক হবে)
- রেল (5.1+ প্রস্তাবিত)
অ্যাপটিকে ডকারাইজ করুন
আসুন একটি সাধারণ রেল অ্যাপ তৈরি করে এটিকে কন্টেইনারাইজ করে শুরু করি। আমি একটি নতুন রেল অ্যাপ দিয়ে শুরু করছি। আপনি বিদ্যমান রেল অ্যাপটিও কনটেইনারাইজ করতে পারেন।
rails new calculator
Dockerfile
নামে একটি ফাইল তৈরি করুন নিম্নলিখিত বিষয়বস্তু সহ:
FROM ruby:2.7
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN mkdir /calculator
WORKDIR /calculator
COPY Gemfile /calculator/Gemfile
COPY Gemfile.lock /calculator/Gemfile.lock
RUN bundle install
COPY package.json /calculator/package.json
COPY yarn.lock /calculator/yarn.lock
RUN yarn install --check-files
COPY . /calculator
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
আমরা সংজ্ঞায়িত ডকারফাইলের একটি রুবি 2.7 বেস ইমেজ রয়েছে। আমাদের NodeJS এবং Yarn দরকার, তাই পরবর্তী ধাপ হল সেগুলি ইনস্টল করা। একবার সেগুলি ইনস্টল হয়ে গেলে, আমরা bundle install
চালাই এবং yarn install
. অবশেষে, আমরা সমস্ত কোড কপি করি এবং রপ্তানি করা 3000 পোর্ট সহ রেল সার্ভার চালাই। এটি একটি খুব সাধারণ ডকারফাইল। এটির সাথে, আমাদের রেল অ্যাপটি ডকারাইজ করা হয়েছে।
এখন আমরা ডকার ইমেজ তৈরি এবং চালাতে পারি তা নিশ্চিত করতে এটি চলছে।
ডকার ইমেজ তৈরি করুন:
docker build . -t calculator
ধারক চালান:
docker run -p 3000:3000 calculator
ক্যালকুলেশন লজিক দিয়ে একটি মডেল তৈরি করুন
আসুন আমরা গণনা নামে একটি মডেল তৈরি করি যেখানে আমরা আমাদের গণনার যুক্তি যোগ করতে পারি। আমরা তাদের জন্য কিছু যুক্তি এবং পরীক্ষা লিখতে এই মডেলটি ব্যবহার করব। ডকার কম্পোজ ব্যবহার করে আমরা কীভাবে এই পরীক্ষার নির্ভরতাগুলি পরিচালনা করতে পারি তা আমরা দেখতে পারি।
আমরা বর্তমানে SQLite এর সাথে রেল চালাচ্ছি। আসুন SQLite এর পরিবর্তে Postgres এ পরিবর্তন করি। নিম্নলিখিত কমান্ডের সাহায্যে এটি সহজেই করা যেতে পারে:
rails db:system:change --to=postgresql
একটি গণনা মডেল তৈরি করুন:
bundle exec rails generate model calculation
গণনার স্কিমাতে কিছু ক্ষেত্র যোগ করুন:
# db/migrate/create_calculation.rb
class CreateCalculations < ActiveRecord::Migration[6.0]
def change
create_table :calculations do |t|
t.integer :x
t.integer :y
t.integer :result
t.timestamps
end
end
end
এর পরে, আসুন ডাটাবেসটি কনটেইনারের ভিতরে মাইগ্রেশন চালানোর চেষ্টা করি:
docker-compose exec web rails db:migrate
যেহেতু ডাটাবেসটি কন্টেইনারের ভিতরে চলছে না, তাই এই কমান্ডটি চালানোর ফলে একটি ত্রুটি হবে।
rake aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
আমরা একটি পোস্টগ্রেস ইমেজ অন্য ইমেজ হিসাবে চালাতে পারি এবং তাদের মধ্যে একটি নেটওয়ার্ক যোগ করতে পারি। এই কন্টেইনার যোগাযোগ পরিচালনা করতে, আমরা ডকার কম্পোজ ব্যবহার করতে পারি।
একাধিক কন্টেইনার পরিচালনা করতে ডকার রচনা ব্যবহার করা
রেল অ্যাপ কন্টেইনারাইজডের সাথে, আমরা ডকার কম্পোজ ব্যবহার করে পরিষেবাতে নির্ভরতা যোগ করতে পারি। আবেদনের উপর নির্ভরতা পোস্টগ্রেস।
পোস্টগ্রেস ডকার চিত্রটি সর্বজনীনভাবে উপলব্ধ, তাই আমাদের একটি তৈরি করার দরকার নেই। যাইহোক, আমাদের ডাটাবেস কন্টেইনার এবং আমাদের রেল অ্যাপ কন্টেইনার পরিচালনা করতে হবে।
version: "3.0"
services:
db:
image: postgres
environment:
POSTGRES_USER: calculator
POSTGRES_PASSWORD: password
POSTGRES_DB: calculator_test
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
CALCULATOR_DATABASE_PASSWORD: password
এখন, database.yaml
-এ যান ফাইল করুন এবং ডাটাবেসটিকে একটি ভিন্ন হোস্টে পরিবর্তন করুন। হোস্টটি ডকার কম্পোজ ফাইলে পরিষেবার ভিতরে নির্দিষ্ট করা নাম হবে। আমাদের ক্ষেত্রে, হোস্ট হল db
. নিশ্চিত করুন যে DB পাসওয়ার্ডটি postgres
-এ একই পরিষেবা এবং web
সেবা এছাড়াও, ডকার কম্পোজ ফাইলে উল্লেখিত ব্যবহারকারীর নাম, পাসওয়ার্ড এবং ডাটাবেসের নাম পরিবর্তন করুন।
# database.yaml
development:
<<: *default
database: calculator_development
username: calculator
password: <%= ENV['CALCULATOR_DATABASE_PASSWORD'] %>
এখন, আমরা একটি একক কমান্ড ব্যবহার করে কন্টেইনারগুলি শুরু করতে পারি:
docker-compose up
এটি ডাটাবেস এবং আমাদের রেল সার্ভার উভয়ই শুরু করবে। আমরা এখন মাইগ্রেশন কমান্ড চালাতে পারি, এবং এটি পোস্টগ্রেসের সাথে সংযোগ করতে এবং মাইগ্রেশন চালাতে সক্ষম হওয়া উচিত।
পরীক্ষা যোগ করা
এখন যেহেতু আমরা সমস্ত সেটআপ প্রস্তুত করেছি, আসুন মডেলের ভিতরে একটি সহজ পদ্ধতি লিখি এবং পদ্ধতিটি পরীক্ষা করি:
# calculation.rb
class Calculation < ApplicationRecord
def self.sum(x, y)
result = x + y
Calculation.create(x: x, y: y, result: result)
result
end
end
এই যোগ পদ্ধতি শুধুমাত্র সংখ্যা যোগ করে না কিন্তু একটি ডাটাবেসে সংখ্যা সংরক্ষণ করে। সুতরাং, এই পদ্ধতিটি পরীক্ষা করার জন্য একটি ডাটাবেস দৃষ্টান্ত প্রয়োজন।
এই পরীক্ষাটি একটি ইন্টিগ্রেশন পরীক্ষা হবে, কারণ আমাদের অবশ্যই একটি ডাটাবেসের সাথে সংযোগ করতে হবে।
আমরা পরীক্ষা লিখতে মিনি-টেস্ট ব্যবহার করব, যা রেলের ডিফল্ট।
# calculation_test.rb
require 'test_helper'
class CalculationTest < ActiveSupport::TestCase
test "should sum and save the data" do
result = Calculation.sum(1, 2)
c = Calculation.last
assert result, 3
assert c.result, result
end
end
পরীক্ষা চালান:
docker-compose exec web rails test
উপরের পরীক্ষায়, আমরা পরীক্ষা করছি যে যোগ পদ্ধতিটি মানগুলি যোগ করছে এবং ডেটাবেসে মানগুলি সংরক্ষণ করছে কিনা। ডকার কম্পোজের সাথে, আমাদের কাছে ডাটাবেসের সাথে সংযোগ করার একটি খুব সহজ উপায় রয়েছে৷
এখানে, পদ্ধতি ডাটাবেসের উপর নির্ভরশীল। নির্ভরতা শুধুমাত্র একটি ডাটাবেস নয় বরং একটি তৃতীয় পক্ষের পরিষেবাও হতে পারে যা একটি REST API প্রদান করে। সুতরাং, আসুন আমরা একটি তৃতীয় পক্ষের পরিষেবা ব্যবহার করার চেষ্টা করি যা একটি sum
প্রদান করে পদ্ধতি, যা আমরা নিজেদের লেখার পরিবর্তে ব্যবহার করতে পারি।
# calculation.rb
class Calculation < ApplicationRecord
def self.sum(x, y)
# The hostname should be the same as it is specified in the docker-compose file
url = 'https://sumservice:4010/sum'
uri = URI(url)
params = { :x => x, :y => y }
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
throw "Error" unless res.is_a?(Net::HTTPSuccess)
result = res.body.to_i
Calculation.create(x: x, y: y, result: result)
result
end
end
আমরা REST API-এর জন্য অনুরূপ কিছু করতে পারি যা আমরা নির্ভরতা হিসাবে ডাটাবেসের জন্য করেছি। আমাদের নিশ্চিত করতে হবে যে এগুলি বৈধ শেষ পয়েন্ট, কিন্তু আমরা পরীক্ষার সময় প্রকৃত পরিষেবাতে কল করতে চাই না। এই ক্ষেত্রে, আমরা মক/স্টাব পরীক্ষা তৈরি করতে পারি, কিন্তু আমরা যদি তা করি তবে এই পরীক্ষাগুলি একটি ইন্টিগ্রেশন পরীক্ষা হবে না। আমরা নিশ্চিত করতে চাই যে পরীক্ষা যতটা সম্ভব বাস্তবসম্মত। এই উদ্দেশ্যে, আমরা একটি মক এপিআই এন্ডপয়েন্ট তৈরি করতে পারি, যা আমরা একটি কন্টেইনারে চালাব এবং মক কন্টেইনার এপিআই পরিষেবাতে কল করব, যা ফলাফলের সাথে আমাদের প্রতিক্রিয়া জানাবে।
আসুন প্রথমে পরীক্ষাটি পরিবর্তন করি:
# calculation_test.rb
require 'test_helper'
class CalculationTest < ActiveSupport::TestCase
test "should sum and save the data" do
result = Calculation.sum(1, 2)
c = Calculation.last
# we don't need this assetion as we are deligation this responsibility to external service:
# assert result, 3 // Not needed
assert c.result, result
end
end
এখানে, আমরা পরীক্ষার ক্ষেত্রে পরিবর্তন করেছি শুধুমাত্র পরীক্ষা করার জন্য যে সম API দ্বারা প্রদত্ত ফলাফল ডাটাবেসে সঠিকভাবে সংরক্ষিত হয়েছে কিনা। যোগফলের প্রকৃত মান সঠিক কিনা তা আমাদের পরীক্ষা করার দরকার নেই, কারণ এটি বহিরাগত পরিষেবা দ্বারা পরিচালিত হয় এবং আমরা তাদের বিশ্বাস করি।
একটি মক সার্ভার তৈরি করতে, আমরা openAPI ব্যবহার করব। আসুন একটি সাধারণ swagger সংজ্ঞা তৈরি করি:
রুট ডিরেক্টরিতে একটি নতুন ফোল্ডার তৈরি করুন এবং এটির নাম দিন mock
. ফোল্ডারের ভিতরে, একটি ফাইলের নাম api.yaml
তৈরি করুন
# api.yaml
swagger: "2.0"
info:
description: "This is a sum api provider"
version: "1.0.0"
title: "API Provider"
host: "https://mock-service.com/"
basePath: "/api"
schemes:
- "https"
- "http"
paths:
/sum:
get:
produces:
- "application/json"
parameters:
- name: "x"
in: "query"
description: "x value"
required: true
type: "integer"
- name: "y"
in: "query"
description: "y value"
required: true
type: "integer"
responses:
"200":
description: "successful operation"
schema:
type: "integer"
example: 3
স্পেসিফিকেশনের উপর ভিত্তি করে এই সার্ভারটি চালানোর জন্য, আমরা যে কোনও মক পরিষেবা প্রদানকারী ব্যবহার করতে পারি। আমি প্রিজম নামক একটি টুল ব্যবহার করব। এটিতে একটি ডকার ইমেজ উপলব্ধ রয়েছে, যা আমরা আমাদের ডকার-কম্পোজ ফাইলে যোগ করতে পারি:
version: "3.0"
services:
db:
image: postgres
environment:
POSTGRES_USER: calculator
POSTGRES_PASSWORD: password
POSTGRES_DB: calculator_test
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
- sumservice
environment:
CALCULATOR_DATABASE_PASSWORD: password
sumservice:
image: stoplight/prism:4
command: mock -h 0.0.0.0 "/tmp/api.yaml"
volumes:
- ./mock:/tmp/
ports:
- 4010:4010
init: true
এখন, পরীক্ষাটি চালানো যাক এবং দেখুন এটি প্রত্যাশিতভাবে কাজ করছে কিনা:
> docker-compose exec web rails test
Finished in 0.337710s, 2.9611 runs/s, 5.9222 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
হ্যাঁ! আমাদের এখন পরীক্ষা চলছে। পদ্ধতিটি যোগফল পাওয়ার জন্য যোগ সার্ভিস ডকার ইমেজের সাথে সংযোগ করে এবং ডেটা সংরক্ষণ করতে পোস্টগ্রেসের সাথে সংযোগ করে। সমস্ত নির্ভরতা ডকার কম্পোজ দ্বারা পরিচালিত হয়, তাই আমাদের পূর্বে ইনস্টল হওয়া নির্ভরতা সম্পর্কে চিন্তা করার দরকার নেই। এই পরীক্ষাটি যেকোনো মেশিনে স্থানান্তর করা কোনো নির্ভরতা ইনস্টলেশনের প্রয়োজন ছাড়াই কাজ করবে। যন্ত্রের জন্য শুধুমাত্র একটি ডকার প্রয়োজন।
যদি আপনার আবেদন অন্য কোনো নির্ভরতার উপর নির্ভর করে, যেমন Redis বা Memcached, এগুলো ডকারহাবে পাওয়া যাবে। আমরা এই ছবিগুলিকে আমাদের ডকার কম্পোজ ফাইলে যোগ করতে পারি।
সমান্তরাল পরীক্ষা
রেল 5.1.5+ সমান্তরালভাবে চলমান পরীক্ষা সমর্থন করে। ডিফল্টরূপে, পরীক্ষাগুলি প্রসেসরের সংখ্যার উপর ভিত্তি করে রেল 6 থেকে সমান্তরালে চলে। একটি পরীক্ষা চালানোর সময়, এটি সমান্তরাল পরীক্ষার সংখ্যার উপর ভিত্তি করে ডাটাবেস উদাহরণ তৈরি করে। যদি আমাদের চারটি প্রসেসর থাকে তবে এটি "ক্যালকুলেটর_টেস্ট-0", ক্যালকুলেটর_টেস্ট-1, ক্যালকুলেটর_টেস্ট-2 এবং ক্যালকুলেটর_টেস্ট-3 ডেটাবেস তৈরি করে। আপনি যদি postgres cli এ যান এবং ডাটাবেসগুলি পরীক্ষা করেন, আপনি নিম্নলিখিতগুলি দেখতে পাবেন:
> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------------+------------+----------+------------+------------+---------------------------
calculator_test | calculator | UTF8 | en_US.utf8 | en_US.utf8 |
calculator_test-0 | calculator | UTF8 | en_US.utf8 | en_US.utf8 |
calculator_test-1 | calculator | UTF8 | en_US.utf8 | en_US.utf8 |
calculator_test-2 | calculator | UTF8 | en_US.utf8 | en_US.utf8 |
calculator_test-3 | calculator | UTF8 | en_US.utf8 | en_US.utf8 |
এখন, এমনকি আপনি যদি রেল বা মিনি-টেস্ট ব্যবহার না করেন বা রেলের একটি পুরানো সংস্করণ না থাকে, আপনি এখনও সমান্তরালভাবে পরীক্ষা চালান যদি আপনি সেগুলি ডকার দিয়ে লেখেন। রেলগুলি সমান্তরাল পরীক্ষার জন্য স্বয়ংক্রিয়ভাবে ডাটাবেস তৈরি করে, তবে যদি অন্য কোনও নির্ভরতা থাকে, যেমন রেডিস বা মেমক্যাশ, সেগুলিকে ম্যানুয়ালি পরিচালনা করতে হতে পারে৷
যেহেতু আমরা আমাদের সমস্ত নির্ভরতা পরিচালনা করেছি, আমরা সমান্তরালভাবে পরীক্ষা চালানোর জন্য বিভিন্ন আর্গুমেন্ট সহ ডকার কম্পোজ চালাতে পারি। এই উদ্দেশ্যে, আমরা নির্দিষ্ট করতে পারি কোন ফোল্ডারে আমরা সমান্তরালভাবে পরীক্ষা চালাতে চাই, একাধিক ডকার কম্পোজ ফাইল তৈরি করতে এবং সমান্তরালে চালাতে চাই।
কমান্ড সরলীকরণ করতে মেকফাইল যোগ করা
যেহেতু আমরা আমাদের পরীক্ষা চালানোর জন্য ডকার এবং ডকার কম্পোজ কমান্ড ব্যবহার করছি, কমান্ডগুলি দীর্ঘ। প্রতিদিনের উন্নয়ন করার সময় তাদের মনে রাখা এবং চালানো কঠিন হতে পারে। এটিকে একটি সাধারণ কমান্ডে সরল করতে, আসুন মেকফাইল যোগ করুন। মেকফাইল হল একটি সাধারণ টেক্সট ফাইল যা টার্গেট কমান্ড এক্সিকিউশনের জন্য ব্যবহৃত হয়।
.PHONY: test
up:
docker-compose up
down:
docker-compose down
test:
docker-compose exec web rails test
আমরা মেকফাইলে কয়েকটি কমান্ড যুক্ত করেছি। এটি আবেদনের প্রয়োজন অনুসারে বাড়ানো যেতে পারে। Rails অ্যাপ্লিকেশনের রুট ডিরেক্টরিতে makefile যোগ করুন। একবার আমাদের কাছে এই মেকফাইলটি হয়ে গেলে, আমরা কেবল নিম্নলিখিত কমান্ডটি ব্যবহার করে পরীক্ষা চালাতে পারি:
পাত্রে বুট করুন:
> make up
পরীক্ষা চালান:
> make test
স্থানীয় উন্নয়নের জন্য ডকার ব্যবহার করা
অ্যাপ্লিকেশন বিকাশ করার সময় আমরা ডকার ব্যবহার করতে পারি। এটি নিশ্চিত করতে সহায়তা করে যে অ্যাপ্লিকেশনটি পরীক্ষা, বিকাশ এবং উত্পাদন জুড়ে ধারাবাহিকভাবে আচরণ করে। স্থানীয় উন্নয়নের জন্য উপরের কন্টেইনার ব্যবহার করার জন্য আমাদের কী পরিবর্তন করতে হবে তা পর্যালোচনা করা যাক।
ভলিউম মাউন্ট
স্থানীয়ভাবে অ্যাপ্লিকেশন চালানোর সময়, আমরা কোডে পরিবর্তন করার সময় অ্যাপ্লিকেশনটি স্থানীয় সার্ভারে পরিবর্তনগুলি প্রতিফলিত করতে চাই। বর্তমান পরিস্থিতিতে, কোডটি আমাদের মেশিন থেকে ডকারে অনুলিপি করা হয়েছে এবং সার্ভারটি শুরু হয়েছে। সুতরাং, যদি আমরা স্থানীয় মেশিনে ফাইলে পরিবর্তন করি, সেগুলি ডকারে প্রতিফলিত হয় না। কোডটি সর্বদা সিঙ্কে রয়েছে তা নিশ্চিত করতে, আমরা ভলিউম মাউন্ট ব্যবহার করতে পারি।
ডকার কম্পোজ ফাইলে, আসুন ভলিউম যোগ করি:
version: "3.0"
services:
db:
image: postgres
environment:
POSTGRES_USER: calculator
POSTGRES_PASSWORD: password
POSTGRES_DB: calculator_test
web:
build: .
volumes:
- .:/calculator # Volume mounted
ports:
- "3000:3000"
depends_on:
- db
- sumservice
environment:
CALCULATOR_DATABASE_PASSWORD: password
sumservice:
image: stoplight/prism:4
command: mock -h 0.0.0.0 "/tmp/api.yaml"
volumes:
- ./mock:/tmp/
ports:
- 4010:4010
init: true
এখন, যদি আমরা বিচ্ছেদে কোনো পরিবর্তন করি, তবে পরিবর্তনগুলি প্রতিফলিত হবে। আসুন একটি কন্ট্রোলার তৈরি করে এবং আমাদের যোগ পদ্ধতিতে কল করে এটি চেষ্টা করি:
# controllers/calculation_controller.rb
class CalculationController < ApplicationController
def index
result = Calculation.sum(params[:x], params[:y])
render json: {result: result}
end
end
রুট রুট যোগ করুন:
# routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root "calculation#index"
end
এখন, যদি আমরা ফিরে যাই এবং ব্রাউজারে অ্যাপটি পরীক্ষা করি, আমরা প্রত্যাশিত প্রতিক্রিয়া পাব:
মনে রাখবেন যে আমরা মক sumservice
ব্যবহার করে সার্ভার শুরু করছি , তাই আমরা একটি ক্যোয়ারী প্যারামিটার হিসাবে URL-এ যা প্রদান করি তা নির্বিশেষে, এটি সর্বদা 2 ফেরত দেবে। এটি ডেভেলপমেন্ট করার একটি ভাল উপায় বলে মনে হয় না কিন্তু একটি উপহাস পরিষেবা প্রদানকারী ব্যবহার করার সুবিধা রয়েছে। মাইক্রোসার্ভিস ডেভেলপ করার সময়, অনেক নির্ভরশীল পরিষেবা থাকতে পারে, যেগুলি পরিষেবা শুরু করার আগে আমাদের বুট আপ করতে হবে। এটি বিকাশের সময় উত্পাদনশীলতা বাড়াতে সহায়তা করে। আমরা অন্যান্য পরিষেবার সাথে উদ্বিগ্ন নই এবং আমরা যে পরিষেবাটি বিকাশ করছি তা নিয়েই আছি৷
আমরা যদি প্রকৃত পরিষেবার সাথে এটি কীভাবে কাজ করে তার চূড়ান্ত যাচাই করতে চাই, আমরা একটি নতুন ডকার কম্পোজ ফাইল তৈরি করে এবং পরিষেবাটির প্রকৃত চিত্র দিয়ে প্রতিস্থাপন করে তা করতে পারি। যদি এটি একটি অভ্যন্তরীণ পরিষেবা হয়, আমরা কেবল এটিকে সর্বশেষ স্থিতিশীল ডকার ইমেজ দিয়ে প্রতিস্থাপন করতে পারি। আমি উন্নয়ন পরিবেশেও একটি উপহাস পরিষেবা থাকার সুপারিশ করব৷
.dockerignore
অ্যাপ্লিকেশনটি বড় হওয়ার সাথে সাথে নির্ভরতা ডকার বিল্ড প্রসঙ্গকে বড় করে তুলবে। একটি বৃহত্তর বিল্ড প্রসঙ্গ সহ, ডকার ইমেজ তৈরি করতে আরও সময় লাগে। এমনকি ভলিউম মাউন্ট অ্যাপ্লিকেশনের বর্ধিত আকারের সাথে বিলম্বের কারণ হতে পারে। এই ক্ষেত্রে, আমরা অবাঞ্ছিত ফাইলটিকে .dockerignore
-এ যোগ করতে পারি বিল্ড কনটেক্সট কমাতে ফাইল।
.git*
log/*
README.md
node_modules
এন্ট্রিপয়েন্ট
যখন একটি Rails সার্ভার একটি কন্টেইনারে চলছে, আমরা মাঝে মাঝে একটি ত্রুটি বার্তা পাই যে সার্ভারটি ইতিমধ্যেই চলছে কারণ কন্টেইনারটি প্রস্থান করার সময় PID ফাইলটি মুছে ফেলা হয়নি৷ এই ত্রুটিটি সরাতে, আমরা একটি ENTRYPOINT যোগ করতে পারি, যা server.pid
সরিয়ে দেবে ফাইল।
FROM ruby:2.7
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN mkdir /calculator
WORKDIR /calculator
COPY Gemfile /calculator/Gemfile
COPY Gemfile.lock /calculator/Gemfile.lock
RUN bundle install
COPY package.json /calculator/package.json
COPY yarn.lock /calculator/yarn.lock
RUN yarn install --check-files
COPY . /calculator
EXPOSE 3000
ENTRYPOINT ./entrypoint.sh
CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
তৈরি করুন ফাইল:
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /calculator/tmp/pids/server.pid
# Exec the container's main process (CMD command in rails file)
exec "$@"
এটি সম্পাদনযোগ্য করুন
chmod +x entrypoint.sh
এখন, যখন আমরা ডকার ইমেজ চালাই, আমরা এই সমস্যাটি অনুভব করব না।
উপসংহার
ইন্টিগ্রেশন টেস্ট এবং ইউনিট টেস্টের মধ্যে পার্থক্য করা খুবই গুরুত্বপূর্ণ। ইউনিট পরীক্ষা লেখার সময়, আমরা ডাটাবেসের মতো বাহ্যিক নির্ভরতাকে উপহাস করতে পারি। এটি বিচ্ছিন্নভাবে কোড পরীক্ষা করতে সাহায্য করবে। মূল ব্যবসায়িক যুক্তি এবং এর নির্ভরতাগুলির মধ্যে ইন্টিগ্রেশন পরীক্ষা চালানোও সমানভাবে গুরুত্বপূর্ণ। নির্ভরতা, যেমন ডাটাবেস এবং বাহ্যিক পরিষেবাগুলি, ডকার এবং ডকার কম্পোজ ব্যবহার করে ইন্টিগ্রেশনে পরীক্ষা করা যেতে পারে। এই দুটি আলাদা করা ভাল অভ্যাস। আমরা তাদের আলাদাভাবে চালাতে সক্ষম হওয়া উচিত। আরও ইউনিট পরীক্ষা এবং কম ইন্টিগ্রেশন পরীক্ষাগুলি আপনার পরীক্ষাগুলিকে আরও দ্রুত এবং আরও নির্ভরযোগ্য করে তোলে৷
এই কর্মপ্রবাহের কিছু সুবিধা নিম্নরূপ:
- ইউনিট এবং ইন্টিগ্রেশন পরীক্ষার মধ্যে বিভাজন।
- যেহেতু সমস্ত CI পরিষেবাগুলি কন্টেইনারে চলে, তাই স্থানীয়ভাবে এবং CI-এ চলমান পরীক্ষাগুলি একই আচরণ করবে৷ এটি স্থানীয় মেশিন এবং CI সার্ভারে পরীক্ষার আচরণের ধারাবাহিকতা নিশ্চিত করতে সহায়তা করে।
- অ্যাপ্লিকেশান স্থাপনের জন্য কন্টেইনার ব্যবহার করা প্রোডাকশন সার্ভারে ধারাবাহিকতা নিশ্চিত করতে সহায়তা করে।
- নির্ভরযোগ্য পরীক্ষা, যেহেতু নির্ভরতাগুলি ভালভাবে পরিচালিত হয়।
- পোর্টেবল পরীক্ষা, একাধিক ডেভেলপারদের দ্বারা ব্যবহার করার সময় সেটআপে সামান্য প্রচেষ্টা প্রয়োজন৷