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目录。