হিল্টের মতো নির্ভরতা ইনজেকশন ফ্রেমওয়ার্ক ব্যবহার করার সুবিধাগুলির মধ্যে একটি হল এটি আপনার কোড পরীক্ষা করা সহজ করে তোলে।
ইউনিট পরীক্ষা
ইউনিট পরীক্ষার জন্য হিল্ট প্রয়োজনীয় নয়, যেহেতু কনস্ট্রাক্টর ইনজেকশন ব্যবহার করে এমন একটি ক্লাস পরীক্ষা করার সময়, সেই ক্লাসটি ইনস্ট্যান্টিয়েট করার জন্য আপনাকে হিল্ট ব্যবহার করতে হবে না। পরিবর্তে, আপনি জাল বা উপহাস নির্ভরতা পাস করে সরাসরি একটি ক্লাস কনস্ট্রাক্টরকে কল করতে পারেন, ঠিক যেমন আপনি যদি কনস্ট্রাক্টরকে টীকা না দেওয়া হয়:
কোটলিন
@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-android-testing
নির্ভরতা অন্তর্ভুক্ত করুন:
গ্রোভি
dependencies { // For Robolectric tests. testImplementation 'com.google.dagger:hilt-android-testing:2.51.1' // ...with Kotlin. kaptTest 'com.google.dagger:hilt-android-compiler:2.51.1' // ...with Java. testAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.51.1' // For instrumented tests. androidTestImplementation 'com.google.dagger:hilt-android-testing:2.51.1' // ...with Kotlin. kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.51.1' // ...with Java. androidTestAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.51.1' }
কোটলিন
dependencies { // For Robolectric tests. testImplementation("com.google.dagger:hilt-android-testing:2.51.1") // ...with Kotlin. kaptTest("com.google.dagger:hilt-android-compiler:2.51.1") // ...with Java. testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.51.1") // For instrumented tests. androidTestImplementation("com.google.dagger:hilt-android-testing:2.51.1") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.51.1") // ...with Java. androidTestAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.51.1") }
UI পরীক্ষা সেটআপ
@HiltAndroidTest
এর সাথে Hilt ব্যবহার করে এমন কোনো UI পরীক্ষা আপনাকে অবশ্যই টীকা করতে হবে। এই টীকাটি প্রতিটি পরীক্ষার জন্য হিল্ট উপাদান তৈরি করার জন্য দায়ী।
এছাড়াও, আপনাকে পরীক্ষার ক্লাসে 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. }
এর পরে, আপনার পরীক্ষার Application
ক্লাস সম্পর্কে জানতে হবে যা হিল্ট স্বয়ংক্রিয়ভাবে আপনার জন্য তৈরি করে।
পরীক্ষার আবেদন
আপনাকে অবশ্যই ইন্সট্রুমেন্টেড টেস্টগুলি চালাতে হবে যা হিল্টকে সমর্থন করে এমন একটি Application
অবজেক্টে হিল্ট ব্যবহার করে। লাইব্রেরি পরীক্ষায় ব্যবহারের জন্য HiltTestApplication
প্রদান করে। যদি আপনার পরীক্ষার জন্য একটি ভিন্ন বেস অ্যাপ্লিকেশনের প্রয়োজন হয়, পরীক্ষার জন্য কাস্টম অ্যাপ্লিকেশন দেখুন।
আপনার ইনস্ট্রুমেন্টেড পরীক্ষা বা রোবোলেক্ট্রিক পরীক্ষায় চালানোর জন্য আপনাকে অবশ্যই আপনার পরীক্ষার অ্যাপ্লিকেশন সেট করতে হবে। নিম্নলিখিত নির্দেশাবলী হিল্টের জন্য নির্দিষ্ট নয়, তবে পরীক্ষা চালানোর জন্য একটি কাস্টম অ্যাপ্লিকেশন কীভাবে নির্দিষ্ট করতে হয় সে সম্পর্কে সাধারণ নির্দেশিকা।
যন্ত্রযুক্ত পরীক্ষায় পরীক্ষার আবেদন সেট করুন
ইন্সট্রুমেন্টেড টেস্টে হিল্ট টেস্ট অ্যাপ্লিকেশন ব্যবহার করতে, আপনাকে একটি নতুন টেস্ট রানার কনফিগার করতে হবে। এটি আপনার প্রজেক্টের সমস্ত যন্ত্রযুক্ত পরীক্ষার জন্য হিল্টকে কাজ করে। নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন:
- একটি কাস্টম ক্লাস তৈরি করুন যা
androidTest
ফোল্ডারেAndroidJUnitRunner
প্রসারিত করে। -
newApplication
ফাংশনটি ওভাররাইড করুন এবং জেনারেট করা হিল্ট পরীক্ষা অ্যাপ্লিকেশনের নামে পাস করুন।
কোটলিন
// 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); } }
এর পরে, আপনার গ্রেডল ফাইলে এই টেস্ট রানারটি কনফিগার করুন যেমন ইন্সট্রুমেন্টেড ইউনিট টেস্ট গাইডে বর্ণিত হয়েছে। আপনি সম্পূর্ণ ক্লাসপথ ব্যবহার নিশ্চিত করুন:
গ্রোভি
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. }
আপনি যদি 4.2 এর চেয়ে কম একটি Android Gradle Plugin সংস্করণ ব্যবহার করেন, তাহলে আপনার মডিউলের build.gradle
ফাইলে নিম্নলিখিত কনফিগারেশন প্রয়োগ করে স্থানীয় ইউনিট পরীক্ষায় @AndroidEntryPoint
ক্লাসগুলিকে রূপান্তরিত করতে সক্ষম করুন:
গ্রোভি
hilt { enableTransformForLocalTests = true }
কোটলিন
hilt { enableTransformForLocalTests = true }
হিল্ট ডকুমেন্টেশনে enableTransformForLocalTests
সম্পর্কে আরও তথ্য।
পরীক্ষার বৈশিষ্ট্য
একবার হিল্ট আপনার পরীক্ষায় ব্যবহারের জন্য প্রস্তুত হয়ে গেলে, আপনি পরীক্ষার প্রক্রিয়া কাস্টমাইজ করতে বেশ কয়েকটি বৈশিষ্ট্য ব্যবহার করতে পারেন।
পরীক্ষায় ইনজেকশনের ধরন
একটি পরীক্ষায় প্রকারগুলি ইনজেকশন করতে, ফিল্ড ইনজেকশনের জন্য @Inject
ব্যবহার করুন। @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
ফোল্ডারে একটি নতুন হিল্ট মডিউল তৈরি করুন এবং @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
টীকা ব্যবহার করে একটি পরীক্ষা থেকে একটি হিল্ট মডিউল আনইনস্টল করুন এবং পরীক্ষার ভিতরে একটি নতুন পরীক্ষা মডিউল তৈরি করুন।
পূর্ববর্তী সংস্করণ থেকে AnalyticsService
উদাহরণ অনুসরণ করে, পরীক্ষা ক্লাসে @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
ব্যবহার করা।
নতুন মান বাঁধাই
হিল্ট নির্ভরতা গ্রাফে আপনার পরীক্ষায় ক্ষেত্রগুলিকে সহজেই আবদ্ধ করতে @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 }
আপনি যদি একটি মাল্টিবাইন্ডিং যোগ করতে চান, তাহলে আপনি @BindValue
এর জায়গায় @BindValueIntoSet
এবং @BindValueIntoMap
টীকা ব্যবহার করতে পারেন। @BindValueIntoMap
জন্য আপনাকে একটি মানচিত্র কী টীকা সহ ক্ষেত্রটি টীকা করতে হবে।
বিশেষ ক্ষেত্রে
হিল্ট অমানক ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য বৈশিষ্ট্যগুলিও সরবরাহ করে।
পরীক্ষার জন্য কাস্টম অ্যাপ্লিকেশন
আপনি যদি HiltTestApplication
ব্যবহার করতে না পারেন কারণ আপনার পরীক্ষার অ্যাপ্লিকেশনটিকে অন্য একটি অ্যাপ্লিকেশন প্রসারিত করতে হবে, তাহলে @CustomTestApplication
এর সাথে একটি নতুন ক্লাস বা ইন্টারফেস টীকা করুন, যে বেস ক্লাসের মানটি আপনি তৈরি করা হিল্ট অ্যাপ্লিকেশনটিকে প্রসারিত করতে চান তার মান দিয়ে।
@CustomTestApplication
হিল্টের সাথে পরীক্ষার জন্য প্রস্তুত একটি Application
ক্লাস তৈরি করবে যা প্যারামিটার হিসাবে আপনার পাস করা অ্যাপ্লিকেশনটিকে প্রসারিত করবে।
কোটলিন
@CustomTestApplication(BaseApplication::class) interface HiltTestApplication
জাভা
@CustomTestApplication(BaseApplication.class) interface HiltTestApplication { }
উদাহরণে, হিল্ট একটি Application
তৈরি করে যার নাম HiltTestApplication_Application
যা BaseApplication
ক্লাস প্রসারিত করে। সাধারণভাবে, জেনারেট করা অ্যাপ্লিকেশনটির নাম হল _Application
সাথে যুক্ত টীকাযুক্ত শ্রেণীর নাম। টেস্ট অ্যাপ্লিকেশানে বর্ণিত হিসাবে আপনার ইন্সট্রুমেন্টেড পরীক্ষা বা রোবোলেক্ট্রিক পরীক্ষায় চালানোর জন্য আপনাকে অবশ্যই জেনারেট করা হিল্ট টেস্ট অ্যাপ্লিকেশন সেট করতে হবে।
আপনার ইনস্ট্রুমেন্টেড টেস্টে একাধিক টেস্টরুল অবজেক্ট
আপনার পরীক্ষায় অন্যান্য 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. }
FragmentInContainer চালু করুন
হিল্টের সাথে androidx.fragment:fragment-testing
লাইব্রেরি থেকে launchFragmentInContainer
ব্যবহার করা সম্ভব নয়, কারণ এটি এমন একটি কার্যকলাপের উপর নির্ভর করে যা @AndroidEntryPoint
এর সাথে টীকা করা হয়নি।
পরিবর্তে architecture-samples
GitHub সংগ্রহস্থল থেকে launchFragmentInHiltContainer
কোড ব্যবহার করুন।
সিঙ্গেলটন উপাদান উপলব্ধ হওয়ার আগে একটি এন্ট্রি পয়েন্ট ব্যবহার করুন
@EarlyEntryPoint
টীকাটি একটি এস্কেপ হ্যাচ প্রদান করে যখন হিল্ট পরীক্ষায় সিঙ্গেলটন উপাদান উপলব্ধ হওয়ার আগে একটি হিল্ট এন্ট্রি পয়েন্ট তৈরি করা প্রয়োজন।
হিল্ট ডকুমেন্টেশনে @EarlyEntryPoint
সম্পর্কে আরও তথ্য।