ইউনিট টেস্টিং

প্রোগ্রামিং আর ইউনিট টেস্টিং একসূত্রে গাঁথা, নয়নের অংশ যেমন নয়নের পাতা।

আমরা তো ইতিমধ্যে ইউজার ডিফাইন্ড ফাংশন শিখে ফেলেছি। শুধু তাই নয়, ছোট ছোট অনেক ইউজার ডিফাইন্ড ফাংশন লিখে কাজও করেছি। এইসব ফাংশন ঠিকমত কাজ করে কিনা সেটা বোঝার জন্য কি করেছি আমরা? কি আবার! প্রোগ্রাম রান করে দেখেছি। আচ্ছা, যখন আমরা বড়সড় প্রজেক্ট করব যেখানে হাজার-হাজার ফাংশন থাকবে তখনও কি বারবার প্রোগ্রাম রান করে দেখব?

অবশ্যই না। আসলে সেটা তো সম্ভবও না। বড় বড় কোম্পানিতে কোন প্রোগ্রামারই সম্পূর্ণ প্রজেক্ট একা করেন না। বরং সবাই ছোট ছোট অংশের কাজ করে। সেক্ষেত্রে টেস্টিংয়ের জন্য আমাদেরকে বিকল্প উপায় খুঁজে বের করতে হবে।

ইউনিট টেস্টিং হল প্রোগ্রামের বিভিন্ন ফাংশনকে অটোম্যাটিকালি টেস্ট করার উপায়। এইক্ষেত্রে প্রতিটি ফাংশনের জন্য প্রোগ্রামের ভিতর টেস্ট কোড লেখা হয়। এই টেস্ট কোড লেখার জন্য বিভিন্ন ফ্রেমওয়ার্ক, টুলস ব্যবহার করা হয়। যেমন: unittest, py.test, nose, tox, unittest2, mock ইত্যাদি।

unittest

এটা পাইথনের ডিফল্ট ইউনিট টেস্টিং ফ্রেমওয়ার্ক, স্টান্ডার্ড লাইব্রেরির অন্তর্গত। কোড টেস্ট করার মোটামুটি সব দরকারি জিনিসই এতে পাওয়া যায়। যাহোক, এখন আমরা hijibiji.py ফাইলে কয়েকটা ফাংশন লিখব।

def add(a, b):
    return a + b

def is_even(number):
    if (number % 2) == 0:
        return True
    else:
        return False

এই ফাংশন দুইটা টেস্ট করার জন্য আমরা একই ডিরেক্টরির test.py তে টেস্ট কোড লিখব।

import unittest
from hijibiji import add, is_even

class MyTest(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(2, 3), 5)

    def test_is_even(self):
        self.assertTrue(is_even(2))

if __name__ == '__main__':
    unittest.main()

আউটপুট

..
----------------------------------------------------------------------
Ran 2 tests in 0.010s

OK

কি করলাম আমরা? একটু ব্যাখ্যা করা যাক। add() ফাংশনটা দুইটা ভ্যালুকে যোগ করে। তাই আমরা টেস্ট করে দেখেছি যে add() ফাংশনে 2, 3 পাস করলে রিটার্নকৃত মান সত্যিই 5 এর সমান হয় কিনা। আর is_even() ফাংশনটা চেক করে দেখে যে কোন সংখ্যা জোড় কিনা! জেড় হলে True রিটার্ন করে, বিজোড় হলে False রিটার্ন করে। তাই আমরা টেস্ট করে দেখেছি যে is_even() ফাংশনে 2 পাস করলে তা True রিটার্ন করে কিনা।

আসলে টেস্ট কোড এভাবেই লেখা হয়। এই মূুহুর্তে পুরো ফ্রেমওয়ার্কের বর্ণনা দেয়া তো সম্ভব না। আমরা যদি আরো অনেক কিছু জানতে চাই তবে সেটা অফিসিয়াল ডক (https://docs.python.org/3.5/library/unittest.html) থেকে শিখে নিতে হবে।

pytest

pytest হল ম্যাচিউর, ফুল-ফিচার্ড থার্ট-পার্টি পাইথন টেস্টিং টুল। unittest এর চেয়ে অনেক বেশি সহজ ও ফিচারসমৃদ্ধ। ইন্সটল করার জন্য নিচের কমান্ডটা দিব:

sudo pip3 install -U pytest

ইন্সটল হয়ে গেল pytest। এবার আমরা test.py তে লেখা আমাদের টেস্ট কোড কে রি-রাইট করব।

from hijibiji import add, is_even

def test_add():
    assert add(2, 3) == 5

def test_is_even():
    assert is_even(2) == True

এবার টার্মিনালে আমরা নিচের কমান্ডটি দেব।

pytest test.py

আউটপুট

============================= test session starts ==============================
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: /home/ugcoder/Desktop, inifile: 
collected 2 items 

test.py ..

=========================== 2 passed in 0.03 seconds ===========================

আগের চেয়ে অনেক সহজে আমরা টেস্ট করে ফেললাম। pytest নিয়ে ডিটেইলস জানার জন্য আমার এর অফিসিয়াল ডক (http://docs.pytest.org/en/latest/index.html) ফলো করব।

টেস্টিং আর কিছু নিয়ম-নীতি

টেস্টিংয়ের সময় কিছু নিয়ম-নীতি মানা উচিত।

(১) একটা টেস্ট ইউনিট শুধু একটা ছোট্ট ফাংশনালিটির উপর ফোকাস করবে আর সেটাকে সঠিক প্রমাণ করবে।
(২) প্রতিটা টেস্ট ইউনিট ইনডিপেন্ডেন্ট হবে। মানে একা একাই রান করতে পারবে।
(৩) টেস্ট ইউনিট এমনভাবে কোড করতে হবে যেন তা খুব দ্রুত রান করে। একটা টেস্ট ইউনিট রান হইতে হইতেই যদি আরেকটা কুরবানীর ঈদ চইলা আসে তাইলে তো প্রজেক্ট শিকায় উঠবে।
(৪) আমাদের সিঙ্গেল টেস্ট ইউনিট রান করা শিখা উচিত। একটা ফাংশনে বারবার চেঞ্জ আনার সময়, প্রতিবার টেস্ট ইউনিট রান করে দেখতে হবে সবকিছু ঠিকঠাক আছে কিনা।
(৫) প্রতিবার কোন প্রজেক্টে কোড করতে শুরু করার আগে ও পরে টেস্ট ইউনিটগুলো রান করে দেখতে হবে।

হ্যাপি ইউনিট টেস্টিং!

সহজ ভাষায় পাইথন ৩

বইটি পড়ার সময় প্রতিটি টপিক ধারাবাহিকভাবে বুঝে বুঝে পড়তে হবে এবং হাতে-কলমে অনুশীলন করতে হবে। কোন অংশ বুঝতে সমস্যা হলে ফেসবুক গ্রুপ পাইথন বাংলাদেশে সমস্যাটি পোস্ট করতে পারেন। এখান থেকে অতি দ্রুত সাহায্য-সহযোগীতা পাবেন আপনি।

results matching ""

    No results matching ""