用蚂蚁库项目的Andr​​oid单元测试 [英] Android unit test using ant with library project

查看:119
本文介绍了用蚂蚁库项目的Andr​​oid单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎也是最新的Andr​​oid SDK工具仍不能正确支持包含链接库项目的应用程序测试。

It seems that also the latest android SDK tools still don't properly support testing of applications that contain linked library projects.

我有以下设置项目:

TESTLIB(机器人库项目)< - TestMain(Android项目)< - TestMainTest(机器人单元测试项目)

TestLib (android library project) <- TestMain (android project) <- TestMainTest (android unit test project)

我创建了日食所有这些项目,然后用 Android的更新(测试 - / lib-)项目... 生成构建。 XML 等。人。

I created all those projects in eclipse and then used android update (test-/lib-)project ... to generate the build.xml et. al.

这个问题,只要你有一类TestMain( InheritAddition.java 在我的例子),开始一个继承自一个类TESTLIB( Addition.java ),并要引用这个类在单元测试( InheritAdditionTest.java )。

The problem starts as soon as you have a class in TestMain (InheritAddition.java in my example) that inherits from a class in TestLib (Addition.java) and you want to reference this class in the unit test (InheritAdditionTest.java).

public class Addition {
    public int add2(int o1, int o2) {
      return o1 + o2;
    }
}

TestMain

public class InheritAddition extends Addition {
    public int sub(int p1, int p2) {
        return p1 - p2;
    }
}

TestMainTest

public class InheritAdditionTest extends AndroidTestCase {
    public void testSub() {
        Assert.assertEquals(2, new InheritAddition().sub(3, 1));
    }
}

在命令行上构建的结果如下:

When building on the command line the result is the following:


W/ClassPathPackageInfoSource(14871): Caused by: java.lang.NoClassDefFoundError: org/test/main/InheritAddition
W/ClassPathPackageInfoSource(14871):    ... 26 more
W/ClassPathPackageInfoSource(14871): Caused by: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
W/ClassPathPackageInfoSource(14871):    at dalvik.system.DexFile.defineClass(Native Method)
W/ClassPathPackageInfoSource(14871):    at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:195)
W/ClassPathPackageInfoSource(14871):    at dalvik.system.DexPathList.findClass(DexPathList.java:315)
W/ClassPathPackageInfoSource(14871):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:58)
W/ClassPathPackageInfoSource(14871):    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
W/ClassPathPackageInfoSource(14871):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
W/ClassPathPackageInfoSource(14871):    ... 26 more
W/dalvikvm(14871): Class resolved by unexpected DEX: Lorg/test/main/InheritAddition;(0x41356250):0x13772e0 ref [Lorg/test/lib/Addition;] Lorg/test/lib/Addition;(0x41356250):0x13ba910

我发现了一些解决方法,适用于Eclipse的:

I found some workaround that works for eclipse:

<一个href="http://stackoverflow.com/questions/2472059/cant-build-and-run-an-android-test-project-created-using-ant-create-test-proje">Can't建立和运行一个Android测试项目中使用&QUOT创建蚁创建测试项目&QUOT;测试时,项目在libs目录罐

这是卓有成效的,但我要寻找一个解决方案,用ANT的作品(更多precisely我要寻找一个解决方案,两个同时工作)。

That does the trick, but I am looking for a solution that works with ANT (more precisely I am looking for a solution that works on both at the same time).

该记录方法(通过改变build.xml文件,从主体工程罐子包括到类路径)在这里不适用作为样本项目不使用任何的jar包(我也相信,这方面的问题已经得到解决与SDK工具R16)。

The documented approach (by changing build.xml to include jars from the main project into the class path) is not applicable here as the sample project doesn't use any library jars (also I believe that this particular problem is now fixed with SDK tools r16).

我想解决了的蛮力方法是尝试,不知怎么删除 TestMainTest 的依赖关系到 TESTLIB (通过修改 project.properties ),而是设法破解构建脚本把那些内置罐子到类路径中(所以替换 -compile 目标的东西,修改的类路径的javac )。因为我有试图跟上Android的SDK工具链的变化很长的历史,这是不是真的我最喜欢的选择,因为它是一个)相当复杂和b)要求的的build.xml 每当工具链的变化(这是相当常见)。

I guess the brute force way of solving that is to try and somehow remove the dependencies of TestMainTest to TestLib (by modifying project.properties) and instead manage to hack the build script to put those built jars into the class path (so replace the -compile target with something that modifies the class path for javac). Since I have a long history of trying to keep up with android SDK toolchain changes, this is not really my favorite option as it is a) rather complicated and b) requires constant modification of the build.xml whenever the toolchain changes (which is quite frequently).

所以我在寻找如何获得这样的设置工作,而无需使用大锤的想法。也许我失去了一些东西完全明显,但对于我这种用例是相当标准,我也很难理解为什么这不支持开箱即用。

So I am looking for ideas of how to get such a setup working without using the sledge hammer. Maybe I am missing something totally obvious but for me this use case is fairly standard and I have a hard time understanding why this isn't supported out of the box.

推荐答案

@ wallacen60的回答是不错的。我昨天来到了同样的结论。 Neverthe少,还有另一种选择:不是不包括从测试谟的德兴的lib的jar,这将是很好,如果我们能找到一种方法,包括在编译的lib的jar文件(javac编译Ant文件的阶段)的测试,并仅在编译阶段,而不是德兴阶段。

The answer of @wallacen60 is nice. I came to the same conclusion yesterday. Neverthe less, there is another option : instead of excluding the lib's jar from dexing of the test projet, it would be nice if we could find a way to include the lib's jar in the compilation (javac, compile stage of the ant file) of test, and only in the compilation stage and not the dexing stage.

@ wallacen60的解决方案,而且介绍了3项目及其相关的汇编之间有很大的语义差别:在Eclipse应用程序依赖于LIB,测试依赖于应用程序。这是正确的方式来做到这一点。但在蚂蚁,无论是应用程序和测试依赖于库,似乎像一个坏redunduncy周期给我。

The solution of @wallacen60 moreover introduces a big semantic difference between the compilation of the 3 project and their dependencies : in Eclipse App depends on lib, test depends on App. And that is the right way to do it. But in ant, both App and Test depend on Lib and seems like a bad redunduncy cycle to me.

所以,就目前而言,我们所做的是补丁测试项目的project.properties文件,使其包含该行:

So, for now, what we did was to patch the test project's project.properties file so that it includes this line :

tested.android.library.reference.1=../SDK_android

和我们修改了测试项目的Ant文件,使编译目标包括图书馆:。(看改变路线,搜索单词变革)

And we modified the ant file of the tested project so that the compile target includes the library : (look at the changed line, search for the word "change").

    <!-- override "compile" target in platform android_rules.xml to include tested app's external libraries -->
<!-- Compiles this project's .java files into .class files. -->
<target name="-compile" depends="-build-setup, -pre-build, -code-gen, -pre-compile">
    <do-only-if-manifest-hasCode elseText="hasCode = false. Skipping...">
        <!-- If android rules are used for a test project, its classpath should include
             tested project's location -->
        <condition property="extensible.classpath"
                value="${tested.project.absolute.dir}/bin/classes"
                else=".">
            <isset property="tested.project.absolute.dir" />
        </condition>
        <condition property="extensible.libs.classpath"
                value="${tested.project.absolute.dir}/${jar.libs.dir}"
                else="${jar.libs.dir}">
            <isset property="tested.project.absolute.dir" />
        </condition>
        <echo message="jar libs dir : ${tested.project.target.project.libraries.jars}"/>
        <javac encoding="${java.encoding}"
                source="${java.source}" target="${java.target}"
                debug="true" extdirs="" includeantruntime="false"
                destdir="${out.classes.absolute.dir}"
                bootclasspathref="android.target.classpath"
                verbose="${verbose}"
                classpath="${extensible.classpath}"
                classpathref="jar.libs.ref">
            <src path="${source.absolute.dir}" />
            <src path="${gen.absolute.dir}" />
            <classpath>
                <!-- steff: we changed one line here !-->
                <fileset dir="${tested.android.library.reference.1}/bin/" includes="*.jar"/>
                <fileset dir="${extensible.libs.classpath}" includes="*.jar" />
            </classpath>
            <compilerarg line="${java.compilerargs}" />
        </javac>
               <!-- if the project is instrumented, intrument the classes -->
                        <if condition="${build.is.instrumented}">
                            <then>
                                <echo>Instrumenting classes from ${out.absolute.dir}/classes...</echo>
                                <!-- It only instruments class files, not any external libs -->
                                <emma enabled="true">
                                    <instr verbosity="${verbosity}"
                                           mode="overwrite"
                                           instrpath="${out.absolute.dir}/classes"
                                           outdir="${out.absolute.dir}/classes">
                                    </instr>
                                    <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from
                                         user defined file -->
                                </emma>
                            </then>
                        </if>           
    </do-only-if-manifest-hasCode>
</target>

事实上,这种机制似乎是正确的,因为它模拟了日食一样。但是Eclipse能够知道应用程序编译测试时依赖于库。唯一的区别是,我们在人工蚂蚁通过管道暴露这种关系(在project.properties)

Indeed, this mechanism seems to be the right one as it mimics what eclipse does. But eclipse is able to know that the App depends on lib when compiling test. The only difference is that we exposed this relation manually in ant via the line (in project.properties)

tested.android.library.reference.1=../SDK_android

但是它可能是可以自动这样做。我找不到,谷歌蚂蚁工具的机制用于生产从android.library REFID的librairy项目路径。*语句在project.properties。但是,如果我能找到这个机制,我可以传播这种依赖的测试项目,与Eclipse一样。

But it could be possible to do that automatically. I can't find the mechanism that google ant tools use to produce the librairy project path refid from the android.library.* statement in a project.properties. But if I could find this mechanism I could propagate this dependency in the test project, as eclipse does.

因此​​,我认为最好的办法是让谷歌知道自己有一个补丁做,并暂时保留手动导出个应用项目向LIB项目的依赖,以编写测试项目的解决方案。

So I think the best would be to let google know that they have a patch to do, and temporarily keep the solution of exporting manually the dependency of th app project toward the lib project in order to compile the test project.

可以了解这个bug的人接触谷歌?

Can someone contact google about this bug ?

这篇关于用蚂蚁库项目的Andr​​oid单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆