Mock测试中遇到找不到message properties文件问题解决过程

最近做iFix GVT测试工作,要测试中文的mock(关于Mock Testing,见附1)

可以发现部署好mock的测试环境后,不管是用IE还是FF都无法打开UI,错误异常信息如下:

Error page exception
The server cannot use the error page specified for your application to handle the Original Exception printed below. Please see the Error Page Exception below for a description of the problem with the specified error page.
 
Original Exception:
Error Message: Can't find bundle for base name com.ibm.rfidic.messages.RFIDICUIMessages, locale
Error Code: 500
Target Servlet: /jsp/RFIDICLogin.jsp
Error Stack:
java.util.MissingResourceException: Can'

问题解决:

原来是IE和FF默认的语言选择成了en_US,而不是zh_CN。

以FF为例,“工具” -> “选项” -> “内容” -> “语言” ,将浏览器的默认语言改成“中文”即可解决。

问题分析:

java.util.MissingResourceException: Can’t find bundle for base name com.ibm.rfidic.messages.RFIDICUIMessages, locale

注意到此错误信息,提示找不到Base的properties文件,并且locale是空值?

Base的properties文件RFIDICUIMessages确实不存在,因为在做Mock的时候已经将其改为RFIDICUIMessages_zh_CN.properties文件了,为什么系统不会自动去找zh_CN呢?

走近源代码观察:

public class MessageProvider implements IMessageProvider {
 
..... //省略其他方法与变量
 
private ResourceBundle getResourceBundle(Message message)
{
Locale locale = message.getLocale();
 
if (locale.getLanguage().equals("en")) {  // 肯定是message的locale设为了en_US才会导致locale重置为空!!!继续查找其他locale设置的方法LocaleContext类,见下。
locale = new Locale("", "", "");
}
ResourceBundle resourceBundle = (this.loader != null) ?
ResourceBundle.getBundle(this.messageConstants.getResourceName(message.getId()), locale, this.loader) :
ResourceBundle.getBundle(this.messageConstants.getResourceName(message.getId()), locale);
 
return resourceBundle;
}
 
protected String getMessageString(Message message)
{
ResourceBundle resourceBundle = getResourceBundle(message);
return resourceBundle.getString(message.getMessageId());
}
 
public IMessage getMessage(int messageId, Object[] args)
{
return getMessage(messageId, LocaleContext.current().getLocale(), args);
}
public class LocaleContext
{
private Locale locale;
private TimeZone timeZone;
private static ThreadLocal currentPreference = new ThreadLocal();
 
public LocaleContext()
{
this(Locale.getDefault(), TimeZone.getDefault());
}
 
public LocaleContext(Locale locale, TimeZone timeZone)
{
this.locale = locale;
this.timeZone = timeZone;
}
 
public Locale getLocale()
{
return this.locale;
}
 
public TimeZone getTimeZone()
{
return this.timeZone;
}
 
public void reset()
{
this.locale = Locale.US;
this.timeZone = TimeZone.getDefault();
}
 
public void setLocale(Locale locale)
{
this.locale = locale;
}
 
public void setTimeZone(TimeZone zone)
{
this.timeZone = zone;
}
 
public static LocaleContext current()
{
LocaleContext localeContext = (LocaleContext)currentPreference.get();
if (localeContext == null)
{
localeContext = new LocaleContext();
bind(localeContext);
}
return localeContext;
}
 
public static void bind(LocaleContext localeContext)
{
currentPreference.set(localeContext);
}
 
public static void unbind()
{
currentPreference.set(null);
}
}

问题就在于浏览器发送的HTTP请求locale是en_US的,到了服务器端自动找默认的RFIDICUIMessages(不带任何后缀),发现没有此resource才抛错。

另外以此可以推断原来访问Google.com的规则,如果浏览器默认设置为中文,那么服务器端会判断时区然后自动重定向到Google.cn;相反如果浏览器设置为英文en_US,那么就是在访问Google.com

附1:Mock Testing简介

Mock Testing又叫做pseudo translation testing

1.检查点

1)检查text是否作了pseudo translated (即,是否做了mock. 主要是检查text是否被抽取从来到resource 文件)
2)检查text是否有concatenated(拼接,嵌套)的情况Example:    [text] [other text] (拼接)Example:    [I go to the [store]] (嵌套)一个句子不可以分为两条message.  如上面的example1。除非是有句号,问号等,标示是两个不同的句子。
3)检查text是否被corrupted(截断)
例如 text 在英文下是: sample messages
在做了mock以后是, [zh中国~~sample mes
则是message 被截断了。 这一般是由于developers给该message留的space不够长。
4)检查是否有Garbled Characters (即显示不正常的字符)例如: 做了mock 的message是:[zh中国~~sample messages ~~ CN]
但是在UI上’中国’这两个字显示的是乱码,或者问号,或者方框。这可能是由于被测产品对相应的字符不支持。
5)检查UI 的控件的显示是否正常例如一:这个控件显示不全

2.Pseudo Translation Testing Process 测试流程
1)安装做过pseudo translated 的build. (在我们的rfidic,因为主要的pII file 是一些properties 文件,RFIDICInternalMessages.properties, RFIDICIWEMessages.properties, RFIDICUIMessages.properties 。 这些文件在com.ibm.rfidic.messages.jar文件中。我们的做法是把这些文件取出来,作mock translation, 然后再打回这个jar 文件去,直接把新jar文件copy到server 的相应目录。)

2)把系统的locale切换为需要测试的locale
For RHEL:
查找
[root@localhost ~]# locale
[root@localhost ~]# locale -a |grep jp ((UNIX)grep:字符串查找)
设置
[root@localhost ~]# export LANG=ja_JP.utf8

[root@localhost ~]# export LC_ALL= ja_JP.utf8
For Linux RedHat server, the following steps are for setting locale to Ja_JP.utf-8.
(1) vi /etc/sysconfig/i18n
(2) modify the LANG=”ja_JP.UTF-8″
(3) reboot server

For AIX:
(1) Edit /etc/environment
(2) 修改 LANG=locale ,export LANG.locale 是你要修改的具体locale.
(3) 保存然后 reboot
3)开始测试(text, message, tips, controls,…)

Leave a Comment.