Özellik yayınlama işaretlerinin kullanıma sunulmasıyla birlikte uymanız gereken yeni test politikaları belirlendi:
- Testleriniz, flag'in hem etkin hem de devre dışı bırakılmış 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 | Çalışma zamanında bir işaretin değerini değiştirme bölümünde ele alınan 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çıklanan işaret değerleri dosyası |
İşaret değerlerinin değiştiği uçtan uca test | FeatureFlagTargetPreparer Uçtan uca testler oluşturma başlıklı makalede açıklandığı gibi |
İşaret değerlerinin değiştiği birim testi | Birim testleri oluşturma (Java ve Kotlin) veya Birim testleri oluşturma (C ve C++) bölümünde açıklandığı gibi SetFlagsRule ile @EnableFlags ve @DisableFlags |
İşaret değerlerinin değişemediği uçtan uca veya birim testi | CheckFlagsRule İşaret 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 yapmayı sağlayan FeatureFlagTargetPreparer
adlı bir sınıf sunar. Bu sınıf, giriş olarak işaret değeri geçersiz kılmalarını kabul eder, test yürütülmeden önce cihaz yapılandırmasında bu işaretleri ayarlar ve yürütme işleminden sonra işaretleri geri yükler.
FeatureFlagTargetPreparer
sınıfının işlevselliğini test modülü ve test yapılandırma düzeylerinde uygulayabilirsiniz.
FeatureFlagTargetPreparer'ı bir test modülü yapılandırmasında uygulama
Bir test modülü yapılandırmasında FeatureFlagTargetPreparer
uygulamak için AndroidTest.xml
test modülü yapılandırma dosyasına FeatureFlagTargetPreparer
ve işaret değeri geçersiz kılmalarını 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
,name
her zamanflag-value
vevalue
namespace/aconfigPackage.flagName=true|false
olarak ayarlanmış işaret geçersiz kılma işlemidir.
İşaret durumlarına göre parametrelendirilmiş test modülleri oluşturma
İşaret durumlarına göre parametrelendirilmiş 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 vevalue
namespace/aconfigPackage.flagName=true|false
olarak ayarlanmış 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) aconfig işareti değerlerini geçersiz kılma 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 birlikte 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
kullanın.
Tüm kod dallarını test etme
Statik sınıfı kullanarak işaretlere erişen 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
öğesinin nasıl ekleneceği ve birkaç 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 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
'nın varsayılan değerleri nasıl belirlediği hakkında bilgi için Cihaz varsayılan değerleri başlıklı makaleyi inceleyin.@EnableFlags
, rastgele sayıda işaret adı 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
ile açıklama eklenmiş kurulum yöntemlerinden önce gelen SetFlagsRule
ile başlayarak tüm test süreci için işaret değerlerini ayarlayın. SetFlagsRule
tamamlandığında (@After
ile açıklama eklenmiş kurulum yöntemlerinden sonra) işaret değerleri önceki durumlarına döner.
İşaretlerin doğru şekilde ayarlandığından emin olun
Daha önce belirtildiği gibi, SetFlagsRule
, JUnit @Rule
ek açıklamasıyla birlikte kullanılır. Bu nedenle, SetFlagsRule
, test sınıfının oluşturucusu veya @BeforeClass
ya da @AfterClass
ek açıklamalı yöntemler sırasında işaretlerinizin doğru şekilde ayarlandığını garanti edemez.
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, armatürleriniz @Before
ile açıklama eklenmiş bir kurulum yöntemi kullanılana 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 test_flag_foo_turned_on
FLAG_FLAG_FOO
, DemoClass
oluşturucusu tarafından okunurken çalıştırmadan önce başarısız olur.
Sınıfınızın tamamında bir işaretin etkinleştirilmesi gerekiyorsa @EnableFlags
ek açıklamasını sınıf düzeyine (sınıf bildiriminden önce) taşıyın. Açıklamanın sınıf düzeyine taşınması, SetFlagsRule.ClassRule
işaretin test sınıfının oluşturucusu sırasında veya herhangi bir @BeforeClass
ya da @AfterClass
ile açıklama eklenmiş yöntem sırasında doğru şekilde ayarlanmasını sağlar.
Birden çok işaret yapılandırmasında test çalıştırma
İşaret değerlerini test bazında ayarlayabildiğiniz için, parametrelendirmeyi kullanarak birden fazla işaret yapılandırmasında testler de çalıştırabilirsiniz:
...
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
ile ancak parametreleştirme olmadan bu sınıfın üç test (fooLogic
, legacyBarLogic
ve newBarLogic
) çalıştırdığını unutmayın. fooLogic
yöntemi, cihazda FLAG_FOO
ve FLAG_BAR
değerleri neye ayarlanmışsa onunla ç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
veFLAG_BAR
true
FLAG_FOO
,true
veFLAG_BAR
,false
FLAG_FOO
,false
veFLAG_BAR
,true
FLAG_FOO
yanlış veFLAG_BAR
,false
@DisableFlags
ve @EnableFlags
ek açıklamaları, işaret değerlerini doğrudan değiştirmek yerine parametre koşullarına göre 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 geçerlidir. Diğer iki kombinasyonda legacyBarLogic
atlanır.
İşaretleriniz için parametreler oluşturmanın iki yöntemi vardır:
FlagsParameterization.allCombinationsOf(String...)
her testin 2^n kez çalıştırılmasını sağlar. Örneğin, bir işaret 2x testleri veya dört işaret 16x testleri çalıştırır.FlagsParameterization.progressionOf(String...)
, her testin n+1 çalışmasını yürütür. Örneğin, bir işaret 2x testleri, dört işaret ise 5x işaretleri çalıştırır.
Birim testleri oluşturma (C ve C++)
AOSP, GoogleTest çerçevesinde yazılmış C ve C++ testleri için işaret değeri makroları içerir.
içinde bulabilirsiniz.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
, etkinleştirme koşulunu karşılaması gereken bir dizi özellik yayınlama işareti tanımlar. Bu işaretleriACONFIG_FLAG
veyaLEGACY_FLAG
makrolarına yazabilirsiniz.REQUIRES_FLAGS_DISABLED
, devre dışı 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 bir 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:[1/2] MyTest#test1: PASSED (0ms) [2/2] MyTestF#test2: IGNORED (0ms)
İşaret değerlerinin değişmediği uçtan uca veya birim testleri oluşturun.
İşaretlerin geçersiz kılınamadığı ve testlerin yalnızca mevcut işaret durumuna göre filtrelenebildiği test durumlarında, CheckFlagsRule
kuralını RequiresFlagsEnabled
ve RequiresFlagsDisabled
ek açıklamalarıyla birlikte 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şturulup çalıştırılacağı gösterilmektedir:
Test kodunuzda test filtreleme uygulamak için
CheckFlagsRule
kullanın. Ayrıca, testiniz için işaret gereksinimlerini belirtmek üzereRequiresFlagsEnabled
veRequiredFlagsDisabled
Java ek açıklamalarını kullanın.Cihaz tarafı testi,
DeviceFlagsValueProvider
sınıfını kullanı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() {} }
jflag-unit
ve aconfig tarafından oluşturulan kitaplıkları, testiniz için derleme dosyasınınstatic_libs
bölümüne 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:[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 varsayılan değerleri
Başlatılan SetFlagsRule
, cihazdaki işaret değerlerini kullanır. Cihazdaki işaret değeri, adb gibi bir yöntemle geçersiz kılınmazsa varsayılan değer, derlemenin yayın yapılandırmasıyla aynı olur. Cihazdaki değer geçersiz kılınmışsa SetFlagsRule
, geçersiz kılma değerini varsayılan olarak kullanır.
Aynı test farklı yayın yapılandırmaları altında yürütülürse SetFlagsRule
ile açıkça ayarlanmamış işaretlerin değeri değişebilir.
Her testten sonra SetFlagsRule
, 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 etkileri olmaz.