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

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

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

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

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

टेस्ट की स्थिति इस्तेमाल किया गया तरीका
फ़्लैग की वैल्यू बार-बार बदलने पर, लोकल टेस्टिंग Android डीबग ब्रिज, जैसा कि रनटाइम के दौरान किसी फ़्लैग की वैल्यू बदलना में बताया गया है
फ़्लैग की वैल्यू अक्सर न बदलने पर, लोकल टेस्टिंग फ़्लैग वैल्यू फ़ाइल, जैसा कि सुविधा लॉन्च करने के लिए फ़्लैग की वैल्यू सेट करना में बताया गया है
शुरू से आखिर तक की जाने वाली टेस्टिंग, जिसमें फ़्लैग की वैल्यू बदलती हैं 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 खत्म होने पर, फ़्लैग की वैल्यू पहले जैसी हो जाती हैं. @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 के कंस्ट्रक्टर से पढ़ने पर, test_flag_foo_turned_on को चलाने से पहले ही गड़बड़ी का मैसेज मिलता है.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 रन करता है. उदाहरण के लिए, एक फ़्लैग दो बार टेस्ट चलाता है या चार फ़्लैग 16 बार टेस्ट चलाते हैं.

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

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

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

में देखा जा सकता है
  1. अपने टेस्ट सोर्स में, मैक्रो डेफ़िनिशन और aconfig से जनरेट की गई लाइब्रेरी शामिल करें:

    #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 से जनरेट की गई लाइब्रेरी और काम की मैक्रो लाइब्रेरी को टेस्ट डिपेंडेंसी के तौर पर जोड़ें:

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