Özellik lansmanı işaretlerinin kullanıma sunulmasıyla birlikte, uymanız gereken yeni test politikaları vardır:
- 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 sık değiştiğinde yerel test | Komut dosyası çalıştırma zamanında bir işaretin değerini değiştirme bölümünde açıklandığı gibi Android hata ayıklama köprüsü |
İşaret değerleri sık sık değişmediğinde yerel test | Özellik lansmanı işaret değerlerini ayarlama bölümünde açıklandığı şekilde işaret değerleri dosyası |
İşaretçi 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çi değerlerinin değiştirilemediği uçtan uca veya birim testi | CheckFlagsRule Bayrak değerlerinin değişmediği uçtan uca veya birim testleri oluşturma başlıklı makalede açıklandığı gibi |
Uçtan uca testler oluşturma
AOSP, bir cihazda uçtan uca test yapılmasını sağlayan FeatureFlagTargetPreparer
adlı 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şlevini test modülü ve test yapılandırması düzeylerinde uygulayabilirsiniz.
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ılmalarını 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 durumuna göre parametreli test modülleri oluşturmak için:
FeatureFlagTargetPreparer
dosyasınıAndroidTest.xml
test modülü yapılandırma dosyasına 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
her zamanflag-value
olarak ayarlanmış vevalue
namespace/aconfigPackage.flagName=true|false
olarak ayarlanmışken işaret geçersiz kılma işlemlerini içerir.
Birim testi oluşturma (Java ve Kotlin)
Bu bölümde, Java ve Kotlin testlerinde sınıf ve yöntem düzeyinde (test başına) aconfig işareti değerlerinin geçersiz kılınmasına yönelik yaklaşım açıklanmaktadır.
Çok sayıda işaret içeren büyük bir kod tabanında otomatik birim testleri yazmak için aşağıdaki adımları uygulayın:
- Tüm kod dallarını test etmek için
SetFlagsRule
sınıfını@EnableFlags
ve@DisableFlags
ek açıklamalarıyla 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'inde, SetFlagsRule
'ün nasıl dahil edileceği ve birden fazla işaretin aynı anda nasıl etkinleştirileceği gösterilmektedir:
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 işaretli 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
'ün 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
, rastgele sayıda işaret adı kabul eden bir ek açıklamadır. İşaretleri devre dışı bırakırken@DisableFlags
simgesini kullanın. Bu ek açıklamaları bir yönteme veya sınıfa uygulayabilirsiniz.
Testteki @Before
notu eklenmiş kurulum yöntemlerinin öncesindeki SetFlagsRule
ile başlayarak test sürecinin tamamı için işaret değerlerini ayarlayın. İşaret değerleri, SetFlagsRule
tamamlandığında (@After
ile ek açıklama yapılan tüm kurulum yöntemlerinin ardından) ö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
'ün, test sınıfının kurucusu veya @BeforeClass
ya da @AfterClass
ek açıklamasıyla işaretlenmiş yöntemler sırasında işaretlerinizin doğru şekilde ayarlandığından emin olamayacağı anlamına gelir.
Test donanımlarının doğru sınıf değeriyle oluşturulduğundan emin olmak için SetFlagsRule.ClassRule
yöntemini kullanın. Böylece donanımlarınız, @Before
notu eklenmiş bir kurulum yöntemi uygulanana kadar oluşturulmaz:
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çıklamayı sınıf düzeyine taşımak, SetFlagsRule.ClassRule
'ün test sınıfının kurucusu sırasında veya @BeforeClass
ya da @AfterClass
ile ek açıklamaya sahip yöntemler sırasında işaretin doğru ş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.
Parametrelendirme eklendiğinde FlagsParameterization.allCombinationsOf
yöntemi, FLAG_FOO
ve FLAG_BAR
işaretlerinin tüm olası kombinasyonlarını oluşturur:
FLAG_FOO
true
,FLAG_BAR
isetrue
FLAG_FOO
,true
veFLAG_BAR
,false
FLAG_FOO
,false
veFLAG_BAR
,true
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 testi n+1 kez çalıştırır. Örneğin, bir işaret 2 kat daha fazla test, dört işaret ise 5 kat daha fazla test çalıştırır.
Birim testi oluşturma (C ve C++)
AOSP, GoogleTest çerçevesinde yazılmış C ve C++ testleri için işaret değeri makroları içerir.
Test kaynağınıza makro tanımlarını ve aconfig tarafından oluşturulan kitaplıkları ekleyin:
#include <flag_macros.h> #include "android_cts_flags.h"
Test kaynağınızda, test senaryolarınız için
TEST
veTESTF
makrolarını kullanmak yerineTEST_WITH_FLAGS
veTEST_F_WITH_FLAGS
makrolarını 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ır.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şulunu 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, bir ad alanı (TEST_NS
) ve işaret adı (readwrite_enabled_flag
) kabul eder.LEGACY_FLAG(aconfig_flags.cts, TEST_NS, readwrite_disabled_flag)
, cihaz yapılandırmasında varsayılan olarak 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ı 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 yerel olarak çalıştırmak için şu komutu kullanın:
atest FlagMacrosTests
my_namespace.android.myflag.tests.my_flag
işareti devre dışıysa test sonucu:[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 mevcut işaret durumuna göre filtreleyebileceğiniz test durumları için RequiresFlagsEnabled
ve RequiresFlagsDisabled
ek açıklamalarıyla birlikte CheckFlagsRule
kuralını kullanın.
Aşağıdaki adımlarda, işaret değerlerinin geçersiz kılınamayacağını uçtan uca veya birim testi oluşturma ve çalıştırma işlemi gösterilmektedir:
Test filtrelemesi uygulamak için test kodunuzda
CheckFlagsRule
kullanın. Ayrıca, testiniz için işaret gereksinimlerini belirtmek üzere Java ek açıklamalarınıRequiresFlagsEnabled
veRequiredFlagsDisabled
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() {} }
Barındırma 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ışıysa test sonucu şöyle olur:[1/2] com.cts.flags.FlagAnnotationTest#test1: ASSUMPTION_FAILED (10ms) [2/2] com.cts.flags.FlagAnnotationTest#test2: PASSED (2ms)
Aksi takdirde test sonucu:
[1/2] com.cts.flags.FlagAnnotationTest#test1: PASSED (2ms) [2/2] com.cts.flags.FlagAnnotationTest#test2: ASSUMPTION_FAILED (10ms)
Cihazın varsayılan değerleri
İlkleştirilen 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 çalıştırılırsa SetFlagsRule
ile açıkça ayarlanmayan işaretçilerin 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.