Özellik lansman flag'lerinin kullanıma sunulmasıyla birlikte uymanız gereken yeni test politikaları var:
- Testleriniz, işaretin hem etkin hem de devre dışı davranışlarını kapsamalıdır.
- Test sırasında işaret değerlerini ayarlamak için resmi mekanizmaları kullanmanız gerekir.
- xTS testleri, testlerdeki işaret değerlerini geçersiz kılmamalıdır.
Sonraki bölümde, bu politikalara uymak için kullanmanız gereken resmi mekanizmalar açıklanmaktadır.
İşaretlenen kodunuzu test etme
Test senaryosu | Kullanılan mekanizma |
---|---|
İşaret değerleri sık değiştiğinde yerel test | Çalışma zamanında bir işaretin değerini değiştirme konusunda açıklandığı gibi Android hata ayıklama köprüsü |
İşaret değerleri sık sık değişmediğinde yerel test | Değerleri, Özellik kullanıma sunma işareti değerlerini belirleme bölümünde açıklandığı gibi işaretleme |
İşaret değerlerinin değiştiği uçtan uca test | FeatureFlagTargetPreparer Uçtan uca test oluşturma bölümünde açıklandığı gibi |
İşaret değerlerinin değiştiği birim testi | Birim testi oluşturma (Java ve Kotlin) veya Birim testi oluşturma (C ve C++) bölümünde açıklandığı gibi @EnableFlags ve @DisableFlags ile SetFlagsRule |
İşaret değerlerinin değişmediği uçtan uca veya birim testi | İşaret değerlerinin değişmediği uçtan uca veya birim testler oluşturma konusunda açıklandığı gibi CheckFlagsRule |
Uçtan uca testler oluşturma
AOSP, cihazda uçtan uca test yapılmasına olanak tanıyan FeatureFlagTargetPreparer
adında bir sınıf sağlar. Bu sınıf, giriş olarak işaret değeri geçersiz kılma işlemlerini kabul eder, test çalıştırmadan önce bu işaretleri cihaz yapılandırmasında ayarlar ve çalıştırma işleminden sonra işaretleri geri yükler.
FeatureFlagTargetPreparer
sınıfının işlevlerini test modülünde uygulayabilir ve test yapılandırması düzeylerinde yapabilirsiniz.
FeatureFlagTargetPreparer'ı test modülü yapılandırmasında uygulama
FeatureFlagTargetPreparer
'ü bir test modülü yapılandırmasına uygulamak için FeatureFlagTargetPreparer
ve işaret değeri geçersiz kılma işlemlerini AndroidTest.xml
test modülü yapılandırma dosyasına ekleyin:
<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>
Nerede:
target.preparer class
her zamancom.android.tradefed.targetprep.FeatureFlagTargetPreparer
olarak ayarlanır.option
, işaret geçersiz kılma işlemidir.name
her zamanflag-value
olarak,value
isenamespace/aconfigPackage.flagName=true|false
olarak ayarlanır.
İşaret durumlarına göre parametreli test modülleri oluşturma
İşaret durumlarına dayalı parametre haline getirilmiş test modülleri oluşturmak için:
AndroidTest.xml
test modülü yapılandırma dosyasınaFeatureFlagTargetPreparer
öğesini ekleyin:<target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer" >
Android.bp
derleme dosyasınıntest_module_config
bölümünde işaret değeri seçeneklerini belirtin: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
alanı,name
değerinin her zamanflag-value
vevalue
değerininnamespace/aconfigPackage.flagName=true|false
olarak ayarlandığı işaret geçersiz kılmalarını içerir.
Birim testleri oluşturma (Java ve Kotlin)
Bu bölümde, Java ve Kotlin testlerinde sınıf ve yöntem düzeyinde (test başına) yapılandırma işareti değerlerini geçersiz kılma yaklaşımı açıklanmaktadır.
Çok sayıda işarete sahip büyük bir kod tabanında otomatik birim testlerini yazmak için aşağıdaki adımları uygulayın:
- Tüm kod dallarını test etmek için
@EnableFlags
ve@DisableFlags
ek açıklamalarıylaSetFlagsRule
sınıfını kullanın. - Sık karşılaşılan test hatalarından kaçınmak için
SetFlagsRule.ClassRule
yöntemini kullanın. - Sınıflarınızı çeşitli işaret yapılandırmalarında test etmek için
FlagsParameterization
seçeneğini kullanın.
Tüm kod dallarını test etme
İşaretlere erişmek için statik sınıfı kullanan projelerde işaret değerlerini geçersiz kılmak için SetFlagsRule
yardımcı sınıfı sağlanır. Aşağıdaki kod snippet'i, SetFlagsRule
öğesinin nasıl dahil edileceğini ve birkaç işaretin aynı anda nasıl etkinleştirileceğini gösterir:
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() {
...
}
Nerede:
@Rule
,SetFlagsRule
sınıfının flag-JUnit bağımlılığını eklemek için kullanılan bir ek açıklamadır.SetFlagsRule
, işaret değerlerini geçersiz kılmak için sağlanan yardımcı sınıftır.SetFlagsRule
hizmetinin varsayılan değerleri nasıl belirlediği hakkında bilgi edinmek için Cihaz varsayılan değerleri bölümüne bakın.@EnableFlags
, isteğe bağlı sayıda işaret adını kabul eden bir ek açıklamadır. İşaretleri devre dışı bırakırken@DisableFlags
kullanın. Bu ek açıklamaları bir yönteme veya sınıfa uygulayabilirsiniz.
Testteki @Before
ek açıklamalı kurulum yöntemlerinden önce gelen SetFlagsRule
ile başlayarak test sürecinin tamamı için işaret değerleri belirleyin. İşaretleme değerleri, SetFlagsRule
tamamlandığında (@After
ek açıklamalı tüm kurulum yöntemlerinden sonra) önceki durumlarına döner.
İşaretçilerin doğru şekilde ayarlandığından emin olun
Daha önce de belirtildiği gibi SetFlagsRule
, JUnit @Rule
ek açıklamasıyla birlikte kullanılır. Bu, SetFlagsRule
ürününün, test sınıfının oluşturucusu veya @BeforeClass
ya da @AfterClass
ek açıklamalı herhangi bir yöntem sırasında işaretlerinizin doğru bir şekilde ayarlandığından emin olamayacağı anlamına gelir.
Test armatürlerinin doğru sınıf değeriyle oluşturulduğundan emin olmak için SetFlagsRule.ClassRule
yöntemini kullanın. Böylece, @Before
ek açıklamalı bir kurulum yöntemine kadar armatürlerinizin oluşturulmaması sağlanır:
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
sınıf kuralı eklendiğinde, FLAG_FLAG_FOO
, DemoClass
sınıfının kurucusu tarafından okunduğunda test_flag_foo_turned_on
çalıştırılmadan önce başarısız olur.
Sınıfınızın tamamı için bir işaretin etkinleştirilmesi gerekiyorsa @EnableFlags
ek açıklamasını sınıf düzeyine (sınıf beyanı öncesine) taşıyın. Ek açıklamanın sınıf düzeyine taşınması, SetFlagsRule.ClassRule
ürününün, test sınıfının oluşturucusu sırasında veya @BeforeClass
ya da @AfterClass
ek açıklamalı herhangi bir yöntem sırasında işaretin doğru bir şekilde ayarlandığından emin olmasını sağlar.
Birden çok işaret yapılandırmasında test çalıştırma
İşaret değerlerini test başına ayarlayabileceğiniz için birden fazla işaret yapılandırmasında test çalıştırmak için parametrelendirmeyi de kullanabilirsiniz:
...
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() {...}
}
Bu sınıfın, SetFlagsRule
ile ancak parametre olmadan üç test (fooLogic
, legacyBarLogic
ve newBarLogic
) çalıştırdığını unutmayın. fooLogic
yöntemi, cihazda FLAG_FOO
ve FLAG_BAR
değerlerinin ayarlandığı şekilde çalışır.
Parametreleştirme eklendiğinde FlagsParameterization.allCombinationsOf
yöntemi, FLAG_FOO
ve FLAG_BAR
işaretlerinin olası tüm kombinasyonlarını oluşturur:
FLAG_FOO
true
,FLAG_BAR
isetrue
FLAG_FOO
true
,FLAG_BAR
isefalse
FLAG_FOO
false
,FLAG_BAR
isetrue
FLAG_FOO
yanlış,FLAG_BAR
isefalse
@DisableFlags
ve @EnableFlags
ek açıklamaları, işaret değerlerini doğrudan değiştirmek yerine parametre koşullarına göre işaret değerlerini değiştirir. Örneğin, legacyBarLogic
yalnızca FLAG_BAR
devre dışı bırakıldığında çalışır. Bu durum, dört işaret kombinasyonundan ikisinde gerçekleşir. Diğer iki kombinasyon için legacyBarLogic
atlanır.
İşaretleriniz için parametrelendirmeleri oluşturmanın iki yöntemi vardır:
FlagsParameterization.allCombinationsOf(String...)
, her testi 2^n kez çalıştırır. Örneğin, bir işaret 2 kat daha fazla test, dört işaret ise 16 kat daha fazla test çalıştırır.FlagsParameterization.progressionOf(String...)
, her test için n+1 çalıştırma işlemi yürütür. Örneğin, bir işaret 2x test çalıştırırken dört işaret 5x işareti çalıştırır.
Birim testleri oluşturma (C ve C++)
AOSP, GoogleTest çerçevesine yazılan C ve C++ testleri için işaret değeri makroları içerir.
Test kaynağınıza makro tanımlarını ve yapılandırma tarafından oluşturulan kitaplıkları ekleyin:
#include <flag_macros.h> #include "android_cts_flags.h"
Test kaynağınızda, test durumlarınız için
TEST
veTESTF
makroları yerineTEST_WITH_FLAGS
veTEST_F_WITH_FLAGS
değerlerini kullanın:#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"); }
Nerede:
TEST
veTEST_F
makroları yerineTEST_WITH_FLAGS
veTEST_F_WITH_FLAGS
makroları kullanılıyor.REQUIRES_FLAGS_ENABLED
, etkin koşulunu karşılaması gereken bir dizi özellik yayınlama işaretini tanımlar. Bu işaretleriACONFIG_FLAG
veyaLEGACY_FLAG
makrolarına yazabilirsiniz.REQUIRES_FLAGS_DISABLED
, devre dışı bırakılmış koşulu karşılaması gereken bir dizi özellik işaretini tanımlar. Bu işaretleriACONFIG_FLAG
veyaLEGACY_FLAG
makrolarına yazabilirsiniz.ACONFIG_FLAG (TEST_NS, readwrite_enabled_flag)
, yapılandırma dosyalarında tanımlanan işaretler için kullanılan bir makrodur. Bu makro, ad alanını (TEST_NS
) ve işaret adını (readwrite_enabled_flag
) kabul eder.LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_disabled_flag)
, varsayılan olarak cihaz yapılandırmasında ayarlanan işaretler için kullanılan bir makrodur.
Android.bp
derleme dosyanıza, aconfig tarafından oluşturulan kitaplıkları ve ilgili makro kitaplıklarını test bağımlılığı olarak ekleyin: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"], ... }
Testleri şu komutla yerel olarak çalıştırın:
atest FlagMacrosTests
my_namespace.android.myflag.tests.my_flag
işareti devre dışı bırakılırsa test sonucu şu şekilde olur:[1/2] MyTest#test1: IGNORED (0ms) [2/2] MyTestF#test2: PASSED (0ms)
my_namespace.android.myflag.tests.my_flag
işareti etkinse test sonucu şudur:[1/2] MyTest#test1: PASSED (0ms) [2/2] MyTestF#test2: IGNORED (0ms)
İşaretçi değerlerinin değişmediği uçtan uca veya birim testleri oluşturma
İşaretleri geçersiz kılamayacağınız ve testleri yalnızca geçerli işaretleme durumuna dayalı olmaları koşuluyla filtreleyebileceğiniz test durumları için RequiresFlagsEnabled
ve RequiresFlagsDisabled
ek açıklamalarıyla CheckFlagsRule
kuralını kullanın.
Aşağıdaki adımlarda, işaret değerlerinin geçersiz kılınamayacağı uçtan uca veya birim testinin nasıl oluşturulacağı ve çalıştırılacağı gösterilmektedir:
Test filtrelemesi uygulamak için test kodunuzda
CheckFlagsRule
kullanın. Ayrıca, testinizin işaret gereksinimlerini belirtmek içinRequiresFlagsEnabled
veRequiredFlagsDisabled
Java ek açıklamalarını kullanın.Cihaz tarafı testinde
DeviceFlagsValueProvider
sınıfı kullanılır:@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() {} }
Ana makine tarafı testi
HostFlagsValueProvider
sınıfını kullanır:@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() {} }
Testiniz için derleme dosyasının
static_libs
bölümünejflag-unit
ve aconfig tarafından oluşturulan kitaplıkları ekleyin:android_test { name: "FlagAnnotationTests", srcs: ["*.java"], static_libs: [ "androidx.test.rules", "my_aconfig_lib", "flag-junit", "platform-test-annotations", ], test_suites: ["general-tests"], }
Testi yerel olarak çalıştırmak için aşağıdaki komutu kullanın:
atest FlagAnnotationTests
Flags.FLAG_FLAG_NAME_1
işareti devre dışı bırakılırsa test sonucu şu şekilde olur:[1/2] com.cts.flags.FlagAnnotationTest#test1: ASSUMPTION_FAILED (10ms) [2/2] com.cts.flags.FlagAnnotationTest#test2: PASSED (2ms)
Aksi takdirde test sonucu şöyle olur:
[1/2] com.cts.flags.FlagAnnotationTest#test1: PASSED (2ms) [2/2] com.cts.flags.FlagAnnotationTest#test2: ASSUMPTION_FAILED (10ms)
Cihaz varsayılan değerleri
Başlatılan SetFlagsRule
, cihazdaki işaret değerlerini kullanır. Cihazdaki işaret değeri geçersiz kılınmamışsa (ör. adb ile) varsayılan değer, derlemenin sürüm yapılandırmasıyla aynıdır. Cihazdaki değer geçersiz kılınmışsa SetFlagsRule
, varsayılan olarak geçersiz kılma değerini kullanır.
Aynı test farklı sürüm yapılandırmaları altında yürütülürse SetFlagsRule
ile açıkça ayarlanmayan işaretlerin değeri değişiklik gösterebilir.
SetFlagsRule
, her testten sonra Flags
içindeki FeatureFlags
örneğini orijinal FeatureFlagsImpl
durumuna geri yükler. Böylece, diğer test yöntemleri ve sınıfları üzerinde yan etki oluşmaz.