আপনি ঠিক বলেছেন, আপনার পরীক্ষাগুলি যাচাই করা উচিত নয় যে random
মডিউলটি কাজ করছে; একটি ইউনিট কেবলমাত্র ক্লাসের নিজেই পরীক্ষা করে দেখা উচিত, এটি অন্যান্য কোডের সাথে কীভাবে ইন্টারঅ্যাক্ট করে (যা আলাদাভাবে পরীক্ষা করা উচিত)।
এটি অবশ্যই সম্পূর্ণরূপে সম্ভব যে আপনার কোডটি random.randint()
ভুল ব্যবহার করে ; অথবা আপনি random.randrange(1, self._sides)
পরিবর্তে কল করছেন এবং আপনার মর কখনই সর্বোচ্চ মান ছুঁড়ে না, তবে এটি একটি ভিন্ন ধরণের বাগ হতে পারে, আপনি ইউনিটেস্টের সাথে ধরতে পারেননি। সেক্ষেত্রে আপনার die
ইউনিট ডিজাইন হিসাবে কাজ করছে, তবে নকশাটি নিজেই ত্রুটিযুক্ত ছিল।
এই ক্ষেত্রে, আমি ঠাট্টা ব্যবহার করতে চাই প্রতিস্থাপনrandint()
ফাংশন, এবং শুধুমাত্র যাচাই করুন যে এটি হয়েছে বলা সঠিকভাবে। পাইথন ৩.৩ এবং তার বেশি এই ধরণের পরীক্ষার পরিচালনা করার জন্য unittest.mock
মডিউলটি নিয়ে আসে তবে ঠিক একই কার্যকারিতাটি পেতে আপনি পুরানো সংস্করণগুলিতে বাহ্যিক mock
প্যাকেজটি ইনস্টল করতে পারেন
import unittest
try:
from unittest.mock import patch
except ImportError:
# < python 3.3
from mock import patch
@patch('random.randint', return_value=3)
class TestDice(unittest.TestCase):
def _make_one(self, *args, **kw):
from die import Die
return Die(*args, **kw)
def test_standard_size(self, mocked_randint):
die = self._make_one()
result = die.roll()
mocked_randint.assert_called_with(1, 6)
self.assertEqual(result, 3)
def test_custom_size(self, mocked_randint):
die = self._make_one(sides=42)
result = die.roll()
mocked_randint.assert_called_with(1, 42)
self.assertEqual(result, 3)
if __name__ == '__main__':
unittest.main()
বিদ্রূপের সাথে, আপনার পরীক্ষা এখন খুব সহজ; সত্যিই আছে মাত্র 2 টি মামলা। 6-পক্ষীয় মরার জন্য ডিফল্ট কেস এবং কাস্টম পক্ষের কেস।
randint()
এর গ্লোবাল নেমস্পেসে অস্থায়ীভাবে ফাংশনটি প্রতিস্থাপন করার অন্যান্য উপায় রয়েছে Die
তবে mock
মডিউলটি এটিকে সহজতম করে তোলে। এখানে @mock.patch
সাজসজ্জা পরীক্ষার ক্ষেত্রে সমস্ত পরীক্ষার পদ্ধতিতে প্রযোজ্য ; প্রতিটি পরীক্ষার পদ্ধতিটি একটি অতিরিক্ত যুক্তি, বিদ্রূপিত random.randint()
ফাংশনটি পাস করে, তাই আমরা মোক এটির বিরুদ্ধে পরীক্ষা করতে পারি যে এটি সত্যই সঠিকভাবে বলা হয়েছে কিনা। return_value
যুক্তি নির্দিষ্ট করে কি, উপহাস থেকে ফিরিয়ে দেওয়া হয় তাই আমরা যাচাই করতে পারেন যে যখন এটা বলা হয় die.roll()
পদ্ধতি সত্যিই আমাদের জন্য 'র্যান্ডম' ফলাফলের ফিরে আসেন।
আমি এখানে পাইথন ইউনিটেস্টিংয়ের জন্য আরও একটি সেরা অনুশীলন ব্যবহার করেছি: পরীক্ষার অংশ হিসাবে পরীক্ষার অধীন শ্রেণিটি আমদানি করুন। _make_one
পদ্ধতি আমদানি এবং ইনস্ট্যান্স কাজ করে একটি পরীক্ষা মধ্যে , পরীক্ষা, যাতে মডিউল এখনও লোড করা হবে এমনকি যদি আপনি একটি বাক্য গঠন ত্রুটি বা অন্যান্য ভুল আমদানি মূল মডিউল প্রতিরোধ করব প্রণীত।
এইভাবে, আপনি যদি মডিউল কোডটিতে নিজেই কোনও ভুল করেন তবে পরীক্ষাগুলি এখনও চালানো হবে; আপনার কোডটিতে ত্রুটি সম্পর্কে আপনাকে জানিয়ে তারা কেবল ব্যর্থ হবে।
স্পষ্টত, উপরোক্ত পরীক্ষাগুলি চরম মধ্যে সরল। এখানে লক্ষ্যটি পরীক্ষা করা নয় random.randint()
যা সঠিক যুক্তি দিয়ে বলা হয়েছে, উদাহরণস্বরূপ। পরিবর্তে, লক্ষ্যটি পরীক্ষা করা যায় যে ইউনিটটি নির্দিষ্ট ইনপুট প্রদত্ত সঠিক ফলাফল তৈরি করছে, যেখানে সেই ইনপুটগুলিতে পরীক্ষার অধীনে না থাকা অন্য ইউনিটের ফলাফল অন্তর্ভুক্ত রয়েছে । random.randint()
পদ্ধতিটি উপহাস করে আপনি নিজের কোডে অন্য একটি ইনপুট নিয়ন্ত্রণ নিতে পারবেন।
ইন বাস্তব জগতে পরীক্ষা আপনার ইউনিট-অধীনে পরীক্ষাটির মধ্যে প্রকৃত কোড আরো জটিল হতে যাচ্ছে; এপিআইতে প্রবেশ করা ইনপুটগুলির সাথে সম্পর্ক এবং কীভাবে অন্য ইউনিটগুলি চাওয়া হয় তা এখনও আকর্ষণীয় হতে পারে এবং মশকরা আপনাকে মধ্যবর্তী ফলাফলগুলিতে অ্যাক্সেস দেবে, পাশাপাশি সেই কলগুলির জন্য ফেরতের মানগুলি সেট করতে দেয়।
উদাহরণস্বরূপ, কোনও কোড যা ব্যবহারকারীদের একটি তৃতীয় পক্ষের OAuth2 পরিষেবাদির (একটি বহু-স্তরের মিথস্ক্রিয়া) বিরুদ্ধে প্রমাণীকরণ করে আপনি পরীক্ষা করতে চান যে আপনার কোডটি সেই তৃতীয় পক্ষের পরিষেবাটিতে সঠিক ডেটা প্রেরণ করছে এবং আপনাকে বিভিন্ন ত্রুটি প্রতিক্রিয়াগুলি উপহাস করতে দেয় that তৃতীয় পক্ষের পরিষেবাটি ফিরে আসবে, আপনাকে নিজে একটি সম্পূর্ণ OAuth2 সার্ভার তৈরি না করেই বিভিন্ন পরিস্থিতিতে সিমুলেট করতে দেয়। এখানে প্রথম টেস্ট প্রতিক্রিয়া থেকে তথ্যটি সঠিকভাবে পরিচালনা করা হয়েছে এবং দ্বিতীয় পর্যায়ে কলটি দেওয়া হয়েছে তা পরীক্ষা করা গুরুত্বপূর্ণ, সুতরাং আপনি দেখতে চান যে উপহাসকৃত পরিষেবাটি সঠিকভাবে ডাকছে।