হিল্টের মতো ডিপেন্ডেন্সি ইনজেকশন ফ্রেমওয়ার্ক ব্যবহারের একটি সুবিধা হল এটি আপনার কোড পরীক্ষা করা সহজ করে তোলে।
ইউনিট পরীক্ষা
ইউনিট পরীক্ষার জন্য Hilt প্রয়োজন নয়, কারণ কনস্ট্রাক্টর ইনজেকশন ব্যবহার করে এমন একটি ক্লাস পরীক্ষা করার সময়, সেই ক্লাসটি ইন্সট্যান্টিয়েট করার জন্য আপনাকে Hilt ব্যবহার করতে হবে না। পরিবর্তে, আপনি ফেক বা মক ডিপেন্ডেন্সি পাস করে সরাসরি একটি ক্লাস কনস্ট্রাক্টর কল করতে পারেন, ঠিক যেমনটি আপনি যদি কনস্ট্রাক্টরটি টীকাযুক্ত না থাকে তবে করতেন:
কোটলিন
@ActivityScoped class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... } class AnalyticsAdapterTest { @Test fun `Happy path`() { // You don't need Hilt to create an instance of AnalyticsAdapter. // You can pass a fake or mock AnalyticsService. val adapter = AnalyticsAdapter(fakeAnalyticsService) assertEquals(...) } }
জাভা
@ActivityScope public class AnalyticsAdapter { private final AnalyticsService analyticsService; @Inject AnalyticsAdapter(AnalyticsService analyticsService) { this.analyticsService = analyticsService; } } public final class AnalyticsAdapterTest { @Test public void happyPath() { // You don't need Hilt to create an instance of AnalyticsAdapter. // You can pass a fake or mock AnalyticsService. AnalyticsAdapter adapter = new AnalyticsAdapter(fakeAnalyticsService); assertEquals(...); } }
এন্ড-টু-এন্ড পরীক্ষা
ইন্টিগ্রেশন পরীক্ষার জন্য, হিল্ট আপনার প্রোডাকশন কোডের মতোই নির্ভরতা ইনজেক্ট করে। হিল্টের সাথে পরীক্ষার জন্য কোনও রক্ষণাবেক্ষণের প্রয়োজন হয় না কারণ হিল্ট স্বয়ংক্রিয়ভাবে প্রতিটি পরীক্ষার জন্য উপাদানগুলির একটি নতুন সেট তৈরি করে।
পরীক্ষার নির্ভরতা যোগ করা হচ্ছে
আপনার পরীক্ষায় Hilt ব্যবহার করতে, আপনার প্রকল্পে hilt-android-testing নির্ভরতা অন্তর্ভুক্ত করুন:
খাঁজকাটা
dependencies { // For Robolectric tests. testImplementation 'com.google.dagger:hilt-android-testing:2.57.1' // ...with Kotlin. kaptTest 'com.google.dagger:hilt-android-compiler:2.57.1' // ...with Java. testAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.57.1' // For instrumented tests. androidTestImplementation 'com.google.dagger:hilt-android-testing:2.57.1' // ...with Kotlin. kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.57.1' // ...with Java. androidTestAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.57.1' }
কোটলিন
dependencies { // For Robolectric tests. testImplementation("com.google.dagger:hilt-android-testing:2.57.1") // ...with Kotlin. kaptTest("com.google.dagger:hilt-android-compiler:2.57.1") // ...with Java. testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.57.1") // For instrumented tests. androidTestImplementation("com.google.dagger:hilt-android-testing:2.57.1") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.57.1") // ...with Java. androidTestAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.57.1") }
UI পরীক্ষা সেটআপ
@HiltAndroidTest দিয়ে Hilt ব্যবহার করে এমন যেকোনো UI পরীক্ষায় আপনাকে অবশ্যই টীকা লিখতে হবে। এই টীকাটি প্রতিটি পরীক্ষার জন্য Hilt উপাদান তৈরির জন্য দায়ী।
এছাড়াও, আপনাকে পরীক্ষার ক্লাসে HiltAndroidRule যোগ করতে হবে। এটি উপাদানগুলির অবস্থা পরিচালনা করে এবং আপনার পরীক্ষায় ইনজেকশন সঞ্চালনের জন্য ব্যবহৃত হয়:
কোটলিন
@HiltAndroidTest class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) // UI tests here. }
জাভা
@HiltAndroidTest public final class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); // UI tests here. }
এরপর, আপনার পরীক্ষায় Hilt স্বয়ংক্রিয়ভাবে আপনার জন্য যে Application ক্লাস তৈরি করে তা সম্পর্কে জানতে হবে।
পরীক্ষার আবেদন
আপনাকে অবশ্যই এমন একটি Application অবজেক্টে Hilt ব্যবহার করে এমন ইন্সট্রুমেন্টেড পরীক্ষা চালাতে হবে যা Hilt সমর্থন করে। লাইব্রেরি পরীক্ষায় ব্যবহারের জন্য HiltTestApplication প্রদান করে। যদি আপনার পরীক্ষায় একটি ভিন্ন বেস অ্যাপ্লিকেশনের প্রয়োজন হয়, তাহলে পরীক্ষার জন্য কাস্টম অ্যাপ্লিকেশন দেখুন।
আপনার টেস্ট অ্যাপ্লিকেশনটি আপনার ইন্সট্রুমেন্টেড টেস্ট বা রোবোলেক্ট্রিক টেস্টে চালানোর জন্য সেট করতে হবে। নিম্নলিখিত নির্দেশাবলী হিল্টের জন্য নির্দিষ্ট নয়, তবে পরীক্ষায় চালানোর জন্য একটি কাস্টম অ্যাপ্লিকেশন কীভাবে নির্দিষ্ট করতে হয় তার সাধারণ নির্দেশিকা।
যন্ত্রযুক্ত পরীক্ষায় পরীক্ষার অ্যাপ্লিকেশন সেট করুন
ইন্সট্রুমেন্টেড টেস্টে হিল্ট টেস্ট অ্যাপ্লিকেশন ব্যবহার করার জন্য, আপনাকে একটি নতুন টেস্ট রানার কনফিগার করতে হবে। এটি হিল্টকে আপনার প্রকল্পের সমস্ত ইন্সট্রুমেন্টেড টেস্টের জন্য কাজ করতে সাহায্য করবে। নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন:
-
androidTestফোল্ডারেAndroidJUnitRunnerপ্রসারিত করে এমন একটি কাস্টম ক্লাস তৈরি করুন। -
newApplicationফাংশনটি ওভাররাইড করুন এবং জেনারেট করা Hilt টেস্ট অ্যাপ্লিকেশনের নামে পাস করুন।
কোটলিন
// A custom runner to set up the instrumented application class for tests. class CustomTestRunner : AndroidJUnitRunner() { override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application { return super.newApplication(cl, HiltTestApplication::class.java.name, context) } }
জাভা
// A custom runner to set up the instrumented application class for tests. public final class CustomTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException { return super.newApplication(cl, HiltTestApplication.class.getName(), context); } }
এরপর, আপনার Gradle ফাইলে এই টেস্ট রানারটি কনফিগার করুন যেমনটি instrumented unit test guide তে বর্ণিত হয়েছে। নিশ্চিত করুন যে আপনি সম্পূর্ণ ক্লাসপাথ ব্যবহার করছেন:
খাঁজকাটা
android { defaultConfig { // Replace com.example.android.dagger with your class path. testInstrumentationRunner "com.example.android.dagger.CustomTestRunner" } }
কোটলিন
android { defaultConfig { // Replace com.example.android.dagger with your class path. testInstrumentationRunner = "com.example.android.dagger.CustomTestRunner" } }
রোবোলেক্ট্রিক পরীক্ষায় পরীক্ষার অ্যাপ্লিকেশন সেট করুন
যদি আপনি আপনার UI লেয়ার পরীক্ষা করার জন্য Robolectric ব্যবহার করেন, তাহলে আপনি robolectric.properties ফাইলে কোন অ্যাপ্লিকেশন ব্যবহার করবেন তা নির্দিষ্ট করতে পারেন:
application = dagger.hilt.android.testing.HiltTestApplication
বিকল্পভাবে, আপনি Robolectric এর @Config টীকা ব্যবহার করে প্রতিটি পরীক্ষায় অ্যাপ্লিকেশনটি পৃথকভাবে কনফিগার করতে পারেন:
কোটলিন
@HiltAndroidTest @Config(application = HiltTestApplication::class) class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) // Robolectric tests here. }
জাভা
@HiltAndroidTest @Config(application = HiltTestApplication.class) class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); // Robolectric tests here. }
যদি আপনি ৪.২ এর কম ভার্সনের Android Gradle Plugin ব্যবহার করেন, তাহলে আপনার মডিউলের build.gradle ফাইলে নিম্নলিখিত কনফিগারেশন প্রয়োগ করে স্থানীয় ইউনিট পরীক্ষায় @AndroidEntryPoint ক্লাস রূপান্তর সক্ষম করুন:
খাঁজকাটা
hilt { enableTransformForLocalTests = true }
কোটলিন
hilt { enableTransformForLocalTests = true }
enableTransformForLocalTests সম্পর্কে আরও তথ্য Hilt ডকুমেন্টেশনে পাবেন।
পরীক্ষার বৈশিষ্ট্য
একবার হিল্ট আপনার পরীক্ষায় ব্যবহারের জন্য প্রস্তুত হয়ে গেলে, আপনি পরীক্ষার প্রক্রিয়াটি কাস্টমাইজ করতে বেশ কয়েকটি বৈশিষ্ট্য ব্যবহার করতে পারেন।
পরীক্ষায় প্রকারভেদ ইনজেক্ট করুন
একটি পরীক্ষায় টাইপ ইনজেক্ট করতে, ফিল্ড ইনজেকশনের জন্য @Inject ব্যবহার করুন। Hilt কে @Inject ক্ষেত্রগুলি পূরণ করতে বলার জন্য, hiltRule.inject() কল করুন।
একটি যন্ত্রচালিত পরীক্ষার নিম্নলিখিত উদাহরণটি দেখুন:
কোটলিন
@HiltAndroidTest class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) @Inject lateinit var analyticsAdapter: AnalyticsAdapter @Before fun init() { hiltRule.inject() } @Test fun `happy path`() { // Can already use analyticsAdapter here. } }
জাভা
@HiltAndroidTest public final class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); @Inject AnalyticsAdapter analyticsAdapter; @Before public void init() { hiltRule.inject(); } @Test public void happyPath() { // Can already use analyticsAdapter here. } }
একটি বাইন্ডিং প্রতিস্থাপন করুন
যদি আপনার কোনও নির্ভরতার নকল বা নকল উদাহরণ ইনজেক্ট করার প্রয়োজন হয়, তাহলে আপনাকে হিল্টকে বলতে হবে যে তারা প্রোডাকশন কোডে ব্যবহৃত বাইন্ডিং ব্যবহার না করে অন্য একটি ব্যবহার করতে। একটি বাইন্ডিং প্রতিস্থাপন করার জন্য, আপনাকে বাইন্ডিং ধারণকারী মডিউলটি একটি টেস্ট মডিউল দিয়ে প্রতিস্থাপন করতে হবে যাতে আপনি পরীক্ষায় ব্যবহার করতে চান এমন বাইন্ডিং থাকে।
উদাহরণস্বরূপ, ধরুন আপনার প্রোডাকশন কোডটি AnalyticsService এর জন্য একটি বাইন্ডিং ঘোষণা করে নিম্নরূপ:
কোটলিন
@Module @InstallIn(SingletonComponent::class) abstract class AnalyticsModule { @Singleton @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService }
জাভা
@Module @InstallIn(SingletonComponent.class) public abstract class AnalyticsModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( AnalyticsServiceImpl analyticsServiceImpl ); }
পরীক্ষাগুলিতে AnalyticsService বাইন্ডিং প্রতিস্থাপন করতে, test অথবা androidTest ফোল্ডারে জাল নির্ভরতা দিয়ে একটি নতুন Hilt মডিউল তৈরি করুন এবং @TestInstallIn দিয়ে এটি টীকা করুন। সেই ফোল্ডারের সমস্ত পরীক্ষা পরিবর্তে জাল নির্ভরতা দিয়ে ইনজেক্ট করা হয়।
কোটলিন
@Module @TestInstallIn( components = [SingletonComponent::class], replaces = [AnalyticsModule::class] ) abstract class FakeAnalyticsModule { @Singleton @Binds abstract fun bindAnalyticsService( fakeAnalyticsService: FakeAnalyticsService ): AnalyticsService }
জাভা
@Module @TestInstallIn( components = SingletonComponent.class, replaces = AnalyticsModule.class ) public abstract class FakeAnalyticsModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( FakeAnalyticsService fakeAnalyticsService ); }
একটি একক পরীক্ষায় একটি বাইন্ডিং প্রতিস্থাপন করুন
সকল পরীক্ষার পরিবর্তে একটি একক পরীক্ষায় একটি বাইন্ডিং প্রতিস্থাপন করতে, @UninstallModules অ্যানোটেশন ব্যবহার করে একটি পরীক্ষা থেকে একটি Hilt মডিউল আনইনস্টল করুন এবং পরীক্ষার ভিতরে একটি নতুন পরীক্ষা মডিউল তৈরি করুন।
পূর্ববর্তী সংস্করণের AnalyticsService উদাহরণ অনুসরণ করে, Hilt কে টেস্ট ক্লাসে @UninstallModules অ্যানোটেশন ব্যবহার করে প্রোডাকশন মডিউলটি উপেক্ষা করতে বলার মাধ্যমে শুরু করুন:
কোটলিন
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { ... }
জাভা
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest public final class SettingsActivityTest { ... }
এরপর, আপনাকে বাইন্ডিংটি প্রতিস্থাপন করতে হবে। টেস্ট ক্লাসের মধ্যে একটি নতুন মডিউল তৈরি করুন যা টেস্ট বাইন্ডিংকে সংজ্ঞায়িত করে:
কোটলিন
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { @Module @InstallIn(SingletonComponent::class) abstract class TestModule { @Singleton @Binds abstract fun bindAnalyticsService( fakeAnalyticsService: FakeAnalyticsService ): AnalyticsService } ... }
জাভা
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest public final class SettingsActivityTest { @Module @InstallIn(SingletonComponent.class) public abstract class TestModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( FakeAnalyticsService fakeAnalyticsService ); } ... }
এটি শুধুমাত্র একটি একক পরীক্ষার ক্লাসের জন্য বাইন্ডিং প্রতিস্থাপন করে। আপনি যদি সমস্ত পরীক্ষার ক্লাসের জন্য বাইন্ডিং প্রতিস্থাপন করতে চান, তাহলে উপরের বিভাগ থেকে @TestInstallIn অ্যানোটেশন ব্যবহার করুন। বিকল্পভাবে, আপনি রোবোলেক্ট্রিক পরীক্ষার জন্য test মডিউলে, অথবা ইন্সট্রুমেন্টেড পরীক্ষার জন্য androidTest মডিউলে টেস্ট বাইন্ডিং রাখতে পারেন। যখনই সম্ভব @TestInstallIn ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।
নতুন মান বাঁধাই করা
আপনার পরীক্ষার ক্ষেত্রগুলিকে সহজেই Hilt নির্ভরতা গ্রাফের সাথে আবদ্ধ করতে @BindValue অ্যানোটেশন ব্যবহার করুন। @BindValue দিয়ে একটি ক্ষেত্র টীকা করুন এবং এটি সেই ক্ষেত্রটির জন্য উপস্থিত যেকোনো যোগ্যতার সাথে ঘোষিত ক্ষেত্র ধরণের অধীনে আবদ্ধ হবে।
AnalyticsService উদাহরণে, আপনি @BindValue ব্যবহার করে AnalyticsService একটি জাল দিয়ে প্রতিস্থাপন করতে পারেন:
কোটলিন
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { @BindValue @JvmField val analyticsService: AnalyticsService = FakeAnalyticsService() ... }
জাভা
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest class SettingsActivityTest { @BindValue AnalyticsService analyticsService = FakeAnalyticsService(); ... }
এটি আপনার পরীক্ষায় একটি বাইন্ডিং প্রতিস্থাপন এবং একটি বাইন্ডিং উল্লেখ করা উভয়কেই সহজ করে তোলে, যার ফলে আপনি একই সময়ে উভয়ই করতে পারবেন।
@BindValue কোয়ালিফায়ার এবং অন্যান্য টেস্টিং অ্যানোটেশনের সাথে কাজ করে। উদাহরণস্বরূপ, যদি আপনি Mockito এর মতো টেস্টিং লাইব্রেরি ব্যবহার করেন, তাহলে আপনি এটি একটি রোবোলেকট্রিক পরীক্ষায় নিম্নরূপ ব্যবহার করতে পারেন:
কোটলিন
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock lateinit var qualifiedVariable: ExampleCustomType // Robolectric tests here }
জাভা
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock ExampleCustomType qualifiedVariable; // Robolectric tests here }
যদি আপনার মাল্টিবাইন্ডিং যোগ করার প্রয়োজন হয়, তাহলে আপনি @BindValueIntoSet এবং @BindValueIntoMap টীকা ব্যবহার করতে পারেন @BindValue এর পরিবর্তে। @BindValueIntoMap জন্য আপনাকে একটি ম্যাপ কী টীকা সহ ফিল্ডটি টীকা করতে হবে।
বিশেষ ক্ষেত্রে
হিল্ট অ-মানক ব্যবহারের ক্ষেত্রে সহায়তা করার জন্য বৈশিষ্ট্যগুলিও প্রদান করে।
পরীক্ষার জন্য কাস্টম অ্যাপ্লিকেশন
যদি আপনি HiltTestApplication ব্যবহার করতে না পারেন কারণ আপনার পরীক্ষার অ্যাপ্লিকেশনটির জন্য অন্য একটি অ্যাপ্লিকেশন প্রসারিত করার প্রয়োজন হয়, তাহলে একটি নতুন ক্লাস বা ইন্টারফেস @CustomTestApplication দিয়ে টীকা করুন, বেস ক্লাসের মান পাস করে আপনি জেনারেট করা Hilt অ্যাপ্লিকেশনটি প্রসারিত করতে চান।
@CustomTestApplication হিল্টের সাথে পরীক্ষার জন্য প্রস্তুত একটি Application ক্লাস তৈরি করবে যা আপনার পাস করা অ্যাপ্লিকেশনটিকে প্যারামিটার হিসাবে প্রসারিত করবে।
কোটলিন
@CustomTestApplication(BaseApplication::class) interface HiltTestApplication
জাভা
@CustomTestApplication(BaseApplication.class) interface HiltTestApplication { }
উদাহরণস্বরূপ, Hilt HiltTestApplication_Application নামে একটি Application তৈরি করে যা BaseApplication ক্লাসকে প্রসারিত করে। সাধারণভাবে, জেনারেট করা অ্যাপ্লিকেশনের নাম হল _Application এর সাথে সংযুক্ত টীকাযুক্ত ক্লাসের নাম। আপনাকে অবশ্যই জেনারেট করা Hilt টেস্ট অ্যাপ্লিকেশনটিকে আপনার ইন্সট্রুমেন্টেড টেস্ট বা রোবোলেক্ট্রিক টেস্টে চালানোর জন্য সেট করতে হবে যেমন Test application এ বর্ণিত হয়েছে।
আপনার ইন্সট্রুমেন্টেড টেস্টে একাধিক TestRule অবজেক্ট
যদি আপনার পরীক্ষায় অন্যান্য TestRule অবজেক্ট থাকে, তাহলে সমস্ত নিয়ম একসাথে কাজ করে তা নিশ্চিত করার একাধিক উপায় রয়েছে।
আপনি নিয়মগুলো এভাবে একত্রিত করতে পারেন:
কোটলিন
@HiltAndroidTest class SettingsActivityTest { @get:Rule var rule = RuleChain.outerRule(HiltAndroidRule(this)). around(SettingsActivityTestRule(...)) // UI tests here. }
জাভা
@HiltAndroidTest public final class SettingsActivityTest { @Rule public RuleChain rule = RuleChain.outerRule(new HiltAndroidRule(this)) .around(new SettingsActivityTestRule(...)); // UI tests here. }
বিকল্পভাবে, আপনি উভয় নিয়ম একই স্তরে ব্যবহার করতে পারেন যতক্ষণ না HiltAndroidRule প্রথমে কার্যকর হয়। @Rule অ্যানোটেশনে order অ্যাট্রিবিউট ব্যবহার করে কার্যকরকরণ ক্রম নির্দিষ্ট করুন। এটি শুধুমাত্র JUnit সংস্করণ 4.13 বা উচ্চতর সংস্করণে কাজ করে:
কোটলিন
@HiltAndroidTest class SettingsActivityTest { @get:Rule(order = 0) var hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) var settingsActivityTestRule = SettingsActivityTestRule(...) // UI tests here. }
জাভা
@HiltAndroidTest public final class SettingsActivityTest { @Rule(order = 0) public HiltAndroidRule hiltRule = new HiltAndroidRule(this); @Rule(order = 1) public SettingsActivityTestRule settingsActivityTestRule = new SettingsActivityTestRule(...); // UI tests here. }
লঞ্চফ্রেগমেন্টইনকন্টেইনার
androidx.fragment:fragment-testing লাইব্রেরি থেকে hilt-এর সাথে launchFragmentInContainer ব্যবহার করা সম্ভব নয়, কারণ এটি এমন একটি কার্যকলাপের উপর নির্ভর করে যা @AndroidEntryPoint এর সাথে টীকাযুক্ত নয়।
পরিবর্তে architecture-samples GitHub রিপোজিটরি থেকে launchFragmentInHiltContainer কোডটি ব্যবহার করুন।
সিঙ্গেলটন কম্পোনেন্ট উপলব্ধ হওয়ার আগে একটি এন্ট্রি পয়েন্ট ব্যবহার করুন
যখন হিল্ট পরীক্ষায় সিঙ্গেলটন উপাদান উপলব্ধ হওয়ার আগে একটি হিল্ট এন্ট্রি পয়েন্ট তৈরি করার প্রয়োজন হয়, তখন @EarlyEntryPoint অ্যানোটেশন একটি এস্কেপ হ্যাচ প্রদান করে।
@EarlyEntryPoint সম্পর্কে আরও তথ্য হিল্ট ডকুমেন্টেশনে পাওয়া যাবে।