একটি লোকাল টেস্ট সরাসরি আপনার নিজের ওয়ার্কস্টেশনে চলে, Android ডিভাইস বা এমুলেটরে নয়। সেই কারণে, এটি টেস্ট চালানোর জন্য Android ডিভাইসের পরিবর্তে আপনার লোকাল জাভা ভার্চুয়াল মেশিন (JVM) ব্যবহার করে। লোকাল টেস্টের মাধ্যমে আপনি আরও দ্রুত আপনার অ্যাপের লজিক মূল্যায়ন করতে পারবেন। তবে, Android ফ্রেমওয়ার্কের সাথে ইন্টার্যাক্ট করতে না পারার কারণে আপনি যে ধরনের টেস্ট চালাতে পারবেন তার উপর সীমাবদ্ধতা তৈরি হয়।
ইউনিট টেস্ট কোডের একটি ছোট অংশের আচরণ যাচাই করে, টেস্টের অধীনে ইউনিট। এটি সেই কোড এক্সিকিউট করে এবং ফলাফল চেক করে এটি করে।
ইউনিট টেস্ট সাধারণত সহজ হয়, তবে পরীক্ষা করা হচ্ছে এমন ইউনিট পরীক্ষা করার কথা মাথায় রেখে ডিজাইন করা না হলে, সেট-আপ করার সময় সমস্যা হতে পারে:
- আপনি যে কোড যাচাই করতে চান সেটি টেস্ট থেকে অ্যাক্সেসযোগ্য হতে হবে। যেমন, আপনি সরাসরি কোনও প্রাইভেট মেথড টেস্ট করতে পারবেন না। পরিবর্তে, আপনি সর্বজনীন API ব্যবহার করে ক্লাসটি পরীক্ষা করেন।
- আইসোলেশনে ইউনিট টেস্ট রান করার জন্য, টেস্টের অধীনে থাকা ইউনিটের ডিপেন্ডেন্সিগুলি অবশ্যই আপনার কন্ট্রোল করা কম্পোনেন্ট দ্বারা প্রতিস্থাপিত হতে হবে, যেমন ফেক বা অন্যান্য টেস্ট ডাবল। আপনার কোড Android ফ্রেমওয়ার্কের উপর নির্ভর করলে, এটি বিশেষভাবে সমস্যাজনক।
Android-এ সাধারণ ইউনিট টেস্টিং স্ট্র্যাটেজি সম্পর্কে জানতে, কী টেস্ট করতে হবে পড়ুন।
স্থানীয় টেস্টের লোকেশন
ডিফল্ট হিসেবে, লোকাল ইউনিট টেস্টের সোর্স ফাইল
module-name/src/test/-এ রাখা হয়। Android Studio ব্যবহার করে নতুন প্রোজেক্ট তৈরি করার সময়
এই ডিরেক্টরি আগে থেকেই থাকে।
টেস্টিং ডিপেন্ডেন্সি যোগ করা হচ্ছে
এছাড়াও, JUnit টেস্টিং ফ্রেমওয়ার্কের মাধ্যমে প্রদান করা স্ট্যান্ডার্ড API ব্যবহার করার জন্য আপনার প্রোজেক্টের টেস্টিং ডিপেন্ডেন্সি কনফিগার করতে হবে।
এটি করতে, আপনার অ্যাপের মডিউলের build.gradle ফাইল খুলুন এবং নিম্নলিখিত লাইব্রেরিগুলি
ডিপেন্ডেন্সি হিসেবে উল্লেখ করুন। testImplementation ফাংশন ব্যবহার করে উল্লেখ করুন যে
সেগুলি লোকাল টেস্ট সোর্স সেটে প্রযোজ্য, অ্যাপ্লিকেশনে নয়:
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
একটি লোকাল ইউনিট টেস্ট ক্লাস তৈরি করুন
আপনি JUnit 4 টেস্ট ক্লাস হিসেবে আপনার লোকাল ইউনিট টেস্ট ক্লাস লেখেন।
এটি করতে, এক বা একাধিক টেস্ট পদ্ধতি সহ একটি ক্লাস তৈরি করুন, সাধারণত
module-name/src/test/-এ। একটি টেস্ট মেথড @Test অ্যানোটেশন দিয়ে শুরু হয় এবং
এতে এমন কোড থাকে যা আপনি যে কম্পোনেন্ট টেস্ট করতে চান তার একটি দিক
প্রয়োগ ও যাচাই করে।
নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে লোকাল ইউনিট টেস্ট ক্লাস প্রয়োগ করতে হয়। test
মেথড emailValidator_correctEmailSimple_returnsTrue()যাচাই করার চেষ্টা করে
isValidEmail(),যা অ্যাপের মধ্যে একটি মেথড। test ফাংশন true রিটার্ন করবে
যদিisValidEmail()-ও true রিটার্ন করে।
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
জাভা
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
আপনার অ্যাপের কম্পোনেন্ট প্রত্যাশিত ফলাফল প্রদান করছে কিনা তা মূল্যায়ন করার জন্য আপনার রিডেবল টেস্ট তৈরি করা উচিত। আমরা আপনাকে junit.Assert, Hamcrest বা
Truth-এর মতো
অ্যাসার্শন লাইব্রেরি ব্যবহার করার সাজেশন দিই। উপরে দেখানো স্নিপেটটি হল
junit.Assert কীভাবে ব্যবহার করতে হয় তার উদাহরণ।
মক করা যায় এমন Android লাইব্রেরি
আপনি লোকাল ইউনিট টেস্ট এক্সিকিউট করলে, Android Gradle প্লাগ-ইন-এ একটি লাইব্রেরি অন্তর্ভুক্ত থাকে যাতে Android ফ্রেমওয়ার্কের সব API থাকে, আপনার প্রোজেক্টে ব্যবহার করা ভার্সনের সাথে এটি সঠিক হয়। লাইব্রেরিতে সেইসব API-এর সব পাবলিক পদ্ধতি ও ক্লাস থাকে, তবে পদ্ধতির মধ্যে থাকা কোড সরিয়ে দেওয়া হয়েছে। কোনও পদ্ধতি অ্যাক্সেস করা হলে, টেস্টটি একটি ব্যতিক্রম দেখায়।
এটি Android ফ্রেমওয়ার্কে Context-এর মতো ক্লাস রেফারেন্স করার সময় লোকাল টেস্ট তৈরি করার অনুমতি দেয়। আরও গুরুত্বপূর্ণ হল, এটি আপনাকে Android ক্লাসের সাথে মকিং ফ্রেমওয়ার্ক ব্যবহার করার অনুমতি দেয়।
Android ডিপেন্ডেন্সি মক করা
একটি সাধারণ সমস্যা হল, কোনও ক্লাস স্ট্রিং রিসোর্স ব্যবহার করছে কিনা তা খুঁজে বের করা। আপনি
Context ক্লাসে getString() মেথড কল করে স্ট্রিং রিসোর্স
পেতে পারেন। তবে, লোকাল টেস্ট Context বা এর কোনও পদ্ধতি ব্যবহার করতে পারে না কারণ সেগুলি
Android ফ্রেমওয়ার্কের অন্তর্গত। সাধারণত, getString()-এ কল করার কোডটি
ক্লাস থেকে সরিয়ে নেওয়া উচিত, তবে এটি সবসময় সম্ভব হয় না। সমাধান হল Context-এর মক বা স্টাব তৈরি করা যা getString() পদ্ধতি কল করা হলে সবসময় একই ভ্যালু রিটার্ন করে।
মক করা যায় এমন Android লাইব্রেরি এবং মকিং ফ্রেমওয়ার্ক যেমন Mockito বা MockK-এর সাহায্যে, আপনি ইউনিট টেস্টে Android ক্লাসের মকের আচরণ প্রোগ্রাম করতে পারবেন।
Mockito ব্যবহার করে আপনার লোকাল ইউনিট টেস্টে মক অবজেক্ট যোগ করতে, এই প্রোগ্রামিং মডেল অনুসরণ করুন:
- আপনার টেস্টিং এনভায়রনমেন্ট সেট-আপ করুন লিঙ্কে যেভাবে বর্ণনা করা হয়েছে, সেইভাবে আপনার
build.gradleফাইলে Mockito লাইব্রেরি ডিপেন্ডেন্সি অন্তর্ভুক্ত করুন। - আপনার ইউনিট টেস্ট ক্লাস ডেফিনিশনের শুরুতে,
@RunWith(MockitoJUnitRunner.class)অ্যানোটেশন যোগ করুন। এই অ্যানোটেশন Mockito টেস্ট রানারকে বলে যে ফ্রেমওয়ার্কের ব্যবহার সঠিক কিনা তা যাচাই করতে এবং আপনার মক অবজেক্টের ইনিশিয়ালাইজেশনকে সহজ করে। - Android ডিপেন্ডেন্সির জন্য মক অবজেক্ট তৈরি করতে, ফিল্ড ডিক্লেয়ারেশনের আগে
@Mockঅ্যানোটেশন যোগ করুন। - ডিপেন্ডেন্সির আচরণ স্টাব করতে, আপনি একটি শর্ত নির্দিষ্ট করতে পারেন এবং
শর্ত পূরণ হলে
when()এবংthenReturn()পদ্ধতি ব্যবহার করে ভ্যালু রিটার্ন করতে পারেন।
নিচের উদাহরণে দেখানো হয়েছে যে আপনি কীভাবে এমন একটি ইউনিট টেস্ট তৈরি করতে পারেন যা Mockito-Kotlin-এর মাধ্যমে তৈরি করা Kotlin-এ মক
Context অবজেক্ট ব্যবহার করে।
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
Mockito ফ্রেমওয়ার্ক ব্যবহার করার ব্যাপারে আরও জানতে, Mockito API
রেফারেন্স এবং স্যাম্পেল কোডে SharedPreferencesHelperTest ক্লাস
দেখুন। এছাড়াও, Android টেস্টিং কোডল্যাব ব্যবহার করে দেখুন।
সমস্যা: "পদ্ধতি ... মক করা হয়নি"
আপনি Error: "Method ... not mocked মেসেজ সহ Mockable Android লাইব্রেরির কোনও পদ্ধতি অ্যাক্সেস করার চেষ্টা করলে,
এটি একটি ব্যতিক্রম থ্রো করে।
ব্যতিক্রমগুলি আপনার পরীক্ষার জন্য সমস্যাজনক হলে, আপনি আচরণ পরিবর্তন করতে পারেন যাতে পদ্ধতিগুলি রিটার্ন টাইপের উপর নির্ভর করে শূন্য বা শূন্য রিটার্ন করে। এটি করতে, Groovy-তে আপনার প্রোজেক্টের
টপ-লেভেল build.gradle ফাইলে নিম্নলিখিত কনফিগারেশন যোগ করুন:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}