2012-02-23 35 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