ทดสอบการแมป

นี่เป็นการแนะนำสั้นๆ เกี่ยวกับการแมปทดสอบและคำอธิบายเกี่ยวกับวิธีเริ่มต้นการกำหนดค่าการทดสอบง่ายๆ ในโปรเจ็กต์โอเพนซอร์ส Android (AOSP)

เกี่ยวกับการทดสอบการแมป

การแมปทดสอบเป็นวิธีที่อิงตาม Gerrit ซึ่งช่วยให้นักพัฒนาแอปสร้างกฎการทดสอบก่อนและหลังการส่งได้โดยตรงในแผนผังแหล่งที่มาของ Android และปล่อยให้มีการทดสอบสาขาและอุปกรณ์กับโครงสร้างพื้นฐานทดสอบด้วยตนเอง คำจำกัดความของการแมปทดสอบคือไฟล์ JSON ชื่อ TEST_MAPPING ที่วางในไดเรกทอรีต้นทางใดก็ได้

Atest สามารถใช้ไฟล์ TEST_MAPPING เพื่อเรียกใช้การทดสอบการส่งล่วงหน้าในไดเรกทอรีที่เกี่ยวข้อง เมื่อใช้การแมปทดสอบ คุณจะเพิ่มการทดสอบชุดเดียวกันเพื่อส่งการตรวจสอบล่วงหน้าได้ด้วยการเปลี่ยนแปลงง่ายๆ ภายในแผนผังแหล่งที่มาของ Android

โปรดดูตัวอย่างต่อไปนี้

เพิ่มการทดสอบที่ส่งล่วงหน้าไปยัง TEST_MAPPING สำหรับ services.core

เพิ่มการทดสอบที่ส่งล่วงหน้าไปยัง TEST_MAPPING สำหรับเครื่องมือ/dexter ที่ใช้การนำเข้า

การแมปทดสอบใช้ Trade Federation (TF) Test Harness ว่าด้วยการดำเนินการทดสอบและการรายงานผลลัพธ์ (Trade Federation TF)

กำหนดกลุ่มทดสอบ

ทดสอบกลุ่มการแมปจะทดสอบผ่านกลุ่มทดสอบ ชื่อของกลุ่มทดสอบ จะเป็นสตริงใดก็ได้ ตัวอย่างเช่น ส่งล่วงหน้าอาจเป็นการให้กลุ่มการทดสอบทำงานเมื่อตรวจสอบการเปลี่ยนแปลง และการทดสอบ postsubmit สามารถใช้เพื่อตรวจสอบความถูกต้องของบิลด์หลังจากรวมการเปลี่ยนแปลงแล้ว

กฎสคริปต์บิลด์แพ็กเกจ

เพื่อให้ Trade Federation Test Harness เรียกใช้โมดูลทดสอบการแมปสำหรับบิลด์ที่ระบุ โมดูลเหล่านี้ต้องตั้งค่า test_suites สำหรับ Soong หรือ LOCAL_COMPATIBILITY_SUITE สำหรับทำให้เป็นชุดใดชุดหนึ่งจาก 2 ชุดต่อไปนี้

  • General-tests (การทดสอบทั่วไป) - การทดสอบที่ไม่ขึ้นอยู่กับฟังก์ชันการทำงานเฉพาะอุปกรณ์ (เช่น ฮาร์ดแวร์เฉพาะผู้ให้บริการซึ่งอุปกรณ์ส่วนใหญ่ไม่มี) การทดสอบส่วนใหญ่ควรอยู่ในชุดการทดสอบทั่วไป แม้ว่าจะมีความเฉพาะเจาะจงกับ ABI หรือฟีเจอร์ด้านฮาร์ดแวร์หนึ่งๆ เช่น HWASan (มีเป้าหมาย test_suites แยกต่างหากสำหรับ ABI แต่ละรายการ) และแม้ว่าจะต้องดำเนินการในอุปกรณ์ก็ตาม
  • device-tests - การทดสอบที่อาศัยฟังก์ชันเฉพาะอุปกรณ์ โดยทั่วไปแล้ว การทดสอบเหล่านี้จะพบได้ในส่วนvendor/ เนื่องจาก "เฉพาะอุปกรณ์" ไม่ได้หมายถึงฟังก์ชัน ABI หรือ SoC ที่อุปกรณ์อื่นๆ อาจมีหรือไม่มี แต่ใช้กับฟังก์ชันเฉพาะของอุปกรณ์ ระบบจึงใช้เฉพาะกับการทดสอบ JUnit ทั้งหมดเท่าๆ กับการทดสอบแบบเนทีฟของ GTest (ซึ่งปกติควรเป็น general-tests แม้ว่าจะเป็น ABI เฉพาะก็ตาม)

ตัวอย่าง

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

กำหนดค่าการทดสอบที่จะเรียกใช้ในชุดทดสอบ

หากต้องการทำการทดสอบภายในชุดทดสอบ การทดสอบจะมีลักษณะดังนี้

  • จะต้องไม่มีผู้ให้บริการบิลด์
  • ต้องล้างข้อมูลหลังจากที่เสร็จสิ้นแล้ว เช่น โดยการลบไฟล์ชั่วคราวที่สร้างขึ้นระหว่างการทดสอบ
  • เปลี่ยนการตั้งค่าระบบเป็นค่าเริ่มต้นหรือค่าเดิม
  • ไม่ควรถือว่าอุปกรณ์อยู่ในสถานะบางอย่าง เช่น พร้อมรูท การทดสอบส่วนใหญ่ไม่จำเป็นต้องใช้สิทธิ์ระดับรูท หากการทดสอบต้องต้องใช้รูท ควรระบุด้วย RootTargetPreparer ใน AndroidTest.xml ตามตัวอย่างต่อไปนี้
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>

สร้างไฟล์การแมปทดสอบ

สำหรับไดเรกทอรีที่ต้องการการครอบคลุมการทดสอบ ให้เพิ่มไฟล์ JSON TEST_MAPPING ไฟล์ที่คล้ายกับตัวอย่างด้านล่าง กฎเหล่านี้จะช่วยให้การทดสอบที่ส่งล่วงหน้าได้รับการตรวจสอบเมื่อมีการแตะไฟล์ในไดเรกทอรีนั้นหรือในไดเรกทอรีย่อย

ทำตามตัวอย่าง

ต่อไปนี้คือตัวอย่างไฟล์ 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": "CtsWindowManagerDeviceTestCases"
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

ตั้งค่าแอตทริบิวต์

ในตัวอย่างข้างต้น presubmit และ postsubmit คือชื่อของกลุ่มทดสอบแต่ละกลุ่ม ดูข้อมูลเพิ่มเติมเกี่ยวกับกลุ่มทดสอบได้ที่กำหนดกลุ่มทดสอบ

คุณตั้งค่าชื่อของโมดูลทดสอบหรือชื่อทดสอบการผสานรวมสหพันธ์การค้า (เส้นทางทรัพยากรไปยังไฟล์ XML ทดสอบ เช่น uiautomator/uiautomator-demo) ได้ในค่าของแอตทริบิวต์ name โปรดทราบว่าช่อง name ใช้คลาส name หรือเมธอดทดสอบ name ไม่ได้ หากต้องการจำกัดการทดสอบให้แคบลง คุณใช้ตัวเลือกต่างๆ เช่น include-filter ได้ที่นี่ ดู (รวมการใช้งานตัวอย่างตัวกรอง)

การตั้งค่าโฮสต์ของการทดสอบจะระบุว่าการทดสอบเป็นการทดสอบแบบไร้อุปกรณ์ที่ทำงานบนโฮสต์หรือไม่ ค่าเริ่มต้นคือ false ซึ่งหมายความว่าอุปกรณ์จะต้องเรียกใช้การทดสอบ ประเภทการทดสอบที่รองรับ ได้แก่ HostGTest สําหรับไบนารีของ GTest และ HostTest สําหรับการทดสอบ JUnit

แอตทริบิวต์ 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

ทำการทดสอบด้วย Atest

วิธีเรียกใช้กฎการทดสอบการส่งล่วงหน้าในเครื่อง

  1. ไปที่ไดเรกทอรีที่มีไฟล์ TEST_MAPPING
  2. เรียกใช้คำสั่งต่อไปนี้
atest

การทดสอบการส่งล่วงหน้าทั้งหมดที่กำหนดค่าในไฟล์ TEST_MAPPING ของไดเรกทอรีปัจจุบันและไดเรกทอรีระดับบนสุดจะทำงาน Atest จะค้นหาและทำการทดสอบ 2 รายการ สำหรับการส่งล่วงหน้า (A และ B)

วิธีนี้เป็นวิธีที่ง่ายที่สุดในการเรียกใช้การทดสอบการส่งล่วงหน้าในไฟล์ TEST_MAPPING ในไดเรกทอรีการทำงานปัจจุบัน (CWD) และไดเรกทอรีระดับบน Atest จะค้นหาและใช้ไฟล์ TEST_MAPPING ใน CWD และไดเรกทอรีระดับบนสุดทั้งหมด

ซอร์สโค้ดของโครงสร้าง

ตัวอย่างต่อไปนี้แสดงวิธีกำหนดค่าไฟล์ 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 ในไดเรกทอรีนั้นได้ คำสั่งต่อไปนี้จะเรียกใช้การทดสอบ 2 รายการ (A, B)

atest --test-mapping src/project_1

เรียกใช้กฎการทดสอบหลังส่ง

คุณยังใช้คำสั่งนี้เพื่อเรียกใช้กฎการทดสอบหลังส่งที่กำหนดไว้ใน TEST_MAPPING ใน src_path (ค่าเริ่มต้นคือ CWD) และไดเรกทอรีระดับบนสุดได้ด้วย

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

ทำการทดสอบที่ไม่ต้องใช้อุปกรณ์เท่านั้น

คุณใช้ตัวเลือก --host สำหรับ Atest เพื่อเรียกใช้การทดสอบที่กำหนดค่าไว้กับโฮสต์ที่ไม่ต้องการอุปกรณ์เท่านั้นได้ หากไม่ใช้ตัวเลือกนี้ Atest จะทำการทดสอบทั้ง 2 รายการ ซึ่งเป็นการทดสอบที่ต้องใช้อุปกรณ์และการทดสอบที่ทำงานบนโฮสต์ซึ่งไม่จำเป็นต้องใช้อุปกรณ์ การทดสอบจะดำเนินการในชุดแยก 2 ชุด

atest [--test-mapping] --host

ระบุกลุ่มทดสอบ

คุณจะระบุกลุ่มทดสอบในคำสั่ง Atest ได้ คำสั่งต่อไปนี้จะเรียกใช้การทดสอบ postsubmit ทั้งหมดที่เกี่ยวข้องกับไฟล์ในไดเรกทอรี src/project_1 ซึ่งมีการทดสอบเพียง 1 รายการ (C)

หรือคุณจะใช้ :all เพื่อทำการทดสอบทั้งหมดโดยไม่คำนึงถึงกลุ่มก็ได้ คำสั่งต่อไปนี้เรียกใช้การทดสอบ 4 รายการ (A, B, C, X)

atest --test-mapping src/project_1:all

รวมไดเรกทอรีย่อย

โดยค่าเริ่มต้น การเรียกใช้การทดสอบใน TEST_MAPPING ด้วย Atest จะเรียกใช้เฉพาะการทดสอบส่งล่วงหน้าที่กำหนดค่าไว้ในไฟล์ TEST_MAPPING ใน CWD (หรือไดเรกทอรีที่ระบุ) และไดเรกทอรีระดับบนเท่านั้น หากต้องการเรียกใช้การทดสอบในไฟล์ TEST_MAPPING ทั้งหมดในไดเรกทอรีย่อย ให้ใช้ตัวเลือก --include-subdir เพื่อบังคับให้ Atest รวมการทดสอบเหล่านั้นด้วย

atest --include-subdir

หากไม่มีตัวเลือก --include-subdir Atest จะเรียกใช้การทดสอบ A เท่านั้น เมื่อใช้ตัวเลือก --include-subdir Atest จะทำการทดสอบ 2 รายการ (A, B)

รองรับความคิดเห็นระดับบรรทัด

คุณสามารถเพิ่มความคิดเห็นรูปแบบ // ระดับบรรทัดเพื่อเพิ่มรายละเอียดของไฟล์ TEST_MAPPING ด้วยคำอธิบายการตั้งค่าที่ตามมา ATest และ Trade Federation จะประมวลผล TEST_MAPPING ล่วงหน้าในรูปแบบ JSON ที่ถูกต้องโดยไม่มีความคิดเห็น ระบบรองรับเฉพาะความคิดเห็นรูปแบบ // ระดับบรรทัดเท่านั้นเพื่อให้ไฟล์ JSON สะอาดตาและอ่านง่าย

ตัวอย่าง

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