5

我的設置:測試使用項目ActionBarSherlock

  1. 庫項目:ActionBarSherlock
  2. 項目
  3. 測試項目

我的項目有鏈接爲庫項目庫項目。它編譯和運行良好。

現在我嘗試使用正常的測試項目來測試我的應用程序。在eclipse中運行測試非常完美。如果我嘗試運行使用Ant測試,測試項目甚至不編譯:通過Eclipse

[javac] LoginActivityTest.java:9: cannot access com.actionbarsherlock.app.SherlockActivity 
[javac] class file for com.actionbarsherlock.app.SherlockActivity not found 
[javac] public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> { 
[javac]                  ^
[javac] LoginActivityTest.java:25: cannot find symbol 

建築工程完善和測試運行完美,太。

如果我將庫項目鏈接到我的測試項目,它會用ant編譯,但測試失敗。

[exec] Error in testSuiteConstructionFailed: 
[exec] java.lang.RuntimeException: Exception during suite construction 
[exec]  at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:238) 
[exec]  at java.lang.reflect.Method.invokeNative(Native Method) 
[exec]  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169) 
[exec]  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154) 
[exec]  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:537) 
[exec]  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551) 
[exec] Caused by: java.lang.reflect.InvocationTargetException 
[exec]  at java.lang.reflect.Constructor.constructNative(Native Method) 
[exec]  at java.lang.reflect.Constructor.newInstance(Constructor.java:417) 
[exec]  at android.test.suitebuilder.TestMethod.instantiateTest(TestMethod.java:87) 
[exec]  at android.test.suitebuilder.TestMethod.createTest(TestMethod.java:73) 
[exec]  at android.test.suitebuilder.TestSuiteBuilder.addTest(TestSuiteBuilder.java:262) 
[exec]  at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:184) 
[exec]  at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:371) 
[exec]  at com.zutubi.android.junitreport.JUnitReportTestRunner.onCreate(JUnitReportTestRunner.java:90) 
[exec]  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3891) 
[exec]  at android.app.ActivityThread.access$1300(ActivityThread.java:122) 
[exec]  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1184) 
[exec]  at android.os.Handler.dispatchMessage(Handler.java:99) 
[exec]  at android.os.Looper.loop(Looper.java:137) 
[exec]  at android.app.ActivityThread.main(ActivityThread.java:4340) 
[exec]  at java.lang.reflect.Method.invokeNative(Native Method) 
[exec]  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
[exec]  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
[exec]  at dalvik.system.NativeStart.main(Native Method) 
[exec] Caused by: java.lang.NoClassDefFoundError: com.myproject.android.app.activities.LoginActivity 
[exec]  at com.myproject.android.app.test.LoginActivityTest.<init>(LoginActivityTest.java:18) 
[exec]  ... 19 more 

我的測試類:

public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> { 

    private LoginActivity mActivity; 

    private EditText  mTextUserName; 

    private EditText  mTextUserPassword; 

    public LoginActivityTest() { 
     // the super call is line 18 (see stack trace above) 
     super("com.myproject.android.app.activities", LoginActivity.class); 
    } 

    @Override 
    protected void setUp() throws Exception { 
     super.setUp(); 
     mActivity = getActivity(); 
     mTextUserName = (EditText) mActivity.findViewById(com.myproject.android.app.R.id.login_activity_username); 
     mTextUserPassword = (EditText) mActivity.findViewById(com.myproject.android.app.R.id.login_activity_password); 
    } 

    public void testPreConditions() { 
     assertTrue("Activity is null!", mActivity != null); 
    } 

    public void testLogin() throws Throwable { 
     mActivity.runOnUiThread(new Runnable() { 
      public void run() { 
       mTextUserName.setText("username"); 
       mTextUserPassword.setText("password"); 
      } 
     }); 
     sendKeys(KeyEvent.KEYCODE_ENTER); 
    } 
} 

一些想法如何,我可以解決這個問題?

更新:它看起來像螞蟻生成/測試仍然是一團糟。根據這個關於testing a library project的博客條目,7個列出的問題中的大多數將在下一個ADT版本(ADT r20)中修復。

回答

7

有很多漂浮使用Library項目,因爲ADT 17(取決於無論您當前正在敲打你的頭靠在你的辦公桌)分手/固定有關的一切信息的不同位。

首先,請注意Library與「庫」的區別,其中Library是Android團隊頒佈的名詞。我還使用Referencing項目,該項目描述了使用Library項目的項目。

即,A Referencing項目使用Library項目。

Library「庫」項目

在正常的Java開發有可能在Eclipse鏈接項目,其中一個是依賴於其他的來源。我相信這種方法具有使用庫項目源作爲參考項目的來源的效果。這意味着在編譯引用項目時,庫項目源在範圍之內。庫項目類與引用項目的類同時構建。

當在大多數情況下使用時,這種方式非常有效,因爲所有類都是以JAR或WAR或其他方式構建並打包的。

庫項目

一個競爭(混搭)的方式來庫項目是在Android團隊Library項目:

的Android項目標記爲一個Library項目將編譯將它的源代碼建立到其bin目錄中的jar文件中(在clean/build命令之後)。任何Referencing項目都會自動導入此jar並獲得對Library項目功能的訪問權限。您可以通過查看包資源管理器中的Java庫Android Dependencies來查看此關係。

除了類依賴分辨率的資源也被直接引用,並編譯成Referencing項目gen目錄內R.java文件。

ADT引進問題,人民設立的,因爲它增加了「支持」,包括它是由Library項目中引用罐子:

預ADT 17

Library項目有一個jar添加到它的構建路徑。 Referencing項目也可以將該jar添加到它的自己的構建路徑中。

ADT 17日起

Dealing With Dependencies

後其動態引用自己的罐子ADT 17 Library項目開始出現異常。這不僅僅是在您的Referencing項目中包含相同的相關參考,以便在兩個範圍內都能看到該jar。現在這導致了包含類的奇怪重複。

不幸的是,簡單地從ReferencingLibrary項目中刪除庫(因此只有一個鏈接存在),然後混淆了eclipse,它不能再使用它來看到項目範圍內的jar。

要解決這個問題,您需要將Library項目罐放在/libs目錄中 - 如果您的罐子在硬盤驅動器上處於獨立位置,這可能會導致後端疼痛。這些罐子將自動用於您的LibraryReferencing項目。

因此,要搬過去ADT 17:

  • 刪除所有jar文件被用作當前的項目範圍源(這是否是你的LibraryReferencing項目)。
  • 從你的Library項目中刪除沒有「庫」項目(而不是將它們編譯成罐子)。
  • 從您的Library項目中刪除外部罐子,將它們複製到libs目錄。