2012-02-23 72 views
3

我在为Android 2.3.x进行CTS R12测试时发现问题。 在媒体压力测试期间,由于文件异常,所有案例均失败。 它是由测试案例中的静态变量“FILE_PATH”为空引起的。 我发现它在Android 2.3.6的NexusOne/NexusS上可以100%重现。JUnit测试期间的Android 2.3.x静态字段问题

我还写了一个非常简单的测试项目来测试它,代码如下。

活动代码:

package com.hw.hello; 

import android.app.Activity; 
import android.os.Bundle; 

public class HelloActivity extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 
} 

测试用例代码:

package com.hw.hello.test; 

import com.hw.hello.HelloActivity; 

import android.test.ActivityInstrumentationTestCase2; 
import android.util.Log; 

public class HelloTest extends ActivityInstrumentationTestCase2<HelloActivity> { 

    private static final String STR; 

    static { 
     STR = "XXXXXX"; 
    } 

    public HelloTest() { 
     super("com.hw.hello", HelloActivity.class); 
    } 

    @Override 
    public void setUp() { 

    } 

    public void test1() { 
     Log.d("111111", "STR="+STR); 
    } 

    public void test2() { 
     Log.d("222222", "STR="+STR); 
    } 
} 

当你运行它,你会发现其结果是:

02-24 01:24: 04.280:D/111111(28075):STR = XXXXXX

02-24 01:24:04.327:D/222222(28075):STR = null

我知道Google已经在ICS上修复了这个问题。 但是我发现Dalvik VM的变化要多合并到2.3.7。 我可以通过CTS R12来解决这个问题吗?

============================================== ==================================

我不能在8小时内自己回答我的问题。 所以我这里有答案:

我的法国同事给我的提示,找到最终解决方案: 我发现在ActivityTestCase.java

的变化是增加的状况ICS源代码中的一些变化: & &(field.getModifiers()& Modifier.FINAL)== 0

@Override 
protected void scrubClass(final Class<?> testCaseClass) 
throws IllegalAccessException { 
    final Field[] fields = getClass().getDeclaredFields(); 
    for (Field field : fields) { 
     final Class<?> fieldClass = field.getDeclaringClass(); 
     if (testCaseClass.isAssignableFrom(fieldClass) && !field.getType().isPrimitive() 
       && (field.getModifiers() & Modifier.FINAL) == 0) { 
      try { 
       field.setAccessible(true); 
       field.set(this, null); 
      } catch (Exception e) { 
       android.util.Log.d("TestCase", "Error: Could not nullify field!"); 
      } 

      if (field.get(this) != null) { 
       android.util.Log.d("TestCase", "Error: Could not nullify field!"); 
      } 
     } 
    } 
} 

我把这段代码到我的测试用例类覆盖超类的方法,这个问题已经得到解决。

+0

你应该已经添加了答案作为自己的答案并接受它。这些信息非常有用,它为我节省了很多时间。 – Malcolm 2012-12-08 03:42:11

回答

1

由于@Malcolm的要求

我不能在8小时内回答我的问题我自己。所以,我这里有答案:

我的法国同事给我的提示,找到最终解决方案:我发现在ActivityTestCase.java

变化的ICS源代码中的一些变化是一个额外的条件:& & (field.getModifiers()& Modifier.FINAL)== 0

@Override 
protected void scrubClass(final Class<?> testCaseClass) 
throws IllegalAccessException { 
    final Field[] fields = getClass().getDeclaredFields(); 
    for (Field field : fields) { 
     final Class<?> fieldClass = field.getDeclaringClass(); 
     if (testCaseClass.isAssignableFrom(fieldClass) && !field.getType().isPrimitive() 
       && (field.getModifiers() & Modifier.FINAL) == 0) { 
      try { 
       field.setAccessible(true); 
       field.set(this, null); 
      } catch (Exception e) { 
       android.util.Log.d("TestCase", "Error: Could not nullify field!"); 
      } 

      if (field.get(this) != null) { 
       android.util.Log.d("TestCase", "Error: Could not nullify field!"); 
      } 
     } 
    } 
} 
0

那么,你可以确保你的静态字段在构造函数中获得合适的值。是的,这是一个丑陋的黑客,但它的工作。

+0

感谢您的回复。是的,我可以在我的测试项目中做到这一点,因为我有源代码。但是我不能为CTS测试包做任何事情,因为它是Google发布的。 – Robin 2012-02-23 14:56:29