我每天都在Eclipse中运行非android JUnit测试。今天我想测试我的一些Android库类。噢,好痛。
我有一个Android库项目使用Android -maven-plugin。我在src/main/java
中有源文件,在src/test/java
中有(新)单元测试。我的POM有适当的JUnit依赖项和android-maven-plugin引用。
有时我从File
创建一个Android Uri
实例。有时我有一个现有的Java URI
实例,我从File
创建,然后将其转换为Uri
。因为我既不相信Java也不相信Android的文件和uri(不要让我开始Java如何在uri中破坏UNC路径,或者Java如何在uri中破坏equals()
契约),我想创建一个简单的单元测试来创建一个临时文件,从两种不同的方法创建Uris
,并确保它们相等。
Ctrl+F11
在Eclipse中运行它。Eclipse问我这是"Android JUnit测试"还是"JUnit测试"。当然是Android。所以我选择了第一个选项,得到:
[2013-03-23 21:37:10 - mylib] ------------------------------
[2013-03-23 21:37:10 - mylib] Android Launch!
[2013-03-23 21:37:10 - mylib] adb is running normally.
[2013-03-23 21:37:10 - mylib] Could not find mylib.apk!
嗯…那不是很成功。因此,我删除了运行配置,并尝试"JUnit测试"。现在我得到一个不同的对话框,要求我选择我喜欢的启动器,"Android JUnit Test launcher"或"Eclipse JUnit Test launcher"。我选择哪一个并不重要;我:
Class not found com.example.MyUnitTest
java.lang.ClassNotFoundException: com.example.MyUnitTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:693)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:429)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
我读过Android -maven-plugin,我可以在Eclipse本地运行单元测试,如果他们只是使用Android jar中的类,但不做任何API调用,这就是我在这里做的。我该怎么做呢?
一种解决方法是单击工具栏中的"Run As…"按钮,然后选择"Run Configurations…"。如果您选择您创建的JUnit启动器并转到它的"Classpath"选项卡,您可以将bin/classes
文件夹添加到JUnit启动器的类路径中。
不要使用Run As - Android JUnit Test
,因为它只用于运行Android测试项目。
当使用Run As - JUnit Test
时, ClassNotFoundException
是由于ADT和Eclipse内置JUnit Test Runner之间关于项目输出文件夹的不一致。ADT生成 bin/classes
下的所有.class文件,而内置的JUnit Test Runner在 target/classes
下查找.class文件。你的Android项目在Eclipse中从不使用 target/classes
,所以它仍然是空的,这就是为什么你得到 ClassNotFoundException
异常的原因。
恐怕没有办法改变Eclipse内置的JUnit Test Runner来使用不同于默认目标/类的文件夹。
查看Ricardo的答案,了解如何将bin/classes
添加到内置JUnit测试运行器的类路径中。还需要注意的是,你不能将Android项目的默认输出文件夹更改为 ../bin/classes
以外的东西,因为它会破坏ADT构建过程。
肮脏的工作方法(用于解决ClassNotFoundException)是手动复制 binclasses
下的所有内容到 targetclasses
,注意每次更改源代码时都需要这样做。
当从命令行或通过Eclipse运行mvn test
时,这不是问题,因为Maven使用 targetclasses
并知道如何正确填充它。注意,通过使用这种方法,您将无法在Eclipse中使用带有漂亮的红/绿错误条的JUnit窗口。
一个android的junit测试应该位于一个单独的模块设置在android Maven插件样例项目(例如morseflash的例子)。这是由于重载路径设置和需要构建apk并将其部署到设备/模拟器上以运行测试。Android单元测试根本不是单元测试,而是集成测试(或者在这种情况下称为instrumentation测试)。