বাংলা

শক্তিশালী এবং নির্ভরযোগ্য সফটওয়্যার তৈরির জন্য আপনার টেস্টিং কৌশলে কীভাবে মক ফাংশন ব্যবহার করবেন তা শিখুন। এই গাইডটি ব্যবহারিক উদাহরণসহ মক ফাংশন কখন, কেন এবং কীভাবে প্রয়োগ করতে হয় তা আলোচনা করে।

মক ফাংশন: ডেভেলপারদের জন্য একটি সম্পূর্ণ গাইড

সফটওয়্যার ডেভেলপমেন্টের জগতে, শক্তিশালী এবং নির্ভরযোগ্য কোড লেখা অত্যন্ত গুরুত্বপূর্ণ। এই লক্ষ্য অর্জনের জন্য পুঙ্খানুপুঙ্খ টেস্টিং অপরিহার্য। বিশেষ করে, ইউনিট টেস্টিং পৃথক কম্পোনেন্ট বা ফাংশনগুলিকে বিচ্ছিন্নভাবে পরীক্ষা করার উপর মনোযোগ দেয়। কিন্তু, বাস্তব অ্যাপ্লিকেশনগুলিতে প্রায়ই জটিল নির্ভরতা (dependencies) থাকে, যা ইউনিটগুলিকে সম্পূর্ণ বিচ্ছিন্নভাবে পরীক্ষা করাকে চ্যালেঞ্জিং করে তোলে। এখানেই মক ফাংশনের আগমন।

মক ফাংশন কী?

মক ফাংশন হলো একটি আসল ফাংশনের সিমুলেটেড সংস্করণ যা আপনি আপনার টেস্টে ব্যবহার করতে পারেন। আসল ফাংশনের লজিক কার্যকর করার পরিবর্তে, একটি মক ফাংশন আপনাকে তার আচরণ নিয়ন্ত্রণ করতে, এটি কীভাবে কল করা হচ্ছে তা পর্যবেক্ষণ করতে এবং তার রিটার্ন ভ্যালু নির্ধারণ করতে দেয়। এগুলি এক ধরনের টেস্ট ডাবল

বিষয়টিকে এভাবে ভাবুন: কল্পনা করুন আপনি একটি গাড়ির ইঞ্জিন (পরীক্ষার অধীনে থাকা ইউনিট) পরীক্ষা করছেন। ইঞ্জিনটি অন্যান্য বিভিন্ন উপাদানের উপর নির্ভর করে, যেমন ফুয়েল ইনজেকশন সিস্টেম এবং কুলিং সিস্টেম। ইঞ্জিন পরীক্ষার সময় আসল ফুয়েল ইনজেকশন এবং কুলিং সিস্টেম চালানোর পরিবর্তে, আপনি মক সিস্টেম ব্যবহার করতে পারেন যা তাদের আচরণকে অনুকরণ করে। এটি আপনাকে ইঞ্জিনকে আলাদা করতে এবং বিশেষভাবে তার কর্মক্ষমতার উপর ফোকাস করতে সাহায্য করে।

মক ফাংশন নিম্নলিখিত ক্ষেত্রগুলিতে শক্তিশালী টুলস হিসেবে কাজ করে:

কখন মক ফাংশন ব্যবহার করবেন

মক নিম্নলিখিত পরিস্থিতিতে সবচেয়ে কার্যকর:

১. বাহ্যিক নির্ভরতা সহ ইউনিট পৃথকীকরণ

যখন আপনার পরীক্ষার অধীনে থাকা ইউনিটটি বাহ্যিক পরিষেবা, ডেটাবেস, এপিআই বা অন্যান্য উপাদানের উপর নির্ভর করে, তখন পরীক্ষার সময় আসল নির্ভরতা ব্যবহার করলে বিভিন্ন সমস্যা দেখা দিতে পারে:

উদাহরণ: কল্পনা করুন আপনি এমন একটি ফাংশন পরীক্ষা করছেন যা একটি দূরবর্তী এপিআই থেকে ব্যবহারকারীর ডেটা নিয়ে আসে। পরীক্ষার সময় আসল এপিআই কল করার পরিবর্তে, আপনি এপিআই প্রতিক্রিয়া সিমুলেট করতে একটি মক ফাংশন ব্যবহার করতে পারেন। এটি আপনাকে বাহ্যিক এপিআই-এর প্রাপ্যতা বা কর্মক্ষমতার উপর নির্ভর না করে ফাংশনটির লজিক পরীক্ষা করার সুযোগ দেয়। এটি বিশেষত গুরুত্বপূর্ণ যখন এপিআই-এর রেট লিমিট থাকে বা প্রতিটি অনুরোধের জন্য খরচ জড়িত থাকে।

২. জটিল মিথস্ক্রিয়া পরীক্ষা করা

কিছু ক্ষেত্রে, আপনার পরীক্ষার অধীনে থাকা ইউনিটটি অন্যান্য উপাদানের সাথে জটিল উপায়ে মিথস্ক্রিয়া করতে পারে। মক ফাংশন আপনাকে এই মিথস্ক্রিয়াগুলি পর্যবেক্ষণ এবং যাচাই করার অনুমতি দেয়।

উদাহরণ: এমন একটি ফাংশন বিবেচনা করুন যা পেমেন্ট লেনদেন প্রক্রিয়া করে। এই ফাংশনটি একটি পেমেন্ট গেটওয়ে, একটি ডেটাবেস এবং একটি নোটিফিকেশন পরিষেবার সাথে মিথস্ক্রিয়া করতে পারে। মক ফাংশন ব্যবহার করে, আপনি যাচাই করতে পারেন যে ফাংশনটি সঠিক লেনদেনের বিবরণ সহ পেমেন্ট গেটওয়েতে কল করে, লেনদেনের স্ট্যাটাস দিয়ে ডেটাবেস আপডেট করে এবং ব্যবহারকারীকে একটি নোটিফিকেশন পাঠায়।

৩. এরর কন্ডিশন সিমুলেট করা

আপনার অ্যাপ্লিকেশনের দৃঢ়তা নিশ্চিত করার জন্য এরর হ্যান্ডলিং পরীক্ষা করা অত্যন্ত গুরুত্বপূর্ণ। মক ফাংশনগুলি এমন এরর কন্ডিশন সিমুলেট করা সহজ করে তোলে যা বাস্তব পরিবেশে পুনরুৎপাদন করা কঠিন বা অসম্ভব।

উদাহরণ: ধরুন আপনি এমন একটি ফাংশন পরীক্ষা করছেন যা ক্লাউড স্টোরেজ পরিষেবাতে ফাইল আপলোড করে। আপনি আপলোড প্রক্রিয়া চলাকালীন একটি নেটওয়ার্ক এরর সিমুলেট করতে একটি মক ফাংশন ব্যবহার করতে পারেন। এটি আপনাকে যাচাই করতে দেয় যে ফাংশনটি সঠিকভাবে এররটি পরিচালনা করে, আপলোড পুনরায় চেষ্টা করে, বা ব্যবহারকারীকে सूचित করে।

৪. অ্যাসিঙ্ক্রোনাস কোড পরীক্ষা করা

অ্যাসিঙ্ক্রোনাস কোড, যেমন কলব্যাক, প্রমিস বা অ্যাসিঙ্ক/অ্যাওয়েট ব্যবহার করে এমন কোড, পরীক্ষা করা চ্যালেঞ্জিং হতে পারে। মক ফাংশন আপনাকে অ্যাসিঙ্ক্রোনাস অপারেশনের সময় এবং আচরণ নিয়ন্ত্রণ করতে সাহায্য করতে পারে।

উদাহরণ: কল্পনা করুন আপনি এমন একটি ফাংশন পরীক্ষা করছেন যা একটি অ্যাসিঙ্ক্রোনাস অনুরোধ ব্যবহার করে একটি সার্ভার থেকে ডেটা নিয়ে আসে। আপনি সার্ভার প্রতিক্রিয়া সিমুলেট করতে এবং প্রতিক্রিয়া কখন ফেরত দেওয়া হবে তা নিয়ন্ত্রণ করতে একটি মক ফাংশন ব্যবহার করতে পারেন। এটি আপনাকে পরীক্ষা করতে দেয় যে ফাংশনটি কীভাবে বিভিন্ন প্রতিক্রিয়া পরিস্থিতি এবং টাইমআউট পরিচালনা করে।

৫. অনাকাঙ্ক্ষিত পার্শ্বপ্রতিক্রিয়া প্রতিরোধ করা

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

উদাহরণ: আপনি এমন একটি ফাংশন পরীক্ষা করছেন যা নতুন ব্যবহারকারীদের স্বাগত ইমেল পাঠায়। একটি মক ইমেল পরিষেবা ব্যবহার করে, আপনি নিশ্চিত করতে পারেন যে আপনার টেস্ট স্যুট চালানোর সময় ইমেল পাঠানোর কার্যকারিতাটি আসল ব্যবহারকারীদের কাছে ইমেল পাঠাচ্ছে না। পরিবর্তে, আপনি যাচাই করতে পারেন যে ফাংশনটি সঠিক তথ্য সহ ইমেল পাঠানোর চেষ্টা করেছে।

কীভাবে মক ফাংশন ব্যবহার করবেন

মক ফাংশন ব্যবহারের নির্দিষ্ট পদক্ষেপগুলি আপনার ব্যবহৃত প্রোগ্রামিং ভাষা এবং টেস্টিং ফ্রেমওয়ার্কের উপর নির্ভর করে। তবে, সাধারণ প্রক্রিয়াটিতে সাধারণত নিম্নলিখিত পদক্ষেপগুলি অন্তর্ভুক্ত থাকে:

  1. নির্ভরতা সনাক্ত করুন: কোন বাহ্যিক নির্ভরতাগুলি আপনার মক করা প্রয়োজন তা নির্ধারণ করুন।
  2. মক অবজেক্ট তৈরি করুন: আসল নির্ভরতা প্রতিস্থাপন করতে মক অবজেক্ট বা ফাংশন তৈরি করুন। এই মকগুলিতে প্রায়শই `called`, `returnValue` এবং `callArguments` এর মতো বৈশিষ্ট্য থাকে।
  3. মকের আচরণ কনফিগার করুন: মক ফাংশনগুলির আচরণ নির্ধারণ করুন, যেমন তাদের রিটার্ন ভ্যালু, এরর কন্ডিশন এবং কল সংখ্যা।
  4. মক ইনজেক্ট করুন: আপনার পরীক্ষার অধীনে থাকা ইউনিটে আসল নির্ভরতাগুলিকে মক অবজেক্ট দিয়ে প্রতিস্থাপন করুন। এটি প্রায়শই ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে করা হয়।
  5. টেস্ট চালান: আপনার টেস্ট চালান এবং পর্যবেক্ষণ করুন কীভাবে পরীক্ষার অধীনে থাকা ইউনিটটি মক ফাংশনগুলির সাথে মিথস্ক্রিয়া করে।
  6. মিথস্ক্রিয়া যাচাই করুন: যাচাই করুন যে মক ফাংশনগুলি প্রত্যাশিত আর্গুমেন্ট, রিটার্ন ভ্যালু এবং কল সংখ্যা সহ কল করা হয়েছে।
  7. আসল কার্যকারিতা পুনরুদ্ধার করুন: পরীক্ষার পরে, মক অবজেক্টগুলি সরিয়ে এবং আসল নির্ভরতায় ফিরে গিয়ে আসল কার্যকারিতা পুনরুদ্ধার করুন। এটি অন্যান্য পরীক্ষার উপর পার্শ্বপ্রতিক্রিয়া এড়াতে সাহায্য করে।

বিভিন্ন ভাষায় মক ফাংশনের উদাহরণ

এখানে জনপ্রিয় প্রোগ্রামিং ভাষা এবং টেস্টিং ফ্রেমওয়ার্কগুলিতে মক ফাংশন ব্যবহারের কিছু উদাহরণ দেওয়া হলো:

জেস্ট সহ জাভাস্ক্রিপ্ট

জেস্ট একটি জনপ্রিয় জাভাস্ক্রিপ্ট টেস্টিং ফ্রেমওয়ার্ক যা মক ফাংশনের জন্য বিল্ট-ইন সাপোর্ট প্রদান করে।

// যে ফাংশনটি পরীক্ষা করতে হবে
function fetchData(callback) {
  setTimeout(() => {
    callback('Data from server');
  }, 100);
}

// টেস্ট কেস
test('fetchData calls callback with correct data', (done) => {
  const mockCallback = jest.fn();
  fetchData(mockCallback);

  setTimeout(() => {
    expect(mockCallback).toHaveBeenCalledWith('Data from server');
    done();
  }, 200);
});

এই উদাহরণে, `jest.fn()` একটি মক ফাংশন তৈরি করে যা আসল কলব্যাক ফাংশনটিকে প্রতিস্থাপন করে। টেস্টটি `toHaveBeenCalledWith()` ব্যবহার করে যাচাই করে যে মক ফাংশনটি সঠিক ডেটা দিয়ে কল করা হয়েছে।

মডিউল ব্যবহার করে আরও উন্নত উদাহরণ:

// user.js
import { getUserDataFromAPI } from './api';

export async function displayUserName(userId) {
  const userData = await getUserDataFromAPI(userId);
  return userData.name;
}

// api.js
export async function getUserDataFromAPI(userId) {
  // এপিআই কল সিমুলেট করা হচ্ছে
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id: userId, name: 'John Doe' });
    }, 50);
  });
}

// user.test.js
import { displayUserName } from './user';
import * as api from './api';

describe('displayUserName', () => {
  it('should display the user name', async () => {
    // getUserDataFromAPI ফাংশনটিকে মক করা হচ্ছে
    const mockGetUserData = jest.spyOn(api, 'getUserDataFromAPI');
    mockGetUserData.mockResolvedValue({ id: 123, name: 'Mocked Name' });

    const userName = await displayUserName(123);
    expect(userName).toBe('Mocked Name');

    // আসল ফাংশনটি পুনরুদ্ধার করা হচ্ছে
    mockGetUserData.mockRestore();
  });
});

এখানে, `./api` মডিউল থেকে ইম্পোর্ট করা `getUserDataFromAPI` ফাংশনটির জন্য একটি মক ফাংশন তৈরি করতে `jest.spyOn` ব্যবহৃত হয়েছে। মকের রিটার্ন ভ্যালু নির্দিষ্ট করতে `mockResolvedValue` ব্যবহৃত হয়। `mockRestore` অপরিহার্য যাতে অন্যান্য পরীক্ষাগুলি অনিচ্ছাকৃতভাবে মক করা সংস্করণটি ব্যবহার না করে।

পাইটেস্ট এবং unittest.mock সহ পাইথন

পাইথন মকিংয়ের জন্য বেশ কয়েকটি লাইব্রেরি অফার করে, যার মধ্যে `unittest.mock` (বিল্ট-ইন) এবং `pytest-mock` এর মতো লাইব্রেরি রয়েছে যা পাইটেস্টের সাথে সহজ ব্যবহার নিশ্চিত করে।

# যে ফাংশনটি পরীক্ষা করতে হবে
def get_data_from_api(url):
    # বাস্তব পরিস্থিতিতে, এটি একটি এপিআই কল করবে
    # সরলতার জন্য, আমরা একটি এপিআই কল সিমুলেট করছি
    if url == "https://example.com/api":
        return {"data": "API data"}
    else:
        return None

def process_data(url):
    data = get_data_from_api(url)
    if data:
        return data["data"]
    else:
        return "No data found"

# unittest.mock ব্যবহার করে টেস্ট কেস
import unittest
from unittest.mock import patch

class TestProcessData(unittest.TestCase):
    @patch('__main__.get_data_from_api') # মূল মডিউলে get_data_from_api প্রতিস্থাপন করা হচ্ছে
    def test_process_data_success(self, mock_get_data_from_api):
        # মক কনফিগার করা হচ্ছে
        mock_get_data_from_api.return_value = {"data": "Mocked data"}

        # পরীক্ষা করা ফাংশনটি কল করা হচ্ছে
        result = process_data("https://example.com/api")

        # ফলাফল যাচাই করা হচ্ছে
        self.assertEqual(result, "Mocked data")
        mock_get_data_from_api.assert_called_once_with("https://example.com/api")

    @patch('__main__.get_data_from_api')
    def test_process_data_failure(self, mock_get_data_from_api):
        mock_get_data_from_api.return_value = None
        result = process_data("https://example.com/api")
        self.assertEqual(result, "No data found")

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

এই উদাহরণটি `get_data_from_api` ফাংশনটিকে একটি মক দিয়ে প্রতিস্থাপন করতে `unittest.mock.patch` ব্যবহার করে। টেস্টটি মককে একটি নির্দিষ্ট মান ফেরত দেওয়ার জন্য কনফিগার করে এবং তারপর যাচাই করে যে `process_data` ফাংশনটি প্রত্যাশিত ফলাফল প্রদান করে।

এখানে `pytest-mock` ব্যবহার করে একই উদাহরণের একটি সংস্করণ দেওয়া হলো:

# পাইটেস্ট সংস্করণ
import pytest

def get_data_from_api(url):
    # বাস্তব পরিস্থিতিতে, এটি একটি এপিআই কল করবে
    # সরলতার জন্য, আমরা একটি এপিআই কল সিমুলেট করছি
    if url == "https://example.com/api":
        return {"data": "API data"}
    else:
        return None

def process_data(url):
    data = get_data_from_api(url)
    if data:
        return data["data"]
    else:
        return "No data found"


def test_process_data_success(mocker):
    mocker.patch('__main__.get_data_from_api', return_value={"data": "Mocked data"})
    result = process_data("https://example.com/api")
    assert result == "Mocked data"


def test_process_data_failure(mocker):
    mocker.patch('__main__.get_data_from_api', return_value=None)
    result = process_data("https://example.com/api")
    assert result == "No data found"

`pytest-mock` লাইব্রেরি একটি `mocker` ফিক্সচার সরবরাহ করে যা পাইটেস্ট পরীক্ষার মধ্যে মক তৈরি এবং কনফিগারেশনকে সহজ করে।

মকিটো সহ জাভা

মকিটো জাভার জন্য একটি জনপ্রিয় মকিং ফ্রেমওয়ার্ক।

import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

interface DataFetcher {
    String fetchData(String url);
}

class DataProcessor {
    private final DataFetcher dataFetcher;

    public DataProcessor(DataFetcher dataFetcher) {
        this.dataFetcher = dataFetcher;
    }

    public String processData(String url) {
        String data = dataFetcher.fetchData(url);
        if (data != null) {
            return "Processed: " + data;
        } else {
            return "No data";
        }
    }
}

public class DataProcessorTest {

    @Test
    public void testProcessDataSuccess() {
        // একটি মক DataFetcher তৈরি করা হচ্ছে
        DataFetcher mockDataFetcher = mock(DataFetcher.class);

        // মক কনফিগার করা হচ্ছে
        when(mockDataFetcher.fetchData("https://example.com/api")).thenReturn("API Data");

        // মক সহ DataProcessor তৈরি করা হচ্ছে
        DataProcessor dataProcessor = new DataProcessor(mockDataFetcher);

        // পরীক্ষা করা ফাংশনটি কল করা হচ্ছে
        String result = dataProcessor.processData("https://example.com/api");

        // ফলাফল যাচাই করা হচ্ছে
        assertEquals("Processed: API Data", result);

        // যাচাই করা হচ্ছে যে মকটি কল করা হয়েছে
        verify(mockDataFetcher).fetchData("https://example.com/api");
    }

    @Test
    public void testProcessDataFailure() {
        DataFetcher mockDataFetcher = mock(DataFetcher.class);
        when(mockDataFetcher.fetchData("https://example.com/api")).thenReturn(null);

        DataProcessor dataProcessor = new DataProcessor(mockDataFetcher);
        String result = dataProcessor.processData("https://example.com/api");
        assertEquals("No data", result);
        verify(mockDataFetcher).fetchData("https://example.com/api");
    }
}

এই উদাহরণে, `Mockito.mock()` `DataFetcher` ইন্টারফেসের জন্য একটি মক অবজেক্ট তৈরি করে। `when()` মকের রিটার্ন ভ্যালু কনফিগার করতে ব্যবহৃত হয়, এবং `verify()` মকটি প্রত্যাশিত আর্গুমেন্টগুলির সাথে কল করা হয়েছিল কিনা তা যাচাই করতে ব্যবহৃত হয়।

মক ফাংশন ব্যবহারের সেরা অনুশীলন

মক ফাংশনের বিকল্প

যদিও মক ফাংশন একটি শক্তিশালী টুল, তবে এগুলি সর্বদা সেরা সমাধান নয়। কিছু ক্ষেত্রে, অন্যান্য কৌশলগুলি আরও উপযুক্ত হতে পারে:

উপসংহার

মক ফাংশনগুলি কার্যকর ইউনিট টেস্ট লেখার জন্য একটি অপরিহার্য টুল, যা আপনাকে ইউনিট পৃথক করতে, আচরণ নিয়ন্ত্রণ করতে, এরর কন্ডিশন সিমুলেট করতে এবং অ্যাসিঙ্ক্রোনাস কোড পরীক্ষা করতে সক্ষম করে। সেরা অনুশীলনগুলি অনুসরণ করে এবং বিকল্পগুলি বোঝার মাধ্যমে, আপনি আরও শক্তিশালী, নির্ভরযোগ্য এবং রক্ষণাবেক্ষণযোগ্য সফ্টওয়্যার তৈরি করতে মক ফাংশনগুলিকে কাজে লাগাতে পারেন। মনে রাখবেন, প্রতিটি পরিস্থিতির জন্য সঠিক টেস্টিং কৌশল বেছে নিতে এবং একটি ব্যাপক ও কার্যকর টেস্টিং কৌশল তৈরি করতে এর সুবিধা-অসুবিধাগুলো বিবেচনা করুন, আপনি বিশ্বের যে কোনো প্রান্ত থেকেই তৈরি করুন না কেন।