টেস্ট ম্যাপিং

এটি হল টেস্ট ম্যাপ করা সম্পর্কে সংক্ষিপ্ত ভূমিকা এবং কীভাবে Android ওপেন সোর্স প্রজেক্টে (AOSP) টেস্ট কনফিগার করা শুরু করতে হয় তার ব্যাখ্যা।

টেস্ট ম্যাপিং সম্পর্কে

টেস্ট ম্যাপিং হল Gerrit-ভিত্তিক একটি পদ্ধতি যা ডেভেলপারদের Android সোর্স ট্রি-তে সরাসরি প্রিসাবমিট ও পোস্টসাবমিট টেস্ট নিয়ম তৈরি করতে এবং টেস্ট ইনফ্রাস্ট্রাকচারে পরীক্ষা করার জন্য ব্রাঞ্চ ও ডিভাইসের সিদ্ধান্ত ছেড়ে দিতে দেয়। টেস্ট ম্যাপিংয়ের সংজ্ঞা হল TEST_MAPPING নামের JSON ফাইল যা আপনি যেকোনও সোর্স ডিরেক্টরিতে রাখতে পারেন।

Atest, TEST_MAPPING ফাইল ব্যবহার করে সংশ্লিষ্ট ডিরেক্টরিতে প্রিসাবমিট টেস্ট রান করতে পারে। টেস্ট ম্যাপিংয়ের মাধ্যমে, আপনি Android সোর্স ট্রি-তে সামান্য পরিবর্তন করে প্রিসাবমিট চেকের সাথে একই টেস্টের সেট যোগ করতে পারবেন।

এইসব উদাহরণ দেখুন:

টেস্ট ম্যাপিং, টেস্ট এক্সিকিউশন ও ফলাফল রিপোর্টিংয়ের জন্য ট্রেড ফেডারেশন (TF) টেস্ট হারনেস-এর উপর নির্ভর করে।

টেস্ট গ্রুপ নির্ধারণ করা

টেস্ট গ্রুপ ব্যবহার করে টেস্ট ম্যাপিং গ্রুপ পরীক্ষা করুন। টেস্ট গ্রুপের নাম যেকোনও স্ট্রিং হতে পারে। যেমন, presubmit হল পরিবর্তনের ভ্যালিডেশন করার সময় রান করার জন্য টেস্টের গ্রুপের নাম। এবং পোস্টসাবমিট হল সেইসব টেস্ট যা পরিবর্তন মার্জ করার পরে বিল্ড যাচাই করতে ব্যবহার করা হয়।

প্যাকেজ বিল্ড স্ক্রিপ্ট সংক্রান্ত নিয়ম

কোনও নির্দিষ্ট বিল্ডের জন্য টেস্ট মডিউল চালানোর জন্য ট্রেড ফেডারেশন টেস্ট হার্নেস এর test_suites Soong-এর জন্য সেট করা থাকতে হবে অথবা LOCAL_COMPATIBILITY_SUITE সেট করা থাকতে হবে এই দুটি স্যুটের মধ্যে একটির জন্য:

  • general-tests হল এমন টেস্টের জন্য যা ডিভাইস-নির্দিষ্ট ক্ষমতার উপর নির্ভর করে না (যেমন বিক্রেতা-নির্দিষ্ট হার্ডওয়্যার যা বেশিরভাগ ডিভাইসে থাকে না)। বেশিরভাগ টেস্ট general-tests স্যুটে থাকা উচিত, এমনকি সেগুলি একটি ABI বা বিটনেস বা HWASan-এর মতো হার্ডওয়্যার ফিচারের জন্য নির্দিষ্ট হলেও (প্রতিটি ABI-এর জন্য একটি আলাদা test_suites টার্গেট আছে) এবং এমনকি সেগুলি কোনও ডিভাইসে রান করতে হলেও।
  • device-tests হল সেইসব পরীক্ষার জন্য যা ডিভাইস-নির্দিষ্ট ক্ষমতার উপর নির্ভর করে। সাধারণত, এইসব পরীক্ষা vendor/-এর অধীনে পাওয়া যায়। ডিভাইস-নির্দিষ্ট বলতে শুধুমাত্র একটি ডিভাইসের অনন্য সক্ষমতা বোঝায়, তাই এটি JUnit টেস্টের পাশাপাশি GTest টেস্টের ক্ষেত্রেও প্রযোজ্য (যেগুলি সাধারণত general-tests হিসেবে চিহ্নিত করা উচিত, এমনকি সেগুলি ABI নির্দিষ্ট হলেও)।

উদাহরণ:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

টেস্ট স্যুটে চালানোর জন্য টেস্ট কনফিগার করা

টেস্ট স্যুটের মধ্যে টেস্ট রান করার জন্য, টেস্ট:

  • কোনও বিল্ড প্রদানকারী থাকলে চলবে না।
  • শেষ হয়ে গেলে অবশ্যই পরিষ্কার করতে হবে, যেমন, পরীক্ষার সময় তৈরি হওয়া যেকোনও অস্থায়ী ফাইল মুছে দিতে হবে।
  • সিস্টেম সেটিংস অবশ্যই ডিফল্ট বা আসল ভ্যালুতে পরিবর্তন করতে হবে।
  • ডিভাইসটি কোনও নির্দিষ্ট অবস্থায় আছে বলে ধরে নেওয়া উচিত নয়, যেমন, রুট করার জন্য রেডি। বেশিরভাগ পরীক্ষা চালানোর জন্য রুট প্রিভিলেজ প্রয়োজন হয় না। কোনও টেস্টে রুট অ্যাক্সেস প্রয়োজন হলে, সেটির AndroidTest.xml-এ RootTargetPreparer দিয়ে তা উল্লেখ করতে হবে, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

টেস্ট ম্যাপিং ফাইল তৈরি করুন

যে ডিরেক্টরির জন্য টেস্ট কভারেজ প্রয়োজন, সেখানে উদাহরণ-এর মতো একটি TEST_MAPPING JSON ফাইল যোগ করুন। এইসব নিয়ম নিশ্চিত করে যে সেই ডিরেক্টরি বা তার কোনও সাবডিরেক্টরি কোনও ফাইল স্পর্শ করলে, পরীক্ষাগুলি প্রিসাবমিট চেকের মধ্যে চলে।

একটি উদাহরণ অনুসরণ করুন

এখানে একটি স্যাম্পেল TEST_MAPPING ফাইল দেওয়া হল (এটি JSON ফর্ম্যাটে আছে, তবে এতে কমেন্ট সমর্থিত):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

অ্যাট্রিবিউট সেট করা

উদাহরণে, presubmit ও postsubmit হল প্রতিটি টেস্ট গ্রুপের নাম। টেস্ট গ্রুপ সম্পর্কে আরও তথ্য পেতে, টেস্ট গ্রুপ নির্ধারণ করুন লিঙ্কে দেখুন।

আপনি name অ্যাট্রিবিউটের ভ্যালুতে টেস্ট মডিউল বা ট্রেড ফেডারেশন ইন্টিগ্রেশন টেস্টের নাম (টেস্ট XML ফাইলের রিসোর্স পাথ, যেমন, uiautomator/uiautomator-demo) সেট করতে পারবেন। মনে রাখবেন, name ফিল্ডে name ক্লাস বা টেস্ট পদ্ধতি name ব্যবহার করা যায় না। কোন কোন টেস্ট রান করানো হবে তা নির্দিষ্ট করতে, include-filter-এর মতো বিকল্প ব্যবহার করুন। include-filter ব্যবহারের নমুনা দেখুন।

host সেটিং থেকে বোঝা যায় যে পরীক্ষাটি হোস্টের উপর চলছে এমন ডিভাইসবিহীন পরীক্ষা নাকি অন্য কিছু। ডিফল্ট ভ্যালু হল false, অর্থাৎ টেস্টটি চালানোর জন্য একটি ডিভাইস প্রয়োজন। GTest বাইনারির জন্য HostGTest এবং JUnit টেস্টের জন্য HostTest হল কাজ করে এমন টেস্টের ধরন।

file_patterns অ্যাট্রিবিউট আপনাকে যেকোনও সোর্স কোড ফাইলের আপেক্ষিক পাথ ম্যাচ করানোর জন্য রেগুলার এক্সপ্রেশন স্ট্রিংয়ের একটি তালিকা সেট করতে দেয় (TEST_MAPPING ফাইল থাকা ডিরেক্টরির আপেক্ষিক)। উদাহরণে, test CtsWindowManagerDeviceTestCases শুধুমাত্র তখনই প্রি-সাবমিটে রান করে যখন কোনও Java ফাইল Window বা Activity দিয়ে শুরু হয়, যা TEST_MAPPING ফাইলের মতো একই ডিরেক্টরিতে বা এর কোনও সাবডিরেক্টরিতে থাকে। ব্যাকস্ল্যাশ (\) এস্কেপ করতে হবে, কারণ এটি JSON ফাইলে আছে।

TEST_MAPPING ফাইল ইমপোর্ট করুন

imports অ্যাট্রিবিউট আপনাকে কন্টেন্ট কপি না করেই অন্য TEST_MAPPING ফাইলে টেস্ট অন্তর্ভুক্ত করতে দেয়। এছাড়াও, ইমপোর্ট করা পাথের পেরেন্ট ডিরেক্টরিতে থাকা TEST_MAPPING ফাইল অন্তর্ভুক্ত করা হয়। TEST_MAPPING নেস্টেড ইমপোর্ট করার অনুমতি দেয় অর্থাৎ ইমপোর্ট করা ফাইলগুলি অন্য TEST_MAPPING ফাইল ইমপোর্ট করতে পারে এবং টেস্ট ম্যাপিং অন্তর্ভুক্ত টেস্টগুলিকে মার্জ করতে পারে।

TEST_MAPPING রুট-লেভেল ও গ্রুপ-লেভেল ইমপোর্ট, দু'টিই কাজ করে:

  • রুট-লেভেল ইমপোর্ট: TEST_MAPPING ফাইলের (যেকোনও টেস্ট গ্রুপের বাইরে) সবচেয়ে উপরের লেভেলে নির্দিষ্ট করা হয়। রুট-লেভেল ইমপোর্ট করলে, সম্পূর্ণ টার্গেট TEST_MAPPING ফাইল (এবং এর পেরেন্ট ডিরেক্টরি) এমনভাবে ইমপোর্ট করা হয় যেন সেটি ইমপোর্ট করা হচ্ছে এমন পাথে লেখা হয়েছে। ইমপোর্ট করা ফাইলের সব টেস্ট গ্রুপের সংজ্ঞা (যেমন, presubmit, postsubmit) ইমপোর্ট করা ফাইলের সংশ্লিষ্ট টেস্ট গ্রুপের সাথে মার্জ করা হয়।
  • গ্রুপ-লেভেল ইমপোর্ট: নির্দিষ্ট টেস্ট গ্রুপের মধ্যে সরাসরি উল্লেখ করা হয় (যেমন presubmit বা postsubmit)। গ্রুপ-লেভেল ইমপোর্ট কঠোরভাবে সেই টেস্ট গ্রুপের মধ্যে সীমাবদ্ধ থাকে, অর্থাৎ টার্গেট TEST_MAPPING ফাইলের মধ্যে সেই নির্দিষ্ট গ্রুপের অধীনে থাকা টেস্টগুলিই শুধু ইমপোর্ট করা হবে। টার্গেট ফাইলে থাকা অন্যান্য টেস্ট গ্রুপ উপেক্ষা করা হয়।

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

রুট-লেভেল ইমপোর্টের উদাহরণ:

{
  "imports": [
    {
      "path": "frameworks/base/services/core"
    }
  ],
  "presubmit": [
    {
      "name": "MyTestModule"
    }
  ]
}

গ্রুপ-লেভেল ইমপোর্টের উদাহরণ:

{
  "presubmit": [
    {
      "name": "MyTestModule"
    },
    {
      "imports": [
        {
          "path": "frameworks/base/services/core"
        }
      ]
    }
  ],
  "postsubmit": [
    {
      "imports": [
        {
          "path": "frameworks/base/services/accessibility"
        }
      ]
    }
  ]
}

options অ্যাট্রিবিউটে অতিরিক্ত Tradefed কমান্ড লাইন বিকল্প থাকে।

কোনও নির্দিষ্ট টেস্টের জন্য উপলভ্য বিকল্পের সম্পূর্ণ তালিকা পেতে, রান করুন:

tradefed.sh run commandAndExit [test_module] --help

বিকল্প কীভাবে কাজ করে সেই সম্পর্কে আরও বিবরণ পেতে Tradefed-এ বিকল্প হ্যান্ডেল করা লিঙ্কে দেখুন।

TEST_MAPPING যাচাইকরণ

TEST_MAPPING ফাইল পরিবর্তন করার জন্য জমা দেওয়ার সময়, সঠিকতা নিশ্চিত করতে প্রিসাবমিট চেক চালানো হয়:

  • ফাইল প্যাটার্ন যাচাইকরণ: নিশ্চিত করে যে file_patterns-এর মধ্যে থাকা সব রেগুলার এক্সপ্রেশন যেন রিপোজিটরিতে অন্তত একটি ফাইলের সাথে মেলে। কোনও ফাইলের সাথে না মেলা পুরনো প্যাটার্নের কারণে চেক করা যায় না।
  • বিল্ড-টাইম যাচাইকরণ: বিল্ড-টাইম যাচাইকরণ সংক্রান্ত সতর্কতা প্রোমোট করে যা বিল্ড, মূল ব্রাঞ্চের জন্য প্রি-সাবমিটে সমস্যা ব্লক করার জন্য সংগ্রহ করে। সাধারণ সতর্কতার মধ্যে এগুলি পড়ে:
    • অস্তিত্বহীন মডিউল: এমন একটি টেস্ট মডিউলের নাম উল্লেখ করা যা কোডবেসে নেই, যেমন নামের বানান ভুল হলে।
    • ভুল ইমপোর্ট: imports-এ রেফারেন্স পাথ যা নেই বা TEST_MAPPING ফাইল নেই।
    • স্কিমা সংক্রান্ত সমস্যা: JSON কনফিগারেশনে কাজ করে না এমন কী বা ভুল স্ট্রাকচার ব্যবহার করা।

Atest-এর মাধ্যমে টেস্ট রান করা

স্থানীয়ভাবে প্রিসাবমিট টেস্টের নিয়ম প্রয়োগ করতে:

  1. TEST_MAPPING ফাইল থাকা ডিরেক্টরিতে যান।
  2. কমান্ড রান করুন:

    atest
    

বর্তমান ডিরেক্টরি ও এর পেরেন্ট ডিরেক্টরির TEST_MAPPING ফাইলে কনফিগার করা সবকটি প্রিসাবমিট টেস্ট চালানো হয়। Atest, presubmit-এর জন্য দুটি টেস্ট (A এবং B) লোকেট করে এবং রান করে।

TEST_MAPPING বর্তমান ওয়ার্কিং ডিরেক্টরি (CWD) ও প্যারেন্ট ডিরেক্টরির ফাইলগুলিতে প্রিসাবমিট টেস্ট চালানোর এটিই সবচেয়ে সহজ উপায়। Atest CWD ও এর সব প্যারেন্ট ডিরেক্টরিতে TEST_MAPPING ফাইল খুঁজে পায় ও ব্যবহার করে।

স্ট্রাকচার সোর্স কোড

এই উদাহরণে দেখানো হয়েছে যে কীভাবে আপনি সোর্স ট্রি জুড়ে TEST_MAPPING ফাইল কনফিগার করতে পারবেন:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

src/TEST_MAPPING-এর কন্টেন্ট:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

src/project_1/TEST_MAPPING-এর কন্টেন্ট:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

src/project_2/TEST_MAPPING-এর কন্টেন্ট:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

টার্গেট ডিরেক্টরি উল্লেখ করুন

আপনি TEST_MAPPING ফাইলে পরীক্ষা চালানোর জন্য একটি টার্গেট ডিরেক্টরি নির্দিষ্ট করতে পারেন। নিম্নলিখিত কমান্ড দুটি পরীক্ষা (A, B) চালায়:

atest --test-mapping src/project_1

postsubmit টেস্ট নিয়ম চালান

এছাড়াও, আপনি এই কমান্ড ব্যবহার করে TEST_MAPPING-এ src_path (ডিফল্ট হিসেবে CWD) এবং এর পেরেন্ট ডিরেক্টরিতে পোস্ট জমা দেওয়ার পরে পরীক্ষা সংক্রান্ত নিয়ম চালাতে পারবেন:

atest [--test-mapping] [src_path]:postsubmit

শুধুমাত্র সেইসব টেস্ট চালান যেগুলির জন্য কোনও ডিভাইসের প্রয়োজন নেই

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

atest [--test-mapping] --host

টেস্ট গ্রুপ শনাক্ত করা

আপনি Atest কমান্ডে টেস্ট গ্রুপ নির্দিষ্ট করতে পারবেন। নিচের কমান্ডটি src/project_1 ডিরেক্টরিতে থাকা ফাইল সম্পর্কিত সব postsubmit টেস্ট রান করে, যার মধ্যে শুধুমাত্র একটি টেস্ট (C) আছে।

অথবা, গ্রুপ নির্বিশেষে সব টেস্ট চালানোর জন্য আপনি :all ব্যবহার করতে পারেন। নিম্নলিখিত কমান্ড চারটি টেস্ট (A, B, C, X) চালায়:

atest --test-mapping src/project_1:all

সাবডাইরেক্টরি যোগ করুন

ডিফল্ট হিসেবে, TEST_MAPPING-এ Atest চালানোর সময়, শুধুমাত্র CWD (বা প্রদত্ত ডিরেক্টরি) ও এর পেরেন্ট ডিরেক্টরিতে TEST_MAPPING ফাইলে কনফিগার করা প্রিসাবমিট টেস্ট চালানো হয়। আপনি যদি সাবডিরেক্টরির সব TEST_MAPPING ফাইলে পরীক্ষা চালাতে চান, তাহলে --include-subdir বিকল্পটি ব্যবহার করে Atest-কে সেইসব পরীক্ষা অন্তর্ভুক্ত করতে বাধ্য করুন।

atest --include-subdir

--include-subdir বিকল্পটি না থাকলে, Atest শুধুমাত্র টেস্ট A রান করে। --include-subdir বিকল্পের মাধ্যমে, Atest দুটি টেস্ট (A, B) রান করে।

লাইন-লেভেল কমেন্ট কাজ করে

আপনি TEST_MAPPING ফাইলে লাইন-লেভেল // ফর্ম্যাটে কমেন্ট যোগ করে সেটিংয়ের বিবরণ দিতে পারেন। ATest এবং Trade Federation কমেন্ট ছাড়া সঠিক JSON ফর্ম্যাটে TEST_MAPPING প্রসেস করুন। JSON ফাইল পরিষ্কার রাখতে, শুধুমাত্র লাইন-লেভেল // ফর্ম্যাট কমেন্ট কাজ করে।

উদাহরণ:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}