এই ধরনের ইন্সট্রুমেন্টেশন টেস্ট, সাধারণ Android অ্যাপ্লিকেশনকে টার্গেট করা টেস্টের থেকে খুব বেশি আলাদা নয়। এটি মনে রাখা গুরুত্বপূর্ণ যে, যে টেস্ট অ্যাপ্লিকেশন ইনস্ট্রুমেন্টেশন অন্তর্ভুক্ত করে, সেটিকে সেই অ্যাপ্লিকেশন এর মতো একই সার্টিফিকেট দিয়ে সাইন করতে হবে, যেটিকে এটি টার্গেট করছে।
মনে রাখবেন যে এই নির্দেশিকা ধরে নেয় যে প্ল্যাটফর্ম সোর্স ট্রি ওয়ার্কফ্লো সম্পর্কে আপনার কিছু জ্ঞান আছে। না হলে, প্রয়োজনীয়তা দেখুন। এখানে যে উদাহরণটি কভার করা হয়েছে তা হল টার্গেট প্যাকেজ সহ একটি নতুন ইন্সট্রুমেন্টেশন টেস্ট লেখা যা নিজস্ব টেস্ট অ্যাপ্লিকেশন প্যাকেজে সেট করা হয়েছে। আপনি যদি এই ধারণা সম্পর্কে অপরিচিত হন, তাহলে প্ল্যাটফর্ম টেস্টিংয়ের ভূমিকা পড়ুন।
এই নির্দেশিকায় ফলো টেস্টকে নমুনা হিসেবে ব্যবহার করা হয়েছে:
- frameworks/base/packages/Shell/tests
এগিয়ে যাওয়ার আগে কোডটি একবার ব্রাউজ করে নিলে ভালো হয়, তাহলে একটি প্রাথমিক ধারণা পাওয়া যায়।
সোর্স লোকেশন ঠিক করুন
যেহেতু ইন্সট্রুমেন্টেশন টেস্ট কোনও অ্যাপ্লিকেশনকে টার্গেট করবে, তাই কনভেনশন
হল, প্ল্যাটফর্ম সোর্স ট্রি-তে আপনার কম্পোনেন্ট সোর্স ডিরেক্টরির
রুটের মধ্যে tests ডিরেক্টরিতে টেস্ট সোর্স কোড প্লেস করা।
সেল্ফ-ইনস্ট্রুমেন্টিং টেস্টের জন্য এন্ড-টু-এন্ড উদাহরণ-এ সোর্স লোকেশন সম্পর্কে আরও আলোচনা দেখুন।
ম্যানিফেস্ট ফাইল
সাধারণ অ্যাপ্লিকেশনের মতোই, প্রতিটি ইন্সট্রুমেন্টেশন টেস্ট মডিউলের জন্য একটি
ম্যানিফেস্ট ফাইল প্রয়োজন। আপনি যদি ফাইলটির নাম AndroidManifest.xml রাখেন এবং আপনার টেস্ট মডিউলের জন্য Android.mk-এর পাশে
সেটি প্রদান করেন, তাহলে BUILD_PACKAGE কোর মেকফাইলের
মাধ্যমে এটি অটোমেটিক অন্তর্ভুক্ত হয়ে যাবে।
এগিয়ে যাওয়ার আগে, প্রথমে অ্যাপ মেনিফেস্ট ওভারভিউ পড়ে নিলে ভালো হয়।
এটি ম্যানিফেস্ট ফাইলের প্রাথমিক কম্পোনেন্ট ও সেগুলির কার্যকারিতা সম্পর্কে একটি ওভারভিউ দেয়।
gerrit পরিবর্তনের স্যাম্পেলের জন্য ম্যানিফেস্ট ফাইলের লেটেস্ট ভার্সন এখানে অ্যাক্সেস করা যেতে পারে: https://android.googlesource.com/platform/frameworks/base/+/android17-release/packages/Shell/tests/AndroidManifest.xml
সুবিধার জন্য এখানে একটি স্ন্যাপশট অন্তর্ভুক্ত করা হয়েছে:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
<application>
<uses-library android:name="android.test.runner" />
<activity
android:name="com.android.shell.ActionSendMultipleConsumerActivity"
android:label="ActionSendMultipleConsumer"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.shell"
android:label="Tests for Shell" />
</manifest>
মেনিফেস্ট ফাইল সম্পর্কে কিছু বাছাই করা মন্তব্য:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.shell.tests">
package অ্যাট্রিবিউট হল অ্যাপ্লিকেশন প্যাকেজের নাম: এটি হল অনন্য শনাক্তকারী যা Android অ্যাপ্লিকেশন ফ্রেমওয়ার্ক কোনও অ্যাপ্লিকেশন (বা এই প্রসঙ্গে: আপনার টেস্ট অ্যাপ্লিকেশন) শনাক্ত করতে ব্যবহার করে। সিস্টেমের প্রতিটি ব্যবহারকারী
সেই প্যাকেজের নাম দিয়ে শুধুমাত্র একটি অ্যাপ্লিকেশন ইনস্টল করতে পারবেন।
যেহেতু এটি একটি টেস্ট অ্যাপ্লিকেশন প্যাকেজ, তাই টেস্ট করা হচ্ছে এমন অ্যাপ্লিকেশন প্যাকেজ থেকে
আলাদা, একটি ভিন্ন প্যাকেজের নাম ব্যবহার করতে হবে: একটি সাধারণ প্রথা
হল একটি প্রত্যয় .test যোগ করা।
এছাড়াও, এই package অ্যাট্রিবিউটটি
ComponentName#getPackageName()
থেকে পাওয়া অ্যাট্রিবিউটের মতো এবং adb shell-এর মাধ্যমে বিভিন্ন pm সাব
কমান্ডের সাথে ইন্টার্যাক্ট করার জন্য আপনি এটিই ব্যবহার করবেন।
এছাড়াও মনে রাখবেন যে প্যাকেজের নাম সাধারণত Java প্যাকেজের নামের মতো একই স্টাইলে হলেও, আসলে এর সাথে খুব কম জিনিসই করতে হয়। অন্যভাবে বলতে গেলে, আপনার অ্যাপ্লিকেশন (বা টেস্ট) প্যাকেজে যেকোনও প্যাকেজ নাম সহ ক্লাস থাকতে পারে, যদিও অন্যদিকে, আপনি সরলতার জন্য বেছে নিতে পারেন এবং আপনার অ্যাপ্লিকেশনে বা টেস্টে অ্যাপ্লিকেশন প্যাকেজ নামের মতো একই টপ লেভেল জাভা প্যাকেজ নাম থাকতে পারে।
<uses-library android:name="android.test.runner" />
সব ইনস্ট্রুমেন্টেশন টেস্টের জন্য এটি প্রয়োজন কারণ সংশ্লিষ্ট ক্লাসগুলি আলাদা ফ্রেমওয়ার্ক জার লাইব্রেরি ফাইলে প্যাকেজ করা থাকে, তাই অ্যাপ্লিকেশন ফ্রেমওয়ার্কের মাধ্যমে টেস্ট প্যাকেজ ইনভোক করা হলে অতিরিক্ত ক্লাসপাথ এন্ট্রি প্রয়োজন হয়।
android:targetPackage="com.android.shell"
এটি ইন্সট্রুমেন্টেশনের টার্গেট প্যাকেজকে com.android.shell হিসেবে সেট করে।
am instrument কমান্ডের মাধ্যমে ইন্সট্রুমেন্টেশন কল করা হলে, ফ্রেমওয়ার্ক
com.android.shell প্রসেস রিস্টার্ট করে এবং টেস্ট এক্সিকিউশনের জন্য
প্রসেসে ইন্সট্রুমেন্টেশন কোড ইনজেক্ট করে। এর অর্থ হল, টেস্ট কোডের কাছে
পরীক্ষা করা হচ্ছে এমন অ্যাপ্লিকেশনে রান করা সব ক্লাস ইনস্ট্যান্সের অ্যাক্সেস থাকবে এবং এটি
এক্সপোজ করা টেস্ট হুক অনুযায়ী স্টেট ম্যানিপুলেট করতে পারবে।
সহজ কনফিগারেশন ফাইল
প্রতিটি নতুন টেস্ট মডিউলে মডিউল মেটাডেটা, কম্পাইল-টাইম ডিপেন্ডেন্সি ও প্যাকেজিং নির্দেশাবলী সহ বিল্ড সিস্টেমকে ডাইরেক্ট করার জন্য একটি কনফিগারেশন ফাইল থাকতে হবে। বেশিরভাগ ক্ষেত্রে, Soong-ভিত্তিক, ব্লুপ্রিন্ট ফাইল বিকল্পটি যথেষ্ট। আরও তথ্যের জন্য সহজ টেস্ট কনফিগারেশন দেখুন।
জটিল কনফিগারেশন ফাইল
আরও জটিল পরীক্ষার জন্য, আপনাকে Android-এর টেস্ট হার্নেস, ট্রেড ফেডারেশনের জন্য একটি টেস্ট কনফিগারেশন ফাইলও লিখতে হবে।
টেস্ট কনফিগারেশন, টেস্ট ক্লাসকে সাপ্লাই করার জন্য বিশেষ ডিভাইস সেট-আপ বিকল্প ও ডিফল্ট আর্গুমেন্ট নির্দিষ্ট করতে পারে।
স্যাম্পেল gerrit পরিবর্তনের জন্য কনফিগারেশন ফাইলের লেটেস্ট ভার্সন এখানে অ্যাক্সেস করা যাবে: frameworks/base/packages/Shell/tests/AndroidTest.xml
সুবিধার জন্য এখানে একটি স্ন্যাপশট অন্তর্ভুক্ত করা হয়েছে:
<configuration description="Runs Tests for Shell.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="ShellTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.shell.tests" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
</configuration>
টেস্ট কনফিগারেশন ফাইল সম্পর্কে কিছু বাছাই করা মন্তব্য:
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="ShellTests.apk"/>
</target_preparer>
এটি Trade Federation-কে নির্দিষ্ট target_preparer ব্যবহার করে টার্গেট ডিভাইসে ShellTests.apk ইনস্টল করতে বলে। Trade Federation-এ ডেভেলপারদের জন্য অনেক টার্গেট প্রিপেয়ারার উপলভ্য এবং এগুলি ব্যবহার করে নিশ্চিত করা যেতে পারে যে টেস্ট এক্সিকিউশনের আগে ডিভাইসটি সঠিকভাবে সেট-আপ করা হয়েছে।
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.shell.tests"/>
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
এটি ট্রেড ফেডারেশন টেস্ট ক্লাস নির্দিষ্ট করে যা টেস্ট এক্সিকিউট করতে ব্যবহার করা হয় এবং ডিভাইসে এক্সিকিউট করার জন্য প্যাকেজ এবং টেস্ট রানার ফ্রেমওয়ার্ক পাস করে যা এই ক্ষেত্রে JUnit।
টেস্ট মডিউল কনফিগারেশন সম্পর্কে আরও তথ্য পেতে এখানে দেখুন
JUnit4 ফিচার
android-support-test লাইব্রেরিকে টেস্ট রানার হিসেবে ব্যবহার করলে নতুন
JUnit4 স্টাইলের টেস্ট ক্লাস গ্রহণ করা যায় এবং স্যাম্পেল Gerrit পরিবর্তনটিতে এর ফিচারের কিছু খুব প্রাথমিক
ব্যবহার রয়েছে।
স্যাম্পেল gerrit পরিবর্তনের জন্য লেটেস্ট সোর্স কোড এখানে অ্যাক্সেস করা যাবে: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
টেস্টিং প্যাটার্ন সাধারণত কম্পোনেন্ট টিমের জন্য নির্দিষ্ট হলেও, কিছু সাধারণত উপযোগী ব্যবহারের প্যাটার্ন আছে।
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {
JUnit4-এর একটি গুরুত্বপূর্ণ পার্থক্য হল, টেস্টগুলিকে আর কোনও সাধারণ বেস টেস্ট ক্লাস থেকে ইনহেরিট করতে হয় না; পরিবর্তে, আপনি সাধারণ Java ক্লাসে টেস্ট লেখেন এবং নির্দিষ্ট টেস্ট সেট-আপ ও সীমাবদ্ধতা বোঝাতে অ্যানোটেশন ব্যবহার করেন। এই উদাহরণে, আমরা নির্দেশ দিচ্ছি যে এই ক্লাসটি Android JUnit4 টেস্ট হিসেবে রান করতে হবে।
@SmallTest অ্যানোটেশনে সম্পূর্ণ টেস্ট ক্লাসের জন্য টেস্ট সাইজ নির্দিষ্ট করা হয়েছে: এই টেস্ট ক্লাসে যোগ করা সব
টেস্ট পদ্ধতি এই টেস্ট সাইজ অ্যানোটেশন ইনহেরিট করে।
প্রি-টেস্ট ক্লাস সেট-আপ, পোস্ট-টেস্ট টিয়ার ডাউন এবং পোস্ট-টেস্ট ক্লাস টিয়ার ডাউন:
JUnit4-এর setUp ও tearDown পদ্ধতির মতো।
Test অ্যানোটেশন আসল টেস্টের অ্যানোটেশনের জন্য ব্যবহার করা হয়।
@Before
public void setup() {
...
@Test
public void testGetProvider_shouldCacheProvider() {
...
JUnit4-এর মাধ্যমে প্রি-টেস্ট সেট-আপ করার জন্য পদ্ধতিতে @Before অ্যানোটেশন ব্যবহার করা হয়।
এই উদাহরণে ব্যবহার করা না হলেও, পোস্ট টেস্ট টিয়ারডাউনের জন্য @After-ও আছে।
একইভাবে, JUnit4-এর মাধ্যমে কোনও টেস্ট ক্লাসে সব টেস্ট এক্সিকিউট করার আগে সেট-আপ পারফর্ম করতে
এবং তারপরে টিয়ারডাউন করতে, @BeforeClass ও @AfterClass অ্যানোটেশন
মেথডে ব্যবহার করা যেতে পারে। মনে রাখবেন যে ক্লাস-স্কোপ সেট-আপ এবং টিয়ারডাউন পদ্ধতি
অবশ্যই স্ট্যাটিক হতে হবে।
পরীক্ষা পদ্ধতির ক্ষেত্রে, JUnit-এর আগের ভার্সনের মতো, সেগুলিকে আর test দিয়ে পদ্ধতির নাম শুরু করতে হবে না, পরিবর্তে, সেগুলির প্রত্যেকটিকে @Test দিয়ে অ্যানোটেট করতে হবে।
যথারীতি, টেস্ট পদ্ধতি অবশ্যই সর্বজনীন হতে হবে, কোনও রিটার্ন ভ্যালু ঘোষণা করা যাবে না,
কোনও প্যারামিটার নেওয়া যাবে না এবং ব্যতিক্রম দেখাতে পারে।
Context context = InstrumentationRegistry.getTargetContext();
যেহেতু JUnit4 টেস্টের জন্য আর কোনও সাধারণ বেস ক্লাস প্রয়োজন হয় না, তাই getContext() বা
getTargetContext() বেস ক্লাস পদ্ধতির মাধ্যমে Context ইনস্ট্যান্স পাওয়ার আর প্রয়োজন নেই;
পরিবর্তে, নতুন টেস্ট রানার InstrumentationRegistry-এর মাধ্যমে এগুলি ম্যানেজ করে,
যেখানে ইন্সট্রুমেন্টেশন ফ্রেমওয়ার্কের তৈরি করা প্রাসঙ্গিক ও এনভায়রনমেন্টাল সেট-আপ
স্টোর করা হয়। এই ক্লাসের মাধ্যমে, আপনি এগুলিও কল করতে পারবেন:
getInstrumentation():Instrumentationক্লাসের ইনস্ট্যান্সgetArguments():am instrument-এ পাস করা কমান্ড লাইন আর্গুমেন্ট, যা-e <key> <value>-এর মাধ্যমে করা হয়
লোকাল ডিভাইসে বিল্ড ও টেস্ট করা
সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রে, Atest ব্যবহার করুন।
আরও জটিল কেসের জন্য, যেখানে আরও বেশি কাস্টমাইজেশনের প্রয়োজন, সেখানে ইনস্ট্রুমেন্টেশন সংক্রান্ত নির্দেশাবলী অনুসরণ করুন।