सुविधा लॉन्च करने के फ़्लैग में कोड की जांच करना

सुविधा लॉन्च करने के फ़्लैग की शुरुआत के साथ, टेस्टिंग से जुड़ी नई नीतियां लागू की गई हैं. आपको इनका पालन करना होगा:

  • आपके टेस्ट में, फ़्लैग के चालू और बंद होने की स्थितियों को शामिल किया जाना चाहिए.
  • टेस्टिंग के दौरान फ़्लैग वैल्यू सेट करने के लिए, आधिकारिक तरीकों का इस्तेमाल करना ज़रूरी है.
  • xTS टेस्ट में, टेस्ट के फ़्लैग की वैल्यू को नहीं बदला जाना चाहिए.

अगले सेक्शन में, इन नीतियों का पालन करने के लिए, आधिकारिक तौर पर उपलब्ध तरीके बताए गए हैं.

फ़्लैग किए गए कोड की जांच करना

टेस्ट का तरीका इस्तेमाल किया गया मैकेनिज़्म
जब फ़्लैग की वैल्यू अक्सर बदलती रहती हैं, तब लोकल टेस्टिंग Android Debug Bridge, जैसा कि रनटाइम के दौरान फ़्लैग की वैल्यू बदलना में बताया गया है
जब फ़्लैग की वैल्यू में बार-बार बदलाव नहीं होता, तब लोकल टेस्टिंग की जाती है सुविधा लॉन्च करने के लिए फ़्लैग वैल्यू सेट करना में बताए गए तरीके से, फ़्लैग वैल्यू वाली फ़ाइल को फ़्लैग करें
शुरू से आखिर तक की जाने वाली टेस्टिंग, जिसमें फ़्लैग की वैल्यू बदलती हैं FeatureFlagTargetPreparer जैसा कि एंड-टू-एंड टेस्ट बनाना लेख में बताया गया है
यूनिट टेस्टिंग, जिसमें फ़्लैग की वैल्यू बदलती हैं SetFlagsRule के साथ @EnableFlags और @DisableFlags का इस्तेमाल करें. इसके बारे में यूनिट टेस्ट (Java और Kotlin) बनाएं या यूनिट टेस्ट (C और C++) बनाएं लेख में बताया गया है
एंड-टू-एंड या यूनिट टेस्टिंग, जहां फ़्लैग की वैल्यू नहीं बदली जा सकती CheckFlagsRule जैसा कि ऐसी यूनिट या एंड-टू-एंड जांच बनाएं जिनमें फ़्लैग की वैल्यू न बदलें में बताया गया है

शुरू से आखिर तक टेस्ट बनाना

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

FeatureFlagTargetPreparer क्लास की सुविधा को टेस्ट मॉड्यूल और टेस्ट कॉन्फ़िगरेशन लेवल पर लागू किया जा सकता है.

टेस्ट मॉड्यूल कॉन्फ़िगरेशन में FeatureFlagTargetPreparer लागू करना

टेस्ट मॉड्यूल कॉन्फ़िगरेशन में FeatureFlagTargetPreparer लागू करने के लिए, AndroidTest.xml टेस्ट मॉड्यूल कॉन्फ़िगरेशन फ़ाइल में FeatureFlagTargetPreparer और फ़्लैग वैल्यू ओवरराइड शामिल करें:

  <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer">
        <option name="flag-value"
            value="permissions/com.android.permission.flags.device_aware_permission_grant=true"/>
        <option name="flag-value"
            value="virtual_devices/android.companion.virtual.flags.stream_permissions=true"/>
    </target_preparer>

यहां:

  • target.preparer class हमेशा com.android.tradefed.targetprep.FeatureFlagTargetPreparer पर सेट होता है.
  • option, फ़्लैग ओवरराइड है. इसमें name हमेशा flag-value पर सेट होता है और value, namespace/aconfigPackage.flagName=true|false पर सेट होता है.

फ़्लैग की स्थितियों के आधार पर, पैरामीटर वाले टेस्ट मॉड्यूल बनाना

फ़्लैग की स्थितियों के आधार पर, पैरामीटर वाले टेस्ट मॉड्यूल बनाने के लिए:

  1. AndroidTest.xml टेस्ट मॉड्यूल की कॉन्फ़िगरेशन फ़ाइल में, FeatureFlagTargetPreparer को शामिल करें:

    <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer" >
    
  2. Android.bp बिल्ड फ़ाइल के test_module_config सेक्शन में, फ़्लैग वैल्यू के विकल्प तय करें:

    android_test {
        name: "MyTest"
        ...
    }
    
    test_module_config {
        name: "MyTestWithMyFlagEnabled",
        base: "MyTest",
        ...
        options: [
            {name: "flag-value", value: "telephony/com.android.internal.telephony.flags.oem_enabled_satellite_flag=true"},
        ],
    }
    
    test_module_config {
        name: "MyTestWithMyFlagDisabled",
        base: "MyTest",
        ...
        options: [
            {name: "flag-value", value: "telephony/com.android.internal.telephony.flags.carrier_enabled_satellite_flag=true"},
        ],
    }
    

    options फ़ील्ड में फ़्लैग ओवरराइड होते हैं. इसमें name हमेशा flag-value पर सेट होता है और value, namespace/aconfigPackage.flagName=true|false पर सेट होता है.

यूनिट टेस्ट बनाना (Java और Kotlin)

इस सेक्शन में, Java और Kotlin टेस्ट में क्लास और तरीके के लेवल (हर टेस्ट के हिसाब से) पर, aconfig फ़्लैग की वैल्यू को बदलने के तरीके के बारे में बताया गया है.

ज़्यादा फ़्लैग वाले बड़े कोडबेस में, अपने-आप यूनिट टेस्ट लिखने के लिए, यह तरीका अपनाएं:

  1. सभी कोड ब्रांच की जांच करने के लिए, SetFlagsRule क्लास का इस्तेमाल करें. साथ ही, @EnableFlags और @DisableFlags एनोटेशन का इस्तेमाल करें.
  2. टेस्टिंग के दौरान होने वाली सामान्य गड़बड़ियों से बचने के लिए, SetFlagsRule.ClassRule तरीके का इस्तेमाल करें.
  3. फ़्लैग कॉन्फ़िगरेशन के अलग-अलग सेट पर अपनी क्लास की जांच करने के लिए, FlagsParameterization का इस्तेमाल करें.

कोड की सभी ब्रांच की जांच करना

फ़्लैग ऐक्सेस करने के लिए स्टैटिक क्लास का इस्तेमाल करने वाले प्रोजेक्ट के लिए, फ़्लैग की वैल्यू बदलने के लिए SetFlagsRule हेल्पर क्लास उपलब्ध कराई जाती है. यहां दिए गए कोड स्निपेट में, SetFlagsRule को शामिल करने और एक साथ कई फ़्लैग चालू करने का तरीका बताया गया है:

  import android.platform.test.annotations.EnableFlags;
  import android.platform.test.flag.junit.SetFlagsRule;
  import com.example.android.aconfig.demo.flags.Flags;
  ...
    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Test
    @EnableFlags({Flags.FLAG_FLAG_FOO, Flags.FLAG_FLAG_BAR})
    public void test_flag_foo_and_flag_bar_turned_on() {
    ...
    }

यहां:

  • @Rule एक एनोटेशन है. इसका इस्तेमाल SetFlagsRule क्लास की flag-JUnit डिपेंडेंसी को जोड़ने के लिए किया जाता है.
  • SetFlagsRule एक हेल्पर क्लास है. इसका इस्तेमाल फ़्लैग की वैल्यू बदलने के लिए किया जाता है. SetFlagsRule डिफ़ॉल्ट वैल्यू कैसे तय करता है, इस बारे में जानकारी पाने के लिए, डिवाइस की डिफ़ॉल्ट वैल्यू देखें.
  • @EnableFlags एक एनोटेशन है, जो फ़्लैग के नामों की कोई भी संख्या स्वीकार करता है. फ़्लैग बंद करते समय, @DisableFlags का इस्तेमाल करें. इन एनोटेशन को किसी तरीके या क्लास पर लागू किया जा सकता है.

टेस्ट की पूरी प्रोसेस के लिए फ़्लैग वैल्यू सेट करें. इसकी शुरुआत SetFlagsRule से होती है. यह टेस्ट में @Before-एनोटेट किए गए सेटअप के किसी भी तरीके से पहले होता है. SetFlagsRule खत्म होने पर, फ़्लैग की वैल्यू पहले जैसी हो जाती हैं. SetFlagsRule, सेटअप के उन सभी तरीकों के बाद खत्म होता है जिन्हें एनोटेट किया गया है.@After

पक्का करें कि फ़्लैग सही तरीके से सेट किए गए हों

जैसा कि पहले बताया गया है, SetFlagsRule का इस्तेमाल JUnit @Rule एनोटेशन के साथ किया जाता है. इसका मतलब है कि SetFlagsRule यह पक्का नहीं कर सकता कि टेस्ट क्लास के कंस्ट्रक्टर या @BeforeClass या @AfterClass-एनोटेट किए गए किसी भी तरीके के दौरान, आपके फ़्लैग सही तरीके से सेट किए गए हैं.

यह पक्का करने के लिए कि टेस्ट फ़िक्चर, क्लास की सही वैल्यू के साथ बनाए गए हैं, SetFlagsRule.ClassRule तरीके का इस्तेमाल करें. इससे आपके फ़िक्चर तब तक नहीं बनाए जाएंगे, जब तक कि @Before एनोटेशन वाला सेटअप तरीका इस्तेमाल नहीं किया जाता:

  import android.platform.test.annotations.EnableFlags;
  import android.platform.test.flag.junit.SetFlagsRule;
  import com.example.android.aconfig.demo.flags.Flags;

  class ExampleTest {
    @ClassRule public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
    @Rule public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();

    private DemoClass underTest = new DemoClass();

    @Test
    @EnableFlags(Flags.FLAG_FLAG_FOO)
    public void test_flag_foo_turned_on() {
      ...
    }
  }

SetFlagsRule.ClassRule क्लास का नियम जोड़ने पर, DemoClass के कंस्ट्रक्टर से FLAG_FLAG_FOO को पढ़ने पर, test_flag_foo_turned_on, कोड के चलने से पहले ही फ़ेल हो जाता है.

अगर आपकी पूरी क्लास के लिए फ़्लैग चालू करना है, तो @EnableFlags एनोटेशन को क्लास लेवल पर ले जाएं. यह क्लास के एलान से पहले होना चाहिए. एनोटेशन को क्लास लेवल पर ले जाने से, SetFlagsRule.ClassRule यह पक्का कर पाता है कि टेस्ट क्लास के कंस्ट्रक्टर के दौरान या @BeforeClass या @AfterClass-एनोटेट किए गए किसी भी तरीके के दौरान, फ़्लैग सही तरीके से सेट किया गया है.

अलग-अलग फ़्लैग कॉन्फ़िगरेशन पर टेस्ट चलाएं

हर टेस्ट के हिसाब से फ़्लैग वैल्यू सेट की जा सकती हैं. इसलिए, पैरामीटर का इस्तेमाल करके, फ़्लैग के कई कॉन्फ़िगरेशन पर टेस्ट चलाए जा सकते हैं:

...
import com.example.android.aconfig.demo.flags.Flags;
...

@RunWith(ParameterizedAndroidJunit4::class)
class FooBarTest {
    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
        return FlagsParameterization.allCombinationsOf(Flags.FLAG_FOO, Flags.FLAG_BAR);
    }

    @Rule
    public SetFlagsRule mSetFlagsRule;

    public FooBarTest(FlagsParameterization flags) {
        mSetFlagsRule = new SetFlagsRule(flags);
    }

    @Test public void fooLogic() {...}

    @DisableFlags(Flags.FLAG_BAR)
    @Test public void legacyBarLogic() {...}

    @EnableFlags(Flags.FLAG_BAR)
    @Test public void newBarLogic() {...}
}

ध्यान दें कि SetFlagsRule के साथ, लेकिन पैरामीटर के बिना, यह क्लास तीन टेस्ट (fooLogic, legacyBarLogic, और newBarLogic) चलाती है. fooLogic तरीका, डिवाइस पर FLAG_FOO और FLAG_BAR की सेट की गई वैल्यू के साथ चलता है.

पैरामीटर जोड़ने पर, FlagsParameterization.allCombinationsOf तरीका, FLAG_FOO और FLAG_BAR फ़्लैग के सभी संभावित कॉम्बिनेशन बनाता है:

  • FLAG_FOO true है और FLAG_BAR true है
  • FLAG_FOO true है और FLAG_BAR false है
  • FLAG_FOO false है और FLAG_BAR true है
  • FLAG_FOO गलत है और FLAG_BAR, false है

@DisableFlags और @EnableFlags एनोटेशन, फ़्लैग की वैल्यू में सीधे तौर पर बदलाव करने के बजाय, पैरामीटर की शर्तों के आधार पर फ़्लैग की वैल्यू में बदलाव करते हैं. उदाहरण के लिए, legacyBarLogic सिर्फ़ तब चलता है, जब FLAG_BAR बंद हो. ऐसा चार फ़्लैग कॉम्बिनेशन में से दो में होता है. अन्य दो कॉम्बिनेशन के लिए, legacyBarLogic को स्किप कर दिया जाता है.

अपने फ़्लैग के लिए पैरामीटर बनाने के दो तरीके हैं:

  • FlagsParameterization.allCombinationsOf(String...) हर टेस्ट को 2^n बार चलाता है. उदाहरण के लिए, एक फ़्लैग 2x टेस्ट चलाता है या चार फ़्लैग 16x टेस्ट चलाते हैं.

  • FlagsParameterization.progressionOf(String...) हर टेस्ट को n+1 बार चलाता है. उदाहरण के लिए, एक फ़्लैग 2x टेस्ट चलाता है और चार फ़्लैग 5x फ़्लैग चलाते हैं.

यूनिट टेस्ट बनाना (C और C++)

AOSP में, GoogleTest फ़्रेमवर्क में लिखे गए C और C++ टेस्ट के लिए, फ़्लैग वैल्यू वाले मैक्रो शामिल होते हैं.

  1. अपने टेस्ट सोर्स में, मैक्रो की परिभाषाएं और aconfig-generated लाइब्रेरी शामिल करें:

    #include <flag_macros.h>
    #include "android_cts_flags.h"
    
  2. अपने टेस्ट सोर्स में, टेस्ट केस के लिए TEST और TESTF मैक्रो इस्तेमाल करने के बजाय, TEST_WITH_FLAGS और TEST_F_WITH_FLAGS का इस्तेमाल करें:

    #define TEST_NS android::cts::flags::tests
    
    ...
    
    TEST_F_WITH_FLAGS(
      TestFWithFlagsTest,
      requies_disabled_flag_enabled_skip,
      REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_NS, readwrite_enabled_flag))
    ) {
      TestFail();
    }
    
    ...
    
    TEST_F_WITH_FLAGS(
      TestFWithFlagsTest,
      multi_flags_for_same_state_skip,
      REQUIRES_FLAGS_ENABLED(
          ACONFIG_FLAG(TEST_NS, readwrite_enabled_flag),
          LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_disabled_flag)
      )
    ) {
      TestFail();
    }
    
    ...
    
    TEST_WITH_FLAGS(
      TestWithFlagsTest,
      requies_disabled_flag_enabled_skip,
      REQUIRES_FLAGS_DISABLED(
          LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_enabled_flag))
    ) {
      FAIL();
    }
    
    ...
    
    TEST_WITH_FLAGS(
      TestWithFlagsTest,
      requies_enabled_flag_enabled_executed,
      REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_NS, readwrite_enabled_flag))
    ) {
      TestWithFlagsTestHelper::executed_tests.insert(
          "requies_enabled_flag_enabled_executed");
    }
    

    यहां:

    • TEST और TEST_F मैक्रो के बजाय, TEST_WITH_FLAGS और TEST_F_WITH_FLAGS मैक्रो का इस्तेमाल किया जाता है.
    • REQUIRES_FLAGS_ENABLED, फ़ीचर रिलीज़ फ़्लैग का एक सेट तय करता है. इसके लिए, यह ज़रूरी है कि फ़्लैग चालू होने की शर्त पूरी करता हो. इन फ़्लैग को ACONFIG_FLAG या LEGACY_FLAG मैक्रो में लिखा जा सकता है.
    • REQUIRES_FLAGS_DISABLED, फ़ीचर फ़्लैग का एक ऐसा सेट तय करता है जो बंद होने की शर्त को पूरा करता हो. इन फ़्लैग को ACONFIG_FLAG या LEGACY_FLAG मैक्रो में लिखा जा सकता है.
    • ACONFIG_FLAG (TEST_NS, readwrite_enabled_flag) एक मैक्रो है. इसका इस्तेमाल, aconfig फ़ाइलों में तय किए गए फ़्लैग के लिए किया जाता है. यह मैक्रो, नेमस्पेस (TEST_NS) और फ़्लैग का नाम (readwrite_enabled_flag) स्वीकार करता है.
    • LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_disabled_flag) एक मैक्रो है. इसका इस्तेमाल, डिवाइस के कॉन्फ़िगरेशन में डिफ़ॉल्ट रूप से सेट किए गए फ़्लैग के लिए किया जाता है.
  3. अपनी Android.bp बिल्ड फ़ाइल में, aconfig-generated लाइब्रेरी और काम की मैक्रो लाइब्रेरी को टेस्ट डिपेंडेंसी के तौर पर जोड़ें:

    cc_test {
      name: "FlagMacrosTests",
      srcs: ["src/FlagMacrosTests.cpp"],
      static_libs: [
          "libgtest",
          "libflagtest",
          "my_aconfig_lib",
      ],
      shared_libs: [
          "libbase",
          "server_configurable_flags",
      ],
      test_suites: ["general-tests"],
      ...
    }
    
  4. इस निर्देश की मदद से, स्थानीय तौर पर टेस्ट चलाएं:

    atest FlagMacrosTests
    

    अगर my_namespace.android.myflag.tests.my_flag फ़्लैग बंद है, तो टेस्ट का नतीजा यह होगा:

    [1/2] MyTest#test1: IGNORED (0ms)
    [2/2] MyTestF#test2: PASSED (0ms)
    

    अगर फ़्लैग my_namespace.android.myflag.tests.my_flag चालू है, तो टेस्ट का नतीजा यह होगा:

    [1/2] MyTest#test1: PASSED (0ms)
    [2/2] MyTestF#test2: IGNORED (0ms)
    

शुरू से आखिर तक या यूनिट टेस्ट बनाएं, जिनमें फ़्लैग की वैल्यू न बदलें

ऐसे टेस्ट केस के लिए जहां फ़्लैग को बदला नहीं जा सकता और टेस्ट को सिर्फ़ तब फ़िल्टर किया जा सकता है, जब वे फ़्लैग की मौजूदा स्थिति पर आधारित हों, तो RequiresFlagsEnabled और RequiresFlagsDisabled एनोटेशन के साथ CheckFlagsRule नियम का इस्तेमाल करें.

यहां दिए गए तरीके से, एंड-टू-एंड या यूनिट टेस्ट बनाया और चलाया जा सकता है. इसमें फ़्लैग वैल्यू को बदला नहीं जा सकता:

  1. टेस्ट फ़िल्टरिंग लागू करने के लिए, अपने टेस्ट कोड में CheckFlagsRule का इस्तेमाल करें. साथ ही, अपने टेस्ट के लिए फ़्लैग की ज़रूरी शर्तें बताने के लिए, Java एनोटेशन RequiresFlagsEnabled और RequiredFlagsDisabled का इस्तेमाल करें.

    डिवाइस-साइड टेस्ट, DeviceFlagsValueProvider क्लास का इस्तेमाल करता है:

    @RunWith(JUnit4.class)
    public final class FlagAnnotationTest {
      @Rule
      public final CheckFlagsRule mCheckFlagsRule =
              DeviceFlagsValueProvider.createCheckFlagsRule();
    
      @Test
      @RequiresFlagsEnabled(Flags.FLAG_FLAG_NAME_1)
      public void test1() {}
    
      @Test
      @RequiresFlagsDisabled(Flags.FLAG_FLAG_NAME_1)
      public void test2() {}
    }
    

    होस्ट-साइड टेस्ट में HostFlagsValueProvider क्लास का इस्तेमाल किया जाता है:

    @RunWith(DeviceJUnit4ClassRunner.class)
    public final class FlagAnnotationTest extends BaseHostJUnit4Test {
      @Rule
      public final CheckFlagsRule mCheckFlagsRule =
              HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
    
      @Test
      @RequiresFlagsEnabled(Flags.FLAG_FLAG_NAME_1)
      public void test1() {}
    
      @Test
      @RequiresFlagsDisabled(Flags.FLAG_FLAG_NAME_1)
      public void test2() {}
    }
    
  2. अपने टेस्ट के लिए, बिल्ड फ़ाइल के static_libs सेक्शन में jflag-unit और aconfig-generated लाइब्रेरी जोड़ें:

    android_test {
        name: "FlagAnnotationTests",
        srcs: ["*.java"],
        static_libs: [
            "androidx.test.rules",
            "my_aconfig_lib",
            "flag-junit",
            "platform-test-annotations",
        ],
        test_suites: ["general-tests"],
    }
    
  3. जांच को स्थानीय तौर पर चलाने के लिए, इस कमांड का इस्तेमाल करें:

    atest FlagAnnotationTests
    

    अगर Flags.FLAG_FLAG_NAME_1 फ़्लैग बंद है, तो टेस्ट का नतीजा यह होगा:

    [1/2] com.cts.flags.FlagAnnotationTest#test1: ASSUMPTION_FAILED (10ms)
    [2/2] com.cts.flags.FlagAnnotationTest#test2: PASSED (2ms)
    

    इसके अलावा, टेस्ट का नतीजा यह होगा:

    [1/2] com.cts.flags.FlagAnnotationTest#test1: PASSED (2ms)
    [2/2] com.cts.flags.FlagAnnotationTest#test2: ASSUMPTION_FAILED (10ms)
    

डिवाइस की डिफ़ॉल्ट वैल्यू

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

अगर एक ही टेस्ट को अलग-अलग रिलीज़ कॉन्फ़िगरेशन के तहत लागू किया जाता है, तो SetFlagsRule के साथ साफ़ तौर पर सेट नहीं किए गए फ़्लैग की वैल्यू अलग-अलग हो सकती है.

हर टेस्ट के बाद, SetFlagsRule, Flags में मौजूद FeatureFlags इंस्टेंस को उसके ओरिजनल FeatureFlagsImpl में बदल देता है, ताकि इसका असर अन्य टेस्ट मेथड और क्लास पर न पड़े.