前两篇文章都在聊战术打法,本文开始说说具体的技术实现。Kat先生在这次大会上分享了不少i18n开源项目,包括以下内容。
1. New Pseudolocalizer
作为Android Studio的一部分,适用于Android SDK 23及更高版本。可以使用AAPTBuild tools: aapt --pseudo-localize,也可以通过File > Project Structure >Build Types > Pseudo Locales Enabled来驱动它。
2. Android Lint
通过对Android工程源码进行扫描和检查,Lint能发现尽早潜在的问题,以便修复从而实现“高位逼抢”。目前Lint已经支持如下i18n检查点。
· RTL Compatibility
· Hardcoded text in layout files
· Message correctness
· RelativeLayoutOverlap (starting in SDK 24)
· Hardcoded text in setText
· String concatenation in setText
· Number formatting in setText
3. IME的Mock测试代码
目前提供了两种使用方式。
· AOSP package已经预安装在模拟器中
· apk package也已提供了公开下载的方式
4. I18n Sanity Checker
本文的主角登场啦!大家可以在GitHub拿到它的最新版本https://github.com/googlei18n/i18n_sanitycheck目前只提供了Java版,C++版的相信也会不日放出。
i18n-sanitychecker是一个base在Junit + ICU开源库之上的UT framework,大家可以使用它更加方便的对locale-sensitivemethods进行i18nunit test(严格的说是white-boxtest),解除了对"goldendata"的依赖。
提供一段样例代码,大家感受下。
@Test
public voidtestIntegration_StaticRegexAndNumber() {
assertI18nSanityCheck(
"У *[0-9]+ меня есть {number:{value:120}} яблок. И {number} из них я отдамтебе.",
"У *[0-9]+ меня есть сто двадцать яблок. И 5 из них я отдам тебе.", newULocale("ru"));
}
@Test
public voidtestIntegration_CurrencyValue() {
assertI18nSanityCheck("明日は{number:{value:15.6}}を費やすでしょう。","明日は15.6円を費やすでしょう。",
ULocale.JAPANESE);
}
@Test
public voidtestIntegration_NativeNumbersFa() {
assertI18nSanityCheck("{number}", "١٦٨", newULocale("fa"));
}
@Test
public voidtestIntegration_NativeNumbersTe() {
assertI18nSanityCheck("{number}", "౧౩౮", newULocale("te"));
}
@Test
public voidtestIntegration_NativeNumbersBn() {
assertI18nSanityCheck("{number}", "৪২", newULocale("bn"));
}
@Test
public voidtestIntegration_CustomLocaleInPlaceholder() {
assertI18nSanityCheck("Ответ {number:{locale:'ru'}}","Ответ сорок два", new ULocale("ar"));
}
@Test
public voidtestIntegration_TimeZone() {
assertI18nSanityCheck("{timezone:{value:'Eastern Time'}}","ET", ULocale.US);
}
@Test
public voidtestIntegration_SortingJa() {
assertI18nSanityCheck("{sorting}", "Tokyo,こんにちは,東京",ULocale.JAPANESE);
}
@Test
public voidtestIntegration_PhoneZhStrict() {
assertI18nSanityCheck("{phone:{lenient:false, strict:true}}","+86 (0755) 22445566",
ULocale.CHINA);
}
@Test
public voidtestIntegration_XMLExample() {
assertI18nSanityCheck("<data>" + lnSeparator +"<name>{ignore}</name>" + lnSeparator
+"<dob>{date:{locale:'ja'}}</dob>" + lnSeparator +"<phone>{phone}<phone>" + lnSeparator
+"</data>", "<data>" + lnSeparator +"<name>Zapp</name>" + lnSeparator
+"<dob>2008年12月31日</dob>"+ lnSeparator + "<phone>+1 650 224 2244<phone>" +lnSeparator
+"</data>", ULocale.US);
}
@Test
public voidtestIntegration_TokenizationTh() {
assertI18nSanityCheck("{tokenization}", "สัปดาห์,ที่,ส", newULocale("th"));
}
GitHub上同时提供了详细的placeholders说明。
Placeholders
Placeholder | Description |
{ignore} | Ignores everything within this placeholder. |
{time} | Checks if formatted time satisfies ICU standards. |
{date} | Checks if formatted date satisfies the ICU standards |
{datetime} | Merges 2 and 3 together. Has same optional parameters. |
{number} | Checks if formatted number satisfies the ICU standards. ould be used to check currency, rational, scientific, numbers and spelled numbers. |
{locale} | Checks if locale code matches. |
{timezone} | Checks if timezone matches. |
{sorting} | Checks if the elements within the placeholder were sorted correctly according to the locale rules. |
{period} | checks if date time period is correct. |
Additional parameters for placeholders
Parameter | Applies To | Description |
pattern | date, time, datetime | ICU formatting pattern (see ICU documentation for details). |
skeleton | date, time, datetime | ICU skeleton - less restrictive than pattern |
value | date, time, datetime, number | actual value in numeric locale-independent format. For date and time - milliseconds since Jan 1, 1970 |
lenient | date, time, datetime, number, timezone | Relax format validation rules |
strict | sorting | Apply more strict sorting rules (see ICU documentation) |
对i18nUT同样有兴趣的同学们,还等什么?快来试试哦!
最后Kat先生还宣布一大波工具正在开源的路上,包括Pseudolocalizationof CLDR ,AndroidUI message utility,Translationcoverage tool等,让我们敬请期待!当然,有兴趣的话也欢迎加入开源社区,一起来为i18n测试代码添砖加瓦吧。