फ़ीचर लॉन्च फ़्लैग में कोड की जांच करें

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

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

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

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

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

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

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

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

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

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

पूरी टेस्ट प्रोसेस के लिए फ़्लैग वैल्यू सेट करें. यह प्रोसेस, SetFlagsRule से शुरू होती है, जो टेस्ट में @Before-एनोटेट किए गए किसी भी सेटअप के तरीके से पहले होती है. 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 क्लास का नियम जोड़ने पर, test_flag_foo_turned_on चलने से पहले फ़ेल हो जाता है, जब DemoClass के कंस्ट्रक्टर से FLAG_FLAG_FOO को पढ़ा जाता है.

अगर आपकी पूरी क्लास के लिए फ़्लैग को चालू करना ज़रूरी है, तो @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 रन चलाता है. उदाहरण के लिए, एक फ़्लैग दो बार टेस्ट करता है और चार फ़्लैग पांच बार टेस्ट करते हैं.

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

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

  1. अपने टेस्ट सोर्स में, मैक्रो की परिभाषाएं और कॉन्फ़िगरेशन से जनरेट की गई लाइब्रेरी शामिल करें:

    #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) एक मैक्रो है, जिसका इस्तेमाल कॉन्फ़िगरेशन फ़ाइलों में तय किए गए फ़्लैग के लिए किया जाता है. यह मैक्रो, नेमस्पेस (TEST_NS) और फ़्लैग का नाम (readwrite_enabled_flag) स्वीकार करता है.
    • LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_disabled_flag) एक मैक्रो है, जिसका इस्तेमाल डिफ़ॉल्ट रूप से डिवाइस कॉन्फ़िगरेशन में सेट किए गए फ़्लैग के लिए किया जाता है.
  3. अपनी Android.bp बिल्ड फ़ाइल में, aconfig से जनरेट की गई लाइब्रेरी और काम की मैक्रो लाइब्रेरी को टेस्ट डिपेंडेंसी के तौर पर जोड़ें:

    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 से जनरेट की गई लाइब्रेरी जोड़ें:

    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 पर वापस लाता है, ताकि टेस्ट के अन्य तरीकों और क्लास पर इसका कोई असर न पड़े.