टेस्ट मैपिंग

इसमें टेस्ट मैपिंग के बारे में खास जानकारी दी गई है. साथ ही, Android Open Source Project (AOSP) में टेस्ट कॉन्फ़िगर करने का तरीका बताया गया है.

टेस्ट मैपिंग के बारे में जानकारी

टेस्ट मैपिंग, Gerrit पर आधारित एक तरीका है. इसकी मदद से डेवलपर, Android सोर्स ट्री में सीधे तौर पर, प्रीसबमिट और पोस्टसबमिट टेस्ट के नियम बना सकते हैं. साथ ही, टेस्ट इंफ़्रास्ट्रक्चर को यह तय करने दे सकते हैं कि किन ब्रांच और डिवाइसों की जांच करनी है. मैपिंग की परिभाषाओं की जांच करने वाली फ़ाइलें, JSON फ़ाइलें होती हैं. इनका नाम TEST_MAPPING होता है. इन्हें किसी भी सोर्स डायरेक्ट्री में रखा जा सकता है.

Atest, TEST_MAPPING फ़ाइलों का इस्तेमाल करके, इससे जुड़ी डायरेक्ट्री में सबमिट करने से पहले की जाने वाली जांच कर सकता है. टेस्ट मैपिंग की मदद से, Android सोर्स ट्री में कम से कम बदलाव करके, सबमिट करने से पहले की जाने वाली जांचों में टेस्ट का एक ही सेट जोड़ा जा सकता है.

ये उदाहरण देखें:

टेस्ट मैपिंग, टेस्ट को पूरा करने और नतीजों की रिपोर्टिंग के लिए, ट्रेड फ़ेडरेशन (टीएफ़) टेस्ट हार्नेस पर निर्भर करती है.

टेस्ट ग्रुप तय करना

टेस्ट मैपिंग ग्रुप, टेस्ट ग्रुप के साथ टेस्ट करता है. टेस्ट ग्रुप का नाम कोई भी स्ट्रिंग हो सकता है. उदाहरण के लिए, बदलावों की पुष्टि करते समय किए जाने वाले टेस्ट के ग्रुप का नाम presubmit हो सकता है. बदलावों को मर्ज करने के बाद, बिल्ड की पुष्टि करने के लिए postsubmit टेस्ट का इस्तेमाल किया जा सकता है.

पैकेज बनाने की स्क्रिप्ट के नियम

किसी बिल्ड के लिए टेस्ट मॉड्यूल चलाने के लिए, Trade Federation test harness को इन मॉड्यूल में से किसी एक के लिए test_suites सेट करना होगा: Soong या LOCAL_COMPATIBILITY_SUITE सेट करना होगा.

  • general-tests उन टेस्ट के लिए है जो डिवाइस की खास सुविधाओं पर निर्भर नहीं होते. जैसे, वेंडर के हिसाब से हार्डवेयर, जो ज़्यादातर डिवाइसों में नहीं होता. ज़्यादातर टेस्ट general-tests सुइट में होने चाहिए. भले ही, वे किसी एक एबीआई, बिटनेस या हार्डवेयर की सुविधाओं, जैसे कि HWASan के लिए खास तौर पर बनाए गए हों. हर एबीआई के लिए एक अलग test_suites टारगेट होता है. भले ही, उन्हें किसी डिवाइस पर चलाना हो.
  • device-tests उन टेस्ट के लिए है जो डिवाइस की खास सुविधाओं पर निर्भर करते हैं. आम तौर पर, ये टेस्ट vendor/ में दिखते हैं. डिवाइस के हिसाब से सिर्फ़ उन सुविधाओं के बारे में बताता है जो किसी डिवाइस के लिए यूनीक होती हैं. इसलिए, यह JUnit टेस्ट के साथ-साथ GTest टेस्ट पर भी लागू होता है. 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 एट्रिब्यूट की वैल्यू में, टेस्ट मॉड्यूल या Trade Federation इंटिग्रेशन टेस्ट के नाम को सेट किया जा सकता है. जैसे, टेस्ट एक्सएमएल फ़ाइल का रिसॉर्स पाथ uiautomator/uiautomator-demo. ध्यान दें कि name फ़ील्ड में, क्लास name या टेस्ट के तरीके name का इस्तेमाल नहीं किया जा सकता. टेस्ट की संख्या कम करने के लिए, include-filter जैसे विकल्पों का इस्तेमाल करें. include-filter इस्तेमाल का उदाहरण देखें.

टेस्ट की host सेटिंग से पता चलता है कि टेस्ट, डिवाइस के बिना होस्ट पर चल रहा है या नहीं. डिफ़ॉल्ट वैल्यू false है. इसका मतलब है कि टेस्ट को चलाने के लिए डिवाइस की ज़रूरत होती है. इन टेस्ट टाइप का इस्तेमाल किया जा सकता है: GTest बाइनरी के लिए HostGTest और JUnit टेस्ट के लिए HostTest.

file_patterns एट्रिब्यूट की मदद से, रेगुलर एक्सप्रेशन स्ट्रिंग की सूची सेट की जा सकती है. इससे किसी भी सोर्स कोड फ़ाइल के रिलेटिव पाथ (TEST_MAPPING फ़ाइल वाली डायरेक्ट्री के हिसाब से) को मैच किया जा सकता है. उदाहरण में, टेस्ट CtsWindowManagerDeviceTestCases सिर्फ़ तब चलता है, जब Java फ़ाइल Window या Activity से शुरू होती है. यह फ़ाइल, TEST_MAPPING फ़ाइल या उसकी किसी भी सबडायरेक्ट्री में मौजूद होती है. बैकस्लैश (\) को एस्केप करने की ज़रूरत होती है, क्योंकि वे JSON फ़ाइल में होते हैं.

imports एट्रिब्यूट की मदद से, कॉन्टेंट को कॉपी किए बिना अन्य TEST_MAPPING फ़ाइलों में टेस्ट शामिल किए जा सकते हैं. इंपोर्ट किए गए पाथ की पैरंट डायरेक्ट्री में मौजूद TEST_MAPPING फ़ाइलें भी शामिल की जाती हैं. टेस्ट मैपिंग में नेस्ट किए गए इंपोर्ट की अनुमति होती है. इसका मतलब है कि दो TEST_MAPPING फ़ाइलें एक-दूसरे को इंपोर्ट कर सकती हैं. साथ ही, टेस्ट मैपिंग में शामिल टेस्ट को मर्ज किया जा सकता है.

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 फ़ाइलों में कॉन्फ़िगर किए गए सभी presubmit टेस्ट चलाए जाते हैं. Atest, सबमिट करने से पहले (A और B) दो टेस्ट ढूंढता है और उन्हें चलाता है.

यह मौजूदा वर्किंग डायरेक्ट्री (सीडब्ल्यूडी) और पैरंट डायरेक्ट्री में मौजूद TEST_MAPPING फ़ाइलों में, प्रीसबमिट टेस्ट चलाने का सबसे आसान तरीका है. 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

पोस्टसबमिट टेस्ट के नियम लागू करना

इस निर्देश का इस्तेमाल, src_path में TEST_MAPPING में तय किए गए postsubmit टेस्ट के नियमों को चलाने के लिए भी किया जा सकता है. यह 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

सबडायरेक्ट्री शामिल करें

डिफ़ॉल्ट रूप से, Atest के साथ TEST_MAPPING में टेस्ट चलाने पर, सिर्फ़ उन प्रीसबमिट टेस्ट को चलाया जाता है जिन्हें 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 टिप्पणियों के बिना, TEST_MAPPING को मान्य JSON फ़ॉर्मैट में प्रीप्रोसेस करते हैं. JSON फ़ाइल को साफ़-सुथरा रखने के लिए, सिर्फ़ लाइन-लेवल // फ़ॉर्मैट वाली टिप्पणी का इस्तेमाल किया जा सकता है.

उदाहरण:

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