JUnit হল Java এর জন্য একটি জনপ্রিয় টেস্টিং ফ্রেমওয়ার্ক যা ইউনিট টেস্ট পরিচালনা করতে ব্যবহৃত হয়। Assertions হল JUnit এর একটি শক্তিশালী ফিচার যা টেস্ট চলাকালীন অবজেক্টের বা মানের সঠিকতা যাচাই করে। তবে, অনেক সময় আমাদের প্রয়োজন হতে পারে Custom Matchers তৈরি করার, যা কাস্টম টেস্ট লজিক এবং সমাধান প্রদান করে।
এখানে, আমরা JUnit-এ Custom Matchers তৈরির প্রক্রিয়া এবং তাদের ব্যবহার নিয়ে বিস্তারিত আলোচনা করব।
১. JUnit Assertions এর Overview
JUnit Assertions সাধারণত টেস্ট কেসের প্রত্যাশিত ফলাফল এবং বাস্তব ফলাফল যাচাই করার জন্য ব্যবহৃত হয়। বিভিন্ন ধরনের অ্যাসারশন মেথড ব্যবহার করা হয়, যেমন:
assertEquals(expected, actual)assertTrue(condition)assertFalse(condition)assertNull(object)assertNotNull(object)
এগুলো জেনেরিক অ্যাসারশন, কিন্তু যখন আপনি কাস্টম ভ্যালিডেশন বা মেলানো চাইবেন, তখন Custom Matchers ব্যবহার করা যেতে পারে।
২. Custom Matcher তৈরি করার প্রয়োজনীয়তা
যখন আপনি আপনার টেস্টে জটিল বা বিশেষ ধরনের কাস্টম লজিক যাচাই করতে চান, তখন সাধারণ অ্যাসারশন মেথড কাজ করবে না। এই অবস্থায়, Custom Matchers তৈরি করা অত্যন্ত কার্যকরী হতে পারে। এই কাস্টম ম্যাচারগুলি আপনার টেস্টের জন্য নির্দিষ্ট শর্তাবলী যাচাই করতে সহায়তা করে, এবং এটি Hamcrest লাইব্রেরি দ্বারা সহজেই বাস্তবায়িত করা যায়।
Hamcrest হল একটি Java লাইব্রেরি যা কাস্টম ম্যাচার তৈরি এবং ব্যবহার করতে সহায়তা করে। এটি JUnit এর সাথে ভালোভাবে কাজ করে।
৩. Hamcrest Matcher তৈরি করা
Hamcrest এর সাথে কাস্টম Matcher তৈরি করা খুবই সহজ। নিচে একটি উদাহরণ দেওয়া হলো যেখানে আমরা একটি কাস্টম Matcher তৈরি করব, যা কোনো অবজেক্টের প্রপার্টি যাচাই করবে।
উদাহরণ: String Length Matcher
ধরা যাক, আমরা একটি Matcher তৈরি করতে চাই যা কোনো স্ট্রিংয়ের দৈর্ঘ্য যাচাই করবে।
Step 1: Hamcrest Dependency
প্রথমে, Hamcrest লাইব্রেরি আপনার প্রোজেক্টে যুক্ত করতে হবে।
Maven এর জন্য:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
Gradle এর জন্য:
testImplementation 'org.hamcrest:hamcrest:2.2'
Step 2: Custom Matcher Class
এখন আমরা একটি Custom Matcher তৈরি করব যা স্ট্রিংয়ের দৈর্ঘ্য যাচাই করবে।
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class StringLengthMatcher extends TypeSafeMatcher<String> {
private final int expectedLength;
public StringLengthMatcher(int expectedLength) {
this.expectedLength = expectedLength;
}
@Override
public boolean matchesSafely(String item) {
return item.length() == expectedLength;
}
@Override
public void describeTo(Description description) {
description.appendText("a string with length " + expectedLength);
}
public static Matcher<String> hasLength(int length) {
return new StringLengthMatcher(length);
}
}
এখানে, StringLengthMatcher একটি কাস্টম Hamcrest Matcher যা স্ট্রিংয়ের দৈর্ঘ্য যাচাই করবে।
Step 3: Custom Matcher ব্যবহার
এখন আমরা এটি JUnit টেস্টে ব্যবহার করতে পারব।
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
public class StringLengthMatcherTest {
@Test
public void testStringLengthMatcher() {
String testString = "Hello, World!";
// Using the custom matcher
assertThat(testString, StringLengthMatcher.hasLength(13));
}
}
এখানে, assertThat ব্যবহার করে আমরা StringLengthMatcher এর মাধ্যমে যাচাই করেছি যে "Hello, World!" স্ট্রিংটির দৈর্ঘ্য ১৩।
৪. Hamcrest Matchers এর সুবিধা
- Readable and Expressive: Hamcrest Matchers খুবই পঠনযোগ্য এবং ব্যবহারযোগ্য, কারণ আপনি সহজেই একটি ম্যাচার তৈরি করতে পারেন যা টেস্টের শর্তাবলী পরিষ্কারভাবে বর্ণনা করে।
- Reuse: আপনি কাস্টম Matchers একবার তৈরি করে সেগুলি বিভিন্ন টেস্ট কেসে পুনরায় ব্যবহার করতে পারবেন।
- Flexible: আপনার প্রয়োজন অনুযায়ী যেকোনো ধরনের ম্যাচিং লজিক তৈরি করা যায়।
৫. Custom Matchers এর আরও কিছু উদাহরণ
Example 1: Checking if a list contains a certain object
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import java.util.List;
public class ListContainsObjectMatcher extends TypeSafeMatcher<List<String>> {
private final String expectedValue;
public ListContainsObjectMatcher(String expectedValue) {
this.expectedValue = expectedValue;
}
@Override
public boolean matchesSafely(List<String> list) {
return list.contains(expectedValue);
}
@Override
public void describeTo(Description description) {
description.appendText("a list containing " + expectedValue);
}
public static ListContainsObjectMatcher containsObject(String object) {
return new ListContainsObjectMatcher(object);
}
}
JUnit Test:
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Arrays;
public class ListContainsObjectMatcherTest {
@Test
public void testListContainsObject() {
List<String> testList = Arrays.asList("Apple", "Banana", "Cherry");
// Using the custom matcher
assertThat(testList, ListContainsObjectMatcher.containsObject("Banana"));
}
}
৬. Conclusion
JUnit-এর Custom Matchers ব্যবহারের মাধ্যমে আপনি টেস্টগুলোকে আরও পরিষ্কার, কার্যকর এবং মডুলার করতে পারেন। Hamcrest Matchers একটি শক্তিশালী লাইব্রেরি যা JUnit টেস্টের জন্য কাস্টম ম্যাচার তৈরি এবং ব্যবহার করার সুবিধা প্রদান করে। এই কাস্টম ম্যাচারগুলো ডেভেলপারদের বিশেষ ধরনের যাচাই বা কাস্টম লজিক প্রয়োগ করতে সহায়তা করে, যা সাধারণ অ্যাসারশন দিয়ে সম্ভব হয় না।
JUnit হল একটি জনপ্রিয় টেস্টিং ফ্রেমওয়ার্ক যা Java প্রোগ্রামিং ভাষায় ইউনিট টেস্ট তৈরি এবং পরিচালনার জন্য ব্যবহৃত হয়। Custom Matchers হল এমন একটি বৈশিষ্ট্য যা আপনাকে JUnit টেস্টিংয়ে আরও নমনীয়তা এবং কাস্টমাইজেশন প্রদান করে। এটি একটি কাস্টম লজিক ব্যবহার করতে সাহায্য করে যা ডিফল্ট Matcher এর মাধ্যমে সম্ভব নয়।
এই টিউটোরিয়ালে আমরা আলোচনা করব Custom Matchers এর ব্যবহার, এর প্রয়োজনীয়তা এবং কিভাবে এটি JUnit টেস্টে প্রয়োগ করা যেতে পারে।
১. Custom Matchers কি?
Matchers হল JUnit বা Hamcrest এর একটি বৈশিষ্ট্য যা নির্দিষ্ট শর্ত যাচাই করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আপনি যদি চান যে আপনার টেস্টে কোনো ভ্যালু positive বা negative হতে হবে, তাহলে আপনি Matchers ব্যবহার করে সেই শর্তটি যাচাই করতে পারেন।
Custom Matchers হল কাস্টম লজিক বা কন্ডিশন যা আপনি নিজের প্রয়োজন অনুযায়ী তৈরি করতে পারেন। এগুলি ব্যবহারকারীর নির্দিষ্ট প্রয়োজন অনুসারে কাস্টম যাচাইকরণ লজিক প্রয়োগ করতে সক্ষম।
Custom Matcher উদাহরণ:
ধরা যাক, আপনি একটি কাস্টম Matcher তৈরি করতে চান যা String এর মধ্যে কোনো নির্দিষ্ট সাবস্ট্রিং খুঁজে পাবে।
২. Custom Matchers কেন প্রয়োজন?
Custom Matchers এর প্রয়োজন পড়তে পারে যখন:
- Default Matchers আপনার টেস্টের জন্য পর্যাপ্ত নয় বা তারা আপনার প্রয়োজনের সাথে পুরোপুরি মিলে না।
- আপনি complex বা specific conditions যাচাই করতে চান যা সাধারণ Hamcrest বা JUnit Matchers দিয়ে সম্ভব নয়।
- Reusable conditions তৈরি করতে চান যেগুলি একাধিক টেস্টে ব্যবহৃত হতে পারে।
উদাহরণ: Complex Condition Matching
ধরা যাক, আপনার টেস্টে আপনি চান যে একটি লিস্টের মধ্যে শুধু এমন মান থাকতে হবে যা নির্দিষ্ট রেঞ্জের মধ্যে রয়েছে। এই ধরনের কাস্টম শর্ত যাচাই করতে Custom Matcher তৈরি করতে হবে।
৩. Custom Matcher তৈরি করা (Hamcrest)
Hamcrest একটি জনপ্রিয় লাইব্রেরি যা JUnit এর সাথে ব্যবহার করা হয়। এটি Matcher তৈরি এবং টেস্টের শর্ত যাচাই করার জন্য ব্যবহৃত হয়। নিচে একটি উদাহরণ দেয়া হলো যেখানে আমরা একটি কাস্টম Matcher তৈরি করব।
উদাহরণ: Custom Matcher তৈরি করা
Step 1: Hamcrest Dependency যুক্ত করা (Maven)
<dependencies>
<!-- Hamcrest Dependency -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Step 2: Custom Matcher তৈরি করা
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class StringContainsMatcher extends TypeSafeMatcher<String> {
private final String substring;
public StringContainsMatcher(String substring) {
this.substring = substring;
}
@Override
protected boolean matchesSafely(String item) {
return item.contains(substring);
}
@Override
public void describeTo(Description description) {
description.appendText("a string containing ").appendValue(substring);
}
public static Matcher<String> containsSubstring(String substring) {
return new StringContainsMatcher(substring);
}
}
এখানে, StringContainsMatcher একটি কাস্টম Matcher যা একটি স্ট্রিংয়ে নির্দিষ্ট সাবস্ট্রিং রয়েছে কিনা তা যাচাই করবে।
Step 3: JUnit টেস্টে Custom Matcher ব্যবহার করা
import org.junit.Test;
import static org.junit.Assert.assertThat;
public class CustomMatcherTest {
@Test
public void testStringContainsSubstring() {
String input = "Hello, world!";
assertThat(input, StringContainsMatcher.containsSubstring("world"));
}
}
এখানে, assertThat দিয়ে input স্ট্রিংটিকে যাচাই করা হয়েছে এবং containsSubstring কাস্টম Matcher ব্যবহার করে চেক করা হয়েছে যে স্ট্রিংটি "world" সাবস্ট্রিংটি ধারণ করে কিনা।
৪. Custom Matcher ব্যবহার করার সুবিধা
- Reusability: কাস্টম Matcher তৈরি করার মাধ্যমে আপনি একাধিক টেস্টে একই লজিক ব্যবহার করতে পারেন।
- Complex Conditions: JUnit বা Hamcrest এর ডিফল্ট Matchers দ্বারা যে শর্ত যাচাই করা সম্ভব নয়, তা কাস্টম Matcher দিয়ে যাচাই করা যায়।
- Clean Code: আপনার টেস্ট কোড ক্লিন এবং সহজবোধ্য হয় কারণ আপনি কাস্টম লজিক আলাদা করে রাখছেন, যা কোডের পুনরাবৃত্তি কমাতে সাহায্য করে।
৫. Custom Matcher এর অন্যান্য উদাহরণ
উদাহরণ: Collection Size Matcher
যদি আপনি একটি Collection এর সাইজ যাচাই করতে চান, তবে আপনি একটি কাস্টম Matcher তৈরি করতে পারেন যা নির্দিষ্ট সাইজের সংগ্রহের সাথে মিলে।
public class CollectionSizeMatcher extends TypeSafeMatcher<Collection<?>> {
private final int expectedSize;
public CollectionSizeMatcher(int expectedSize) {
this.expectedSize = expectedSize;
}
@Override
protected boolean matchesSafely(Collection<?> collection) {
return collection.size() == expectedSize;
}
@Override
public void describeTo(Description description) {
description.appendText("a collection of size ").appendValue(expectedSize);
}
public static Matcher<Collection<?>> hasSize(int size) {
return new CollectionSizeMatcher(size);
}
}
JUnit Test:
@Test
public void testCollectionSize() {
Collection<String> collection = Arrays.asList("A", "B", "C");
assertThat(collection, CollectionSizeMatcher.hasSize(3));
}
৬. JUnit 5 এবং Custom Matcher
JUnit 5 তে assertions এর কিছু নতুন বৈশিষ্ট্য রয়েছে, এবং আপনি Custom Matchers ব্যবহার করে আরও কার্যকরী এবং শক্তিশালী Assertions তৈরি করতে পারেন।
উদাহরণ: JUnit 5 এ Custom Matcher ব্যবহার
JUnit 5 তে assertAll এবং assertThat এর মাধ্যমে আপনি একাধিক কাস্টম Matcher ব্যবহার করতে পারেন।
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@Test
void testCustomMatcherWithJUnit5() {
assertThat("Hello, JUnit!", containsSubstring("JUnit"));
}
সারাংশ
Custom Matchers JUnit টেস্টিংয়ের একটি শক্তিশালী বৈশিষ্ট্য, যা আপনাকে বিশেষ লজিক এবং শর্ত যাচাই করতে সহায়তা করে। Hamcrest এর মাধ্যমে Custom Matchers তৈরি করতে পারেন যা JUnit টেস্টে ব্যবহার করা যায়। এর মাধ্যমে আপনি complex conditions, reusability, এবং clean code নিশ্চিত করতে পারেন। এটি আপনার টেস্ট কোডের দক্ষতা এবং গুণগত মান উন্নত করতে সহায়ক হয়।
Hamcrest হল একটি শক্তিশালী লাইব্রেরি যা JUnit টেস্টিং ফ্রেমওয়ার্কের সাথে একত্রে ব্যবহার করা হয়। এটি বিভিন্ন Matcher সরবরাহ করে যা আপনাকে টেস্টের মধ্যে জটিল সমতা, অবস্থা পরীক্ষা করতে সাহায্য করে। তবে, কখনও কখনও আপনাকে custom matcher তৈরি করতে হতে পারে যখন আপনি নির্দিষ্ট কিছু কাস্টম যাচাইকরণ বা লজিক প্রয়োগ করতে চান।
এই টিউটোরিয়ালে, আমরা Hamcrest লাইব্রেরি ব্যবহার করে Custom Matcher তৈরি করার পদ্ধতি আলোচনা করব।
১. Hamcrest Library Overview
Hamcrest হল একটি matcher library যা মূলত JUnit এর সাথে ব্যবহৃত হয়। এটি সহজ এবং স্বাভাবিক ভাষায় asserts বা checks তৈরি করার জন্য ডিজাইন করা হয়েছে। Hamcrest মাচাররা কিছু সাধারণ matchers যেমন is(), equalTo(), not(), greaterThan(), lessThan() ইত্যাদি সরবরাহ করে, তবে কখনও কখনও ডেভেলপারদের নিজের কাস্টম মাচার তৈরি করার প্রয়োজন হতে পারে।
২. Custom Matcher তৈরির প্রয়োজনীয়তা
কখনও কখনও, আপনার টেস্টে এমন কিছু লজিক থাকতে পারে যা Hamcrest এর ডিফল্ট matchers দিয়ে পরীক্ষা করা সম্ভব নয়। এ ধরনের পরিস্থিতিতে, Custom Matcher ব্যবহার করা হয় যা টেস্টের মধ্যে নির্দিষ্ট শর্ত বা নিয়ম পরীক্ষা করতে সহায়তা করে।
যেমন:
- যদি আপনি একটি অদ্ভুত শর্ত (অথবা অস্বাভাবিক যাচাইকরণ) বা কিছু ভ্যালিডেশন করতে চান, যেটি Hamcrest এর প্রাক-নির্ধারিত matchers দ্বারা সম্ভব নয়।
- আপনি যদি আপনার কাস্টম অ্যাসারশন বা লজিক তৈরি করতে চান।
৩. Custom Matcher তৈরি করার পদ্ধতি
Hamcrest লাইব্রেরিতে কাস্টম matcher তৈরি করতে হলে, আপনাকে Matcher ক্লাসটি ইমপ্লিমেন্ট করতে হবে এবং সেই অনুযায়ী মেথডগুলো তৈরি করতে হবে। নিচে একটি উদাহরণ দেওয়া হলো, যেখানে একটি কাস্টম matcher তৈরি করা হচ্ছে যা একটি সংখ্যাকে সঠিকভাবে চেক করবে।
৩.১ Custom Matcher এর উদাহরণ:
ধরা যাক, আপনি একটি Custom Matcher তৈরি করতে চান যা একটি নির্দিষ্ট গুণমানের সাথে সংখ্যাকে যাচাই করবে। উদাহরণস্বরূপ, যদি সংখ্যাটি ১০ এর বেশি হয় এবং তার সাথে একটি নির্দিষ্ট সীমা পূরণ হয়, তবে এটি match হবে।
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class GreaterThanTenMatcher extends TypeSafeMatcher<Integer> {
@Override
public void describeTo(Description description) {
description.appendText("a number greater than 10");
}
@Override
protected boolean matchesSafely(Integer item) {
return item > 10;
}
public static Matcher<Integer> greaterThanTen() {
return new GreaterThanTenMatcher();
}
}
এখানে, GreaterThanTenMatcher একটি কাস্টম matcher যা matchesSafely() মেথডে লজিক দিয়ে সংখ্যাটি ১০ এর বেশি কিনা পরীক্ষা করে। describeTo() মেথডটি ব্যর্থ হলে টেস্টের ব্যাখ্যা তৈরি করতে ব্যবহৃত হয়।
৩.২ Custom Matcher ব্যবহার করা
আপনি যখন আপনার কাস্টম matcher তৈরি করবেন, তখন এটি টেস্টে assertThat() এর সাথে ব্যবহার করতে পারবেন।
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
public class GreaterThanTenMatcherTest {
@Test
public void testGreaterThanTen() {
assertThat(15, GreaterThanTenMatcher.greaterThanTen()); // Test passes
assertThat(5, GreaterThanTenMatcher.greaterThanTen()); // Test fails
}
}
এখানে, assertThat() ব্যবহার করা হয়েছে যা GreaterThanTenMatcher.greaterThanTen() matcher এর মাধ্যমে সংখ্যাটিকে যাচাই করছে।
৪. Custom Matcher তৈরি করার আরেকটি উদাহরণ
ধরা যাক, আপনি একটি String যাচাই করতে চান যে এটি নির্দিষ্ট প্রিফিক্স দিয়ে শুরু হয় কিনা। এটির জন্য একটি কাস্টম matcher তৈরি করা যায়।
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class StartsWithMatcher extends TypeSafeMatcher<String> {
private final String prefix;
public StartsWithMatcher(String prefix) {
this.prefix = prefix;
}
@Override
protected boolean matchesSafely(String item) {
return item.startsWith(prefix);
}
@Override
public void describeTo(Description description) {
description.appendText("a string starting with ").appendValue(prefix);
}
public static Matcher<String> startsWith(String prefix) {
return new StartsWithMatcher(prefix);
}
}
এখানে, startsWith() মেথডের মাধ্যমে আপনি String এর প্রিফিক্স চেক করতে পারেন। এটি String শুরু হয় কি না তা যাচাই করবে।
৪.১ Custom String Matcher ব্যবহার করা
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
public class StartsWithMatcherTest {
@Test
public void testStartsWith() {
assertThat("Hello World", StartsWithMatcher.startsWith("Hello")); // Test passes
assertThat("Hello World", StartsWithMatcher.startsWith("Hi")); // Test fails
}
}
এখানে, StartsWithMatcher কাস্টম matcher এর মাধ্যমে আপনি টেস্টের মধ্যে যাচাই করছেন যে স্ট্রিংটি "Hello" দিয়ে শুরু হয় কিনা।
৫. Hamcrest Matcher তৈরির সুবিধা
- Reusable and Readable: কাস্টম মাচাররা টেস্ট কোডকে আরও সহজ এবং রিডেবল করে তোলে।
- Code Maintainability: আপনি একবার কাস্টম মাচার তৈরি করলে তা একাধিক টেস্ট কেসে ব্যবহার করতে পারেন, যা কোড রিড্যাবিলিটি এবং মেইনটেন্যান্স উন্নত করে।
- Flexibility: কাস্টম মাচাররা খুবই ফ্লেক্সিবল এবং আপনি আপনার টেস্টে বিশেষ শর্ত বা লজিক প্রয়োগ করতে পারবেন।
- Composability: কাস্টম মাচাররা অন্যান্য Hamcrest matchers এর সাথে কম্বাইন করে আরও জটিল লজিক তৈরি করতে পারে।
সারাংশ
Hamcrest লাইব্রেরি দিয়ে কাস্টম matcher তৈরি করা JUnit টেস্টিংয়ের জন্য একটি শক্তিশালী পদ্ধতি। এটি আপনাকে জটিল শর্তগুলো সহজভাবে যাচাই করতে সহায়তা করে, এবং আপনার টেস্টগুলোকে আরও সহজ, রিডেবল এবং মেইনটেইনেবল করে তোলে। TypeSafeMatcher ইন্টারফেস ব্যবহার করে, আপনি সহজেই কাস্টম matcher তৈরি করতে পারেন এবং এগুলোকে আপনার টেস্ট কেসে প্রয়োগ করতে পারেন।
JUnit হল একটি অত্যন্ত জনপ্রিয় এবং কার্যকরী টেস্টিং ফ্রেমওয়ার্ক যা Java অ্যাপ্লিকেশনের ইউনিট টেস্টিং এর জন্য ব্যবহৃত হয়। যখন আপনি JUnit ব্যবহার করেন, সাধারণত assertions এর মাধ্যমে আপনি পরীক্ষিত কোডের ফলাফল যাচাই করেন। JUnit Assertions সাধারণত প্রস্তুত করা assertion মেথডগুলি দিয়ে কাজ করে, যেমন assertEquals(), assertTrue(), assertFalse(), ইত্যাদি।
কিন্তু কখনও কখনও আপনার পরীক্ষাগুলির জন্য নির্দিষ্ট কাস্টম assertion তৈরি করতে হতে পারে। এই টিউটোরিয়ালে, আমরা কিভাবে Custom Assertions তৈরি এবং ব্যবহার করতে পারি তা আলোচনা করব।
১. Custom Assertions এর প্রয়োজনীয়তা
এটি তখন প্রয়োজনীয় হয় যখন আপনার টেস্টগুলি এমন কিছু জটিল লজিক বা ডেটা চেক করে যা JUnit এর ডিফল্ট assertion মেথডের মাধ্যমে যাচাই করা কঠিন বা অসম্ভব। Custom assertion তৈরি করে আপনি সেই যাচাইকরণের প্রক্রিয়াকে আরও পরিষ্কার এবং পুনরায় ব্যবহৃতযোগ্য (reusable) করতে পারেন।
উদাহরণস্বরূপ, আপনি একটি Person অবজেক্টের বয়স এবং নাম যাচাই করতে চান, তবে আপনার assertion কোড যদি একাধিক স্থানে ব্যবহৃত হয়, তবে তা Custom Assertion তৈরি করা সহজ এবং কোড পুনঃব্যবহারযোগ্যতার দিকে কাজ করবে।
২. JUnit Custom Assertion তৈরি করা
Custom assertion তৈরি করার জন্য একটি helper method বা একটি Utility ক্লাস তৈরি করা যেতে পারে, যেটি সাধারণত assert পদ্ধতির মতো কাজ করবে। এটি একটি সাধারণ ক্লাস হতে পারে, যা কোনো অবজেক্টের একটি নির্দিষ্ট প্রপার্টি পরীক্ষা করবে।
উদাহরণ: Person অবজেক্টের জন্য Custom Assertion তৈরি করা
ধরা যাক, আমাদের একটি Person ক্লাস রয়েছে এবং আমরা তার age এবং name প্রপার্টি যাচাই করতে চাই।
Person.java
public class Person {
private String name;
private int age;
// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
এখন, একটি Custom Assertion ক্লাস তৈরি করা যাক।
CustomAssertions.java
public class CustomAssertions {
// Custom assertion to check if the person's age is valid
public static void assertValidAge(int age) {
if (age < 0 || age > 150) {
throw new AssertionError("Age is not valid: " + age);
}
}
// Custom assertion to check if the person's name is valid (non-empty)
public static void assertValidName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new AssertionError("Name is not valid: " + name);
}
}
}
এখানে, আমরা দুটি কাস্টম assertion তৈরি করেছি:
- assertValidAge(): এটি যাচাই করবে যে বয়সের মান ০ থেকে ১৫০ এর মধ্যে রয়েছে।
- assertValidName(): এটি যাচাই করবে যে নামটি
nullবা খালি নয়।
৩. JUnit Test Case এ Custom Assertion ব্যবহার
এখন, আমরা JUnit টেস্ট কেস তৈরি করব যেখানে আমরা উপরের কাস্টম assertion গুলি ব্যবহার করব।
PersonTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.fail;
public class PersonTest {
@Test
public void testValidPerson() {
Person person = new Person("John", 25);
try {
CustomAssertions.assertValidName(person.getName());
CustomAssertions.assertValidAge(person.getAge());
} catch (AssertionError e) {
fail("Person validation failed: " + e.getMessage());
}
}
@Test
public void testInvalidAge() {
Person person = new Person("Jane", -5);
try {
CustomAssertions.assertValidAge(person.getAge());
fail("Expected AssertionError for invalid age");
} catch (AssertionError e) {
// Test passed, invalid age throws AssertionError
}
}
@Test
public void testInvalidName() {
Person person = new Person("", 30);
try {
CustomAssertions.assertValidName(person.getName());
fail("Expected AssertionError for invalid name");
} catch (AssertionError e) {
// Test passed, invalid name throws AssertionError
}
}
}
এখানে:
- testValidPerson() টেস্টে, আমরা একটি valid person যাচাই করব যার নাম এবং বয়স সঠিক।
- testInvalidAge() টেস্টে, আমরা একটি invalid age পরীক্ষা করব (যেমন -5), যা
AssertionErrorতৈরি করবে। - testInvalidName() টেস্টে, আমরা একটি empty name পরীক্ষা করব, যা আবারও
AssertionErrorতৈরি করবে।
৪. Custom Assertion ব্যবহার করার সুবিধা
- Code Reusability: একাধিক টেস্ট কেসে একই ধরনের যাচাইকরণ ব্যবহার করা যাবে, যা কোড পুনঃব্যবহারযোগ্যতা বৃদ্ধি করে।
- Clearer Test Cases: কাস্টম assertion এর মাধ্যমে, টেস্ট কেসগুলি আরও পরিষ্কার এবং সহজবোধ্য হয়, কারণ আপনি শুধু প্রাসঙ্গিক যাচাইকরণকে একটি মেথডের মাধ্যমে একত্রিত করেন।
- Better Error Messages: কাস্টম assertion এ আপনি ত্রুটির বার্তা কাস্টমাইজ করতে পারেন, যা ডিবাগিংকে আরও সহজ করে তোলে।
- Centralized Validation Logic: টেস্টের জন্য একত্রিত যাচাইকরণ লজিক তৈরি করা যায়, যা কোডে অন্যান্য জায়গায় ব্যবহার করা যায়।
৫. JUnit 5 এর নতুন ফিচারগুলির সাথে Custom Assertions
JUnit 5 তে assertAll() এবং assertThrows() এর মতো নতুন ফিচার রয়েছে যা কাস্টম assertion ব্যবহারের আরও কিছু সুযোগ প্রদান করে।
উদাহরণ: assertAll ব্যবহার করে একাধিক assertion একসাথে চালানো
import static org.junit.jupiter.api.Assertions.*;
public class PersonTest {
@Test
public void testPersonValidations() {
Person person = new Person("John", 25);
assertAll(
() -> CustomAssertions.assertValidName(person.getName()),
() -> CustomAssertions.assertValidAge(person.getAge())
);
}
}
এখানে, assertAll() ব্যবহার করে আমরা একাধিক কাস্টম assertion একসাথে চালাতে পারি।
সারাংশ
JUnit Custom Assertions হল একটি শক্তিশালী বৈশিষ্ট্য যা আপনাকে কাস্টম যাচাইকরণ লজিক তৈরি করতে এবং আপনার টেস্টগুলিকে আরও পরিষ্কার এবং রিচ করতে সহায়তা করে। যখন ডিফল্ট JUnit Assertions যথেষ্ট না হয়, তখন কাস্টম assertion ব্যবহার করে আপনি আপনার টেস্টিং প্রক্রিয়াকে আরও দক্ষ এবং পুনরাবৃত্তিযোগ্য করতে পারেন। JUnit 5 এর নতুন ফিচারগুলি কাস্টম assertion এর ব্যবহারের আরও সুযোগ সৃষ্টি করেছে, যেমন assertAll() এবং assertThrows()।
JUnit হল Java টেস্টিং ফ্রেমওয়ার্ক যা ইউনিট টেস্ট তৈরি এবং চালানোর জন্য ব্যবহৃত হয়। JUnit-এ Custom Matcher ব্যবহার করা হয় যখন আপনি কমপ্লেক্স অবজেক্টের উপর বৈশিষ্ট্য বা শর্ত যাচাই করতে চান। Hamcrest হল একটি জনপ্রিয় ম্যাচিং ফ্রেমওয়ার্ক যা JUnit এর সাথে ব্যবহার করা যায় এবং Custom Matcher তৈরি করার জন্য সহায়ক হয়।
এই গাইডে, আমরা একটি Complex Object এর ভ্যালিডেশন টেস্ট করার জন্য Custom Matcher তৈরি করার প্রক্রিয়া দেখব।
১. Custom Matcher কি?
Custom Matcher হল একটি কাস্টম শর্ত বা নিয়ম যা কোন অবজেক্ট বা ভ্যালু যাচাই করতে ব্যবহৃত হয়। JUnit বা Hamcrest ফ্রেমওয়ার্কের মাধ্যমে আপনি সহজেই assert করতে পারবেন, যেখানে ম্যাচার ব্যবহার করে আপনি কোন অবজেক্টের নির্দিষ্ট প্রপার্টি চেক করতে পারবেন।
Hamcrest এর ম্যাচার্স আপনাকে খুবই শক্তিশালী এবং পরিষ্কারভাবে কাস্টম শর্ত পরীক্ষা করার সুযোগ দেয়। আপনি যখন একটি Complex Object যাচাই করতে চান, তখন Custom Matcher খুবই উপকারী।
২. Hamcrest Matcher কিভাবে কাজ করে
Hamcrest এর মাধ্যমে Custom Matcher তৈরি করার জন্য, আপনি একটি Matcher<T> ইন্টারফেস ইমপ্লিমেন্ট করতে পারেন এবং সেখানে আপনি আপনার কাস্টম লজিক বা শর্ত নির্ধারণ করবেন।
Basic Example:
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class CustomMatcher extends TypeSafeMatcher<ComplexObject> {
private String expectedName;
public CustomMatcher(String expectedName) {
this.expectedName = expectedName;
}
@Override
protected boolean matchesSafely(ComplexObject complexObject) {
return complexObject.getName().equals(expectedName);
}
@Override
public void describeTo(Description description) {
description.appendText("Expected name to be: " + expectedName);
}
public static Matcher<ComplexObject> hasName(String name) {
return new CustomMatcher(name);
}
}
এখানে, আমরা একটি CustomMatcher তৈরি করেছি যা একটি ComplexObject এর নাম বৈশিষ্ট্য যাচাই করে। আপনি এই Matcher ব্যবহার করে assertThat বা assert করতে পারবেন।
৩. Complex Object Example
ধরা যাক, আপনার কাছে একটি ComplexObject ক্লাস রয়েছে যেটি বিভিন্ন প্রপার্টি ধারণ করে, এবং আপনি ঐ প্রপার্টির মান যাচাই করতে চান।
ComplexObject.java:
public class ComplexObject {
private String name;
private int age;
public ComplexObject(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
এখানে, ComplexObject দুটি প্রপার্টি ধারণ করে: name এবং age।
৪. JUnit Test Case with Custom Matcher
এখন আমরা JUnit টেস্ট কেস তৈরি করব যেখানে Hamcrest Matcher ব্যবহার করে আমরা ComplexObject এর name বৈশিষ্ট্য যাচাই করব।
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class ComplexObjectTest {
@Test
public void testComplexObjectName() {
ComplexObject complexObject = new ComplexObject("John", 25);
// Using Custom Matcher
assertThat(complexObject, CustomMatcher.hasName("John"));
}
@Test
public void testComplexObjectAge() {
ComplexObject complexObject = new ComplexObject("John", 25);
// Using default Hamcrest matcher
assertThat(complexObject.getAge(), is(25));
}
}
এখানে, প্রথম টেস্ট কেস testComplexObjectName এ আমরা CustomMatcher ব্যবহার করেছি, যা যাচাই করবে যে ComplexObject এর name প্রপার্টি "John" এর সমান কিনা।
assertThat ব্যবহার করে আমরা Hamcrest এর মাধ্যমে ম্যাচিং প্রক্রিয়া সোজা এবং পরিষ্কারভাবে করতে পারি।
৫. Custom Matcher এর সুবিধা
- Code Reusability: আপনি একবার কাস্টম ম্যাচার তৈরি করলে তা বিভিন্ন টেস্ট কেসে পুনরায় ব্যবহার করতে পারেন।
- Readability: Custom Matcher এর মাধ্যমে টেস্ট কেসগুলি পরিষ্কার এবং সহজে পাঠযোগ্য হয়।
- Complex Logic Validation: যখন আপনি বেশি কাস্টমাইজড বা জটিল ভ্যালিডেশন করতে চান, তখন Custom Matcher খুব কার্যকরী হয়।
- Extensibility: নতুন শর্ত বা লজিক যোগ করতে খুব সহজে Custom Matcher কাস্টমাইজ করা যায়।
৬. উপসংহার
JUnit এবং Hamcrest এর মাধ্যমে Custom Matcher তৈরি করে আপনি Complex Object এর ভ্যালিডেশন এবং পরীক্ষা আরও সহজ ও কার্যকরী করতে পারেন। কাস্টম ম্যাচিং ফাংশন তৈরি করলে আপনি জটিল অবজেক্টের বৈশিষ্ট্য যাচাই করার জন্য কাস্টম শর্ত যুক্ত করতে পারবেন, যা পরবর্তীতে আপনার টেস্টিং প্রক্রিয়াকে আরও শক্তিশালী এবং পরিষ্কার করে তুলবে।
এটি ডেভেলপারদের দ্রুত এবং নির্ভুল টেস্টিং করতে সহায়তা করবে এবং বড় এবং জটিল সিস্টেমে আরও কার্যকরী ফলাফল প্রদান করবে।
Read more