একটি অ্যাপের উদাহরণ টার্গেট করুন

এই ধরনের ইন্সট্রুমেন্টেশন টেস্ট সাধারণ অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলোকে লক্ষ্য করে করা টেস্টগুলো থেকে খুব একটা আলাদা নয়। উল্লেখ্য যে, যে টেস্ট অ্যাপ্লিকেশনটিতে ইন্সট্রুমেন্টেশন অন্তর্ভুক্ত করা হয়েছে, সেটিকে অবশ্যই সেই অ্যাপ্লিকেশনটির সার্টিফিকেটের মতোই একই সার্টিফিকেট দিয়ে স্বাক্ষরিত হতে হবে, যেটিকে এটি লক্ষ্যবস্তু করছে।

মনে রাখবেন, এই নির্দেশিকাটি ধরে নেয় যে প্ল্যাটফর্ম সোর্স ট্রি ওয়ার্কফ্লো সম্পর্কে আপনার আগে থেকেই কিছু জ্ঞান আছে। যদি না থাকে, তবে অনুগ্রহ করে ‘প্রয়োজনীয়তা’ অংশটি দেখুন। এখানে যে উদাহরণটি দেওয়া হয়েছে তা হলো, নিজস্ব টেস্ট অ্যাপ্লিকেশন প্যাকেজে টার্গেট প্যাকেজ সেট করে একটি নতুন ইন্সট্রুমেন্টেশন টেস্ট লেখা। আপনি যদি এই ধারণাটির সাথে অপরিচিত হন, তবে অনুগ্রহ করে ‘প্ল্যাটফর্ম টেস্টিং পরিচিতি’ অংশটি পড়ে নিন।

এই নির্দেশিকাটি নমুনা হিসেবে নিম্নলিখিত পরীক্ষাটি ব্যবহার করে:

  • ফ্রেমওয়ার্ক/বেস/প্যাকেজ/শেল/টেস্ট

এগিয়ে যাওয়ার আগে একটি মোটামুটি ধারণা পেতে প্রথমে কোডটি দেখে নেওয়ার পরামর্শ দেওয়া হচ্ছে।

উৎস স্থান নির্ধারণ করুন

যেহেতু ইন্সট্রুমেন্টেশন টেস্টটি একটি অ্যাপ্লিকেশনকে লক্ষ্য করে করা হবে, তাই প্রচলিত নিয়ম অনুযায়ী টেস্ট সোর্স কোডটি প্ল্যাটফর্ম সোর্স ট্রিতে আপনার কম্পোনেন্ট সোর্স ডিরেক্টরির রুটের অধীনে একটি tests ডিরেক্টরিতে রাখতে হয়।

সেলফ-ইনস্ট্রুমেন্টিং টেস্টের এন্ড-টু-এন্ড উদাহরণে সোর্স লোকেশন সম্পর্কে আরও আলোচনা দেখুন।

ম্যানিফেস্ট ফাইল

একটি সাধারণ অ্যাপ্লিকেশনের মতোই, প্রতিটি ইন্সট্রুমেন্টেশন টেস্ট মডিউলের জন্য একটি ম্যানিফেস্ট ফাইল প্রয়োজন। যদি আপনি ফাইলটির নাম AndroidManifest.xml রাখেন এবং আপনার টেস্ট মডিউলের Android.mk এর পাশে এটি প্রদান করেন, তাহলে এটি BUILD_PACKAGE কোর মেকফাইল দ্বারা স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হয়ে যাবে।

আরও অগ্রসর হওয়ার আগে, প্রথমে অ্যাপ ম্যানিফেস্ট ওভারভিউটি পড়ে নেওয়ার জন্য বিশেষভাবে পরামর্শ দেওয়া হচ্ছে।

এখানে একটি ম্যানিফেস্ট ফাইলের মৌলিক উপাদান এবং তাদের কার্যকারিতা সম্পর্কে একটি সংক্ষিপ্ত বিবরণ দেওয়া হয়েছে।

স্যাম্পল গ্যারিট পরিবর্তনের ম্যানিফেস্ট ফাইলের সর্বশেষ সংস্করণটি এখানে পাওয়া যাবে: 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 অ্যাট্রিবিউটটি হলো অ্যাপ্লিকেশন প্যাকেজের নাম: এটি একটি অনন্য শনাক্তকারী যা অ্যান্ড্রয়েড অ্যাপ্লিকেশন ফ্রেমওয়ার্ক একটি অ্যাপ্লিকেশনকে (অথবা এই প্রসঙ্গে: আপনার টেস্ট অ্যাপ্লিকেশনকে) শনাক্ত করতে ব্যবহার করে। সিস্টেমের প্রতিটি ব্যবহারকারী সেই প্যাকেজের নামে শুধুমাত্র একটি অ্যাপ্লিকেশন ইনস্টল করতে পারে।

যেহেতু এটি পরীক্ষাধীন অ্যাপ্লিকেশন প্যাকেজ থেকে স্বাধীন একটি পরীক্ষামূলক অ্যাপ্লিকেশন প্যাকেজ, তাই একটি ভিন্ন প্যাকেজ নাম ব্যবহার করতে হবে: একটি প্রচলিত রীতি হলো এর শেষে .test সাফিক্সটি যোগ করা।

তাছাড়া, এই package অ্যাট্রিবিউটটি ComponentName#getPackageName() যা রিটার্ন করে তার অনুরূপ, এবং adb shell মাধ্যমে বিভিন্ন pm সাব-কমান্ড ব্যবহার করার জন্যও এটিই ব্যবহৃত হয়।

অনুগ্রহ করে আরও মনে রাখবেন যে, যদিও প্যাকেজের নামটি সাধারণত জাভা প্যাকেজের নামের মতোই হয়, বাস্তবে এর সাথে এর খুব সামান্যই সম্পর্ক রয়েছে। অন্য কথায়, আপনার অ্যাপ্লিকেশন (বা টেস্ট) প্যাকেজে যেকোনো প্যাকেজের নামের ক্লাস থাকতে পারে, যদিও অন্যদিকে, আপনি সরলতার জন্য আপনার অ্যাপ্লিকেশন বা টেস্টের শীর্ষ-স্তরের জাভা প্যাকেজের নামটি অ্যাপ্লিকেশন প্যাকেজের নামের মতোই রাখতে পারেন।

<uses-library android:name="android.test.runner" />

সমস্ত ইন্সট্রুমেন্টেশন টেস্টের জন্য এটি প্রয়োজন, কারণ সংশ্লিষ্ট ক্লাসগুলো একটি পৃথক ফ্রেমওয়ার্ক জার লাইব্রেরি ফাইলে প্যাকেজ করা থাকে, ফলে অ্যাপ্লিকেশন ফ্রেমওয়ার্ক দ্বারা টেস্ট প্যাকেজটি আহ্বান করা হলে অতিরিক্ত ক্লাসপাথ এন্ট্রির প্রয়োজন হয়।

android:targetPackage="com.android.shell"

এটি ইন্সট্রুমেন্টেশনের টার্গেট প্যাকেজকে com.android.shell এ সেট করে। যখন am instrument কমান্ডের মাধ্যমে ইন্সট্রুমেন্টেশনটি চালু করা হয়, তখন ফ্রেমওয়ার্ক com.android.shell প্রসেসটি পুনরায় চালু করে এবং টেস্ট সম্পাদনের জন্য প্রসেসটিতে ইন্সট্রুমেন্টেশন কোড ইনজেক্ট করে। এর মানে হলো, টেস্ট কোডটি পরীক্ষাধীন অ্যাপ্লিকেশনে চলমান সমস্ত ক্লাস ইনস্ট্যান্স অ্যাক্সেস করতে পারবে এবং প্রকাশিত টেস্ট হুকগুলোর উপর নির্ভর করে স্টেট পরিবর্তন করতেও সক্ষম হতে পারে।

সাধারণ কনফিগারেশন ফাইল

প্রতিটি নতুন টেস্ট মডিউলের একটি কনফিগারেশন ফাইল থাকা আবশ্যক, যা মডিউল মেটাডেটা, কম্পাইল-টাইম নির্ভরতা এবং প্যাকেজিং নির্দেশাবলী দিয়ে বিল্ড সিস্টেমকে পরিচালনা করে। বেশিরভাগ ক্ষেত্রে, সুং-ভিত্তিক ব্লুপ্রিন্ট ফাইল বিকল্পটিই যথেষ্ট। বিস্তারিত জানতে সিম্পল টেস্ট কনফিগারেশন দেখুন।

জটিল কনফিগারেশন ফাইল

আরও জটিল পরীক্ষার জন্য, আপনাকে অ্যান্ড্রয়েডের টেস্ট হারনেস, ট্রেড ফেডারেশন- এর জন্য একটি টেস্ট কনফিগারেশন ফাইলও লিখতে হবে।

টেস্ট কনফিগারেশনে টেস্ট ক্লাসে সরবরাহ করার জন্য বিশেষ ডিভাইস সেটআপ অপশন এবং ডিফল্ট আর্গুমেন্ট নির্দিষ্ট করা যেতে পারে।

স্যাম্পল গ্যারিট পরিবর্তনের কনফিগারেশন ফাইলের সর্বশেষ সংস্করণটি এখানে পাওয়া যাবে: 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>

এটি ট্রেড ফেডারেশনকে একটি নির্দিষ্ট target_preparer ব্যবহার করে টার্গেট ডিভাইসে ShellTests.apk ইনস্টল করতে নির্দেশ দেয়। ট্রেড ফেডারেশনে ডেভেলপারদের জন্য অনেক target preparer উপলব্ধ রয়েছে এবং টেস্ট সম্পাদনের আগে ডিভাইসটি সঠিকভাবে সেটআপ করা হয়েছে কিনা তা নিশ্চিত করতে এগুলি ব্যবহার করা যেতে পারে।

<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 স্টাইলের টেস্ট ক্লাস গ্রহণ করা সম্ভব হয়, এবং নমুনা গ্যারিট পরিবর্তনটিতে এর বৈশিষ্ট্যগুলোর কিছু অতি সাধারণ ব্যবহার রয়েছে।

স্যাম্পল গ্যারিট পরিবর্তনের সর্বশেষ সোর্স কোড এখানে পাওয়া যাবে: frameworks/base/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java

যদিও টেস্টিং প্যাটার্নগুলো সাধারণত কম্পোনেন্ট টিমের জন্য নির্দিষ্ট হয়ে থাকে, তবুও কিছু সাধারণভাবে কার্যকর ব্যবহারের ধরণ রয়েছে।

@SmallTest
@RunWith(AndroidJUnit4.class)
public final class FeatureFactoryImplTest {

JUnit4-এর একটি উল্লেখযোগ্য পার্থক্য হলো, টেস্টগুলোকে আর কোনো সাধারণ বেস টেস্ট ক্লাস থেকে ইনহেরিট করার প্রয়োজন হয় না; এর পরিবর্তে, আপনি সাধারণ জাভা ক্লাসে টেস্ট লেখেন এবং নির্দিষ্ট টেস্ট সেটআপ ও সীমাবদ্ধতা নির্দেশ করতে অ্যানোটেশন ব্যবহার করেন। এই উদাহরণে, আমরা নির্দেশ দিচ্ছি যে এই ক্লাসটি একটি অ্যান্ড্রয়েড 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() : -e <key> <value> এর মাধ্যমে am instrument পাঠানো কমান্ড লাইন আর্গুমেন্টসমূহ

স্থানীয়ভাবে তৈরি ও পরীক্ষা করুন

সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রে Atest ব্যবহার করুন।

আরও জটিল ক্ষেত্রগুলির জন্য, যেখানে ব্যাপকতর কাস্টমাইজেশনের প্রয়োজন হয়, সেখানে ইন্সট্রুমেন্টেশন নির্দেশাবলী অনুসরণ করুন।