Software testing-এর গোড়া: test pyramid ও কী test করবেন
Test ভয় ছাড়া কোড বদলাতে দেয়। কোন ধরন লিখবেন, প্রতিটির কতগুলো এবং কাজের রাখবেন কীভাবে শিখুন।

স্বয়ংক্রিয় test হলো এমন প্রোগ্রাম যা আপনার প্রোগ্রাম যাচাই করে। এগুলো bug আগে ধরে, আচরণ নথিভুক্ত করে এবং কোড বদলের আত্মবিশ্বাস দেয়। এগুলো ছাড়া প্রতিটি বদল ঝুঁকি আর প্রতিটি release আন্দাজ।
Test-এর ধরন
Unit test
- ছোট অংশ (একটি function বা class) আলাদাভাবে পরীক্ষা করে।
- খুব দ্রুত, তাই হাজারটা চালানো যায়।
- যুক্তি, হিসাব, যাচাই ও প্রান্তিক ক্ষেত্রে দারুণ।
Integration test
- কয়েকটি অংশ একসাথে কাজ করছে কি না পরীক্ষা: আপনার কোড আসল database, queue বা HTTP স্তরের সাথে।
- ধীর, তবে unit test যা মিস করে তা ধরে, যেমন ভুল SQL বা না-মেলা ফরম্যাট।
End-to-end (E2E) test
- ব্যবহারকারীর মতো পুরো অ্যাপ চালায়: browser খোলা, login, কিছু কেনা।
- সবচেয়ে বাস্তব, কিন্তু সবচেয়ে ধীর ও ভঙ্গুর। কম রাখুন এবং গুরুত্বপূর্ণ যাত্রায় কেন্দ্রীভূত রাখুন।
অন্যান্য কাজের ধরন: API-র জন্য contract test, performance ও load test, নিরাপত্তা test, accessibility যাচাই, এবং snapshot বা visual test।
Test pyramid
সুস্থ suite-এ অনেক unit test, কম integration test এবং খুব কম E2E test থাকে। দ্রুত, সস্তা test চওড়া ভিত্তি গড়ে। ধীর, ব্যয়বহুলগুলো ওপরে। উল্টো পিরামিড (বেশিরভাগ E2E) ধীর, flaky ও রক্ষণাবেক্ষণে ব্যয়বহুল।
পিরামিড নির্দেশিকা, আইন নয়। কিছু আধুনিক দল ওয়েব অ্যাপে বেশি integration test পছন্দ করে কারণ তা আত্মবিশ্বাস ও গতির ভালো ভারসাম্য দেয়।
ভালো test-এর গঠন
Arrange, Act, Assert ধরন ব্যবহার করুন।
test("applies a 10% discount for orders over 100", () => {
// Arrange
const order = { subtotal: 120 };
// Act
const total = calculateTotal(order);
// Assert
expect(total).toBe(108);
});
ভালো test:
- দ্রুত ও স্বাধীন (যেকোনো ক্রমে চলতে পারে)।
- পুনরাবৃত্তিযোগ্য: প্রতিবার একই ফল, নিয়ন্ত্রণ না করলে ঘড়ি, network বা এলোমেলো data-র ওপর নির্ভর নয়।
- পরিষ্কার: নাম আচরণ বলে, আর ব্যর্থতা বলে কী ভেঙেছে।
- কেন্দ্রীভূত: প্রতি test-এ একটি ধারণা।
কী test করবেন
- মূল আচরণ (happy path)।
- প্রান্তিক ক্ষেত্র: ফাঁকা ইনপুট, শূন্য, ঋণাত্মক সংখ্যা, খুব বড় মান, অনুপস্থিত field, ডুপ্লিকেট।
- Error ক্ষেত্র: অবৈধ ইনপুট, dependency-র ব্যর্থতা।
- Business নিয়ম এবং আগে যা bug ঘটিয়েছিল।
- নিরাপত্তা-সংশ্লিষ্ট নিয়ম: অনুমতি, মালিকানা যাচাই, ইনপুট যাচাই।
Framework বা তুচ্ছ getter test করার দরকার নেই। আচরণ test করুন, ভেতরের বিস্তারিত নয়, যাতে refactor করলে test না ভাঙে।
Test double: mock, stub ও fake
ধীর বা অনির্দিষ্ট জিনিস (network, পেমেন্ট provider, ঘড়ি) থেকে কোড আলাদা করতে test double দিয়ে বদলান:
- Stub: নির্দিষ্ট উত্তর দেয়।
- Mock: কীভাবে ডাকা হয়েছে তাও রেকর্ড করে, যাতে তার ওপর assert করা যায়।
- Fake: সরল কাজের সংস্করণ, যেমন in-memory database।
মিতব্যয়ী ব্যবহার করুন। বেশি mock এমন test বানায় যা পাস করে অথচ আসল সিস্টেম ভাঙা। বাস্তবসম্মত হলে আসল উপাদান (আসল test database) পছন্দ করুন এবং জোড়ের জন্য কয়েকটি integration test রাখুন।
Test-driven development (TDD)
TDD একটি ছন্দ:
১. Red: পরের ছোট আচরণের জন্য ব্যর্থ test লিখুন। ২. Green: পাস করানোর সবচেয়ে সরল কোড লিখুন। ৩. Refactor: test সুরক্ষা দিলে পরিষ্কার করুন।
এটি বাধ্যতামূলক নয়, তবে চেষ্টা করলে test করা সহজ কোড নকশা শেখায়। প্রতিটি bug ঠিক করার আগে ব্যর্থ test লেখা চমৎকার অভ্যাস।
Coverage: টুল, লক্ষ্য নয়
Code coverage দেখায় test কোন লাইন চালিয়েছে। কম coverage অপরীক্ষিত এলাকা দেখায়। কিন্তু বেশি coverage ভালো test প্রমাণ করে না, কারণ test কিছু যাচাই না করেও কোড চালাতে পারে। ১০০% এর পেছনে ছুটবেন না। গুরুত্বপূর্ণ যুক্তির coverage দেখুন এবং test সত্যিই অর্থপূর্ণ কিছু assert করছে কি না পর্যালোচনা করুন।
Test নির্ভরযোগ্য রাখুন
- Flaky test (কখনো পাস, কখনো ফেল) আস্থা নষ্ট করে। দ্রুত ঠিক করুন বা মুছুন। সাধারণ কারণ: সময়, ভাগ করা state, ক্রম-নির্ভরতা ও আসল network কল।
- Test-এর মধ্যে state রিসেট করুন এবং mutable data ভাগ এড়ান।
- সময় ও এলোমেলো মান নিয়ন্ত্রণ করুন।
- প্রতিটি push ও pull request-এ CI-তে test চালান এবং test ব্যর্থ হলে build ব্যর্থ করুন।
- Suite দ্রুত রাখুন। ধীর suite কম চালানো হয়।
শুরু করা
১. আপনার ভাষার প্রচলিত test framework বাছুন (pytest, JUnit, Jest/Vitest, Go-র testing package ইত্যাদি)।
২. বিদ্যমান যুক্তির কয়েকটি unit test লিখুন।
৩. একটি মূল প্রবাহের জন্য একটি integration test, তারপর সবচেয়ে গুরুত্বপূর্ণ ব্যবহারকারী যাত্রার একটি E2E test যোগ করুন।
৪. প্রতিটি bug ঠিক করার সাথে একটি test যোগ করুন।
৫. সবকিছু CI-তে চালান।
মূল কথা: অনেক দ্রুত unit test, কিছু integration test এবং কয়েকটি E2E test লিখুন। আচরণ ও প্রান্তিক ক্ষেত্র test করুন, mock সাবধানে ব্যবহার করুন, test নির্ভরযোগ্য রাখুন এবং প্রতিটি বদলে স্বয়ংক্রিয়ভাবে চালান।
প্রোগ্রামিং রোডম্যাপ সিরিজ, পর্ব ২ (ভাষা ও নকশা): 5 নম্বর (মোট 5)। আগের লেখা: Clean code ও code review অভ্যাস যা আপনাকে ভালো ডেভেলপার করে.


