यह टेस्ट मैपिंग के बारे में एक संक्षिप्त जानकारी है. साथ ही, इसमें Android Open Source Project (AOSP) में टेस्ट कॉन्फ़िगर करने का तरीका बताया गया है.
टेस्ट मैपिंग के बारे में जानकारी
टेस्ट मैपिंग, Gerrit पर आधारित एक तरीका है. इसकी मदद से, डेवलपर Android सोर्स ट्री में, presubmit और postsubmit टेस्ट के नियम सीधे तौर पर बना सकते हैं. साथ ही, टेस्ट के लिए ब्रांच और डिवाइस चुनने का काम, टेस्ट इन्फ़्रास्ट्रक्चर पर छोड़ा जा सकता है.
टेस्ट मैपिंग की परिभाषाएं, TEST_MAPPING नाम की JSON फ़ाइलें होती हैं. इन्हें किसी भी सोर्स डायरेक्ट्री में रखा जा सकता है.
Atest, TEST_MAPPING फ़ाइलों का इस्तेमाल करके, उनसे जुड़ी
डायरेक्ट्री में presubmit टेस्ट चला सकता है. टेस्ट मैपिंग की मदद से, Android सोर्स ट्री में कम से कम बदलाव करके, presubmit चेक में टेस्ट का एक ही सेट जोड़ा जा सकता है.
ये उदाहरण देखें:
TEST_MAPPINGके लिए,services.coreमें presubmit टेस्ट जोड़नाइंपोर्ट का इस्तेमाल करके,
tools/dexterके लिए,TEST_MAPPINGमें presubmit टेस्ट जोड़ना
टेस्ट मैपिंग, टेस्ट के एक्ज़ीक्यूशन और नतीजों की रिपोर्टिंग के लिए, Trade Federation (TF) टेस्ट हार्नेस पर निर्भर करती है.
टेस्ट ग्रुप तय करना
टेस्ट मैपिंग, टेस्ट को टेस्ट ग्रुप में ग्रुप करती है. टेस्ट ग्रुप का नाम कोई भी स्ट्रिंग हो सकता है. उदाहरण के लिए, बदलावों की पुष्टि करते समय, टेस्ट के ग्रुप के लिए presubmit नाम इस्तेमाल किया जा सकता है. वहीं, postsubmit नाम उन टेस्ट के लिए इस्तेमाल किया जा सकता है जो बदलावों को मर्ज करने के बाद, बिल्ड की पुष्टि करने के लिए इस्तेमाल किए जाते हैं.
पैकेज बिल्ड स्क्रिप्ट के नियम
Trade Federation टेस्ट हार्नेस को किसी दिए गए बिल्ड के लिए टेस्ट मॉड्यूल चलाने के लिए, इन मॉड्यूल में Soong के लिए Trade Federation test harness
a
test_suites सेट या Make के लिए Soonga 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 फ़ाइल
जोड़ें. इन नियमों से यह पक्का होता है कि उस डायरेक्ट्री या उसकी किसी भी सबडायरेक्ट्री में मौजूद किसी भी फ़ाइल में बदलाव करने पर, presubmit चेक में टेस्ट चलाए जाएं.
एक उदाहरण देखें
यहां 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` के इस्तेमाल का सैंपल देखें.include-filter
किसी टेस्ट की host सेटिंग से पता चलता है कि टेस्ट, होस्ट पर बिना डिवाइस के चल रहा है या नहीं. डिफ़ॉल्ट वैल्यू false होती है. इसका मतलब है कि टेस्ट चलाने के लिए, डिवाइस की ज़रूरत होती है. टेस्ट के इन टाइप का इस्तेमाल किया जा सकता है:
HostGTest
GTest बाइनरी के लिए और HostTest JUnit
टेस्ट के लिए.
file_patterns एट्रिब्यूट की मदद से, किसी भी सोर्स कोड फ़ाइल के रिलेटिव पाथ को मैच करने के लिए, रेगुलर एक्सप्रेशन स्ट्रिंग की सूची सेट की जा सकती है. यह पाथ, TEST_MAPPING फ़ाइल वाली डायरेक्ट्री के हिसाब से होता है. उदाहरण में,
टेस्ट CtsWindowManagerDeviceTestCases presubmit में सिर्फ़ तब चलता है, जब कोई 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फ़ाइल में, सिर्फ़ उस खास ग्रुप में तय किए गए टेस्ट इंपोर्ट किए जाएंगे. टारगेट फ़ाइल में मौजूद अन्य सभी टेस्ट ग्रुप को अनदेखा कर दिया जाता है.
ग्रुप-लेवल इंपोर्ट की मदद से, टेस्ट के एक्ज़ीक्यूशन पर बेहतर कंट्रोल मिलता है. उदाहरण के लिए, इंपोर्ट की गई डायरेक्ट्री से, postsubmit के बड़े टेस्ट को शामिल किए बिना, सिर्फ़ presubmit के लिए टेस्ट इंपोर्ट किए जा सकते हैं.
रूट-लेवल इंपोर्ट का उदाहरण:
{
"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 फ़ाइलों में बदलाव करने वाले बदलाव सबमिट करते समय, यह पक्का करने के लिए presubmit चेक चलाए जाते हैं कि वे सही हैं:
- फ़ाइल पैटर्न की पुष्टि करना: इससे यह पक्का होता है कि
file_patternsमें मौजूद सभी रेगुलर एक्सप्रेशन, रिपॉज़िटरी में कम से कम एक फ़ाइल से मैच करें. ऐसे पुराने पैटर्न जो किसी भी फ़ाइल से मैच नहीं करते हैं, उनकी वजह से चेक फ़ेल हो जाता है. - बिल्ड-टाइम की पुष्टि करना: यह मुख्य ब्रांच के लिए, presubmit में बिल्ड-टाइम की पुष्टि करने की चेतावनियों को, ब्लॉक करने वाली गड़बड़ियों में बदलता है. ये चेतावनियां, बिल्ड के दौरान इकट्ठा होती हैं. आम तौर पर मिलने वाली चेतावनियों में ये शामिल हैं:
- ऐसे मॉड्यूल जो मौजूद नहीं हैं: ऐसे टेस्ट मॉड्यूल के नाम का रेफ़रंस देना जो कोडबेस में मौजूद नहीं है. जैसे, नाम में टाइप की गड़बड़ी होना.
- अमान्य इंपोर्ट:
importsमें ऐसे रेफ़रंस पाथ जो मौजूद नहीं हैं या जिनमेंTEST_MAPPINGफ़ाइल नहीं है. - स्कीमा से जुड़ी समस्याएं: JSON कॉन्फ़िगरेशन में, ऐसे कुंजियों का इस्तेमाल करना जो काम नहीं करती हैं या गलत तरीके से बने स्ट्रक्चर का इस्तेमाल करना.
Atest की मदद से टेस्ट चलाना
presubmit टेस्ट के नियमों को स्थानीय तौर पर चलाने के लिए:
- उस डायरेक्ट्री पर जाएं जिसमें
TEST_MAPPINGफ़ाइल मौजूद है. यह कमांड चलाएं:
atest
मौजूदा डायरेक्ट्री और उसकी पैरंट डायरेक्ट्री की TEST_MAPPING फ़ाइलों में कॉन्फ़िगर किए गए सभी presubmit टेस्ट चलाए जाते हैं. Atest, presubmit के लिए दो टेस्ट (A और B) ढूंढकर चलाता है.
यह मौजूदा वर्किंग डायरेक्ट्री (सीडब्ल्यूडी) और पैरंट डायरेक्ट्री में मौजूद TEST_MAPPING फ़ाइलों में, presubmit टेस्ट चलाने का सबसे आसान तरीका है. Atest, सीडब्ल्यूडी और उसकी सभी पैरंट डायरेक्ट्री में मौजूद 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 टेस्ट के नियम चलाना
इस कमांड का इस्तेमाल, src_path (डिफ़ॉल्ट रूप से सीडब्ल्यूडी) और उसकी पैरंट डायरेक्ट्री में मौजूद TEST_MAPPING में तय किए गए postsubmit टेस्ट के नियम चलाने के लिए भी किया जा सकता है:
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 में टेस्ट चलाने पर, सीडब्ल्यूडी (या दी गई डायरेक्ट्री) और उसकी पैरंट डायरेक्ट्री में मौजूद TEST_MAPPING फ़ाइल में कॉन्फ़िगर किए गए सिर्फ़ presubmit टेस्ट चलाए जाते हैं. अगर आपको सबडायरेक्ट्री में मौजूद सभी 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"
}
]
}