我想在运行单元测试时获得代码覆盖率。我使用标准的android build.xml运行ant coverage
进行测试。
测试运行良好。ant coverage
的最后一个字符串是
Tests run: 59, Failures: 1, Errors: 4
Generated code coverage data to /data/data/my.package/files/coverage.ec
但是coverage.ec文件只有37个字节长,而且几乎是空的。
运行emma报告告诉
no collected coverage data found in any of the data files [all reports will be empty]
并在每个字段中生成零的漂亮报告。
我认为emma应该产生更大的覆盖范围
我做错了什么?
---更新---
做了一些深挖掘。除了覆盖率结果生成之外,似乎大多数事情都很好。
1) 它编译了所有表示的内容
[javac] /blabla/android-sdk-linux_x86/tools/ant/main_rules.xml:384: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 88 source files to /blabla/project/tests/instrumented/classes
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
2) 它正在为正在测试的项目执行<instr>
和mode="overwrite"
。路径正常。
-emma仪器:[echo]正在从/blaba/project/tests/instrument/classes检测类。。。
因此,有一个*.em文件,其中包含98个类的元数据。
3) 一些标准的android转换为dex,package转换为unaligned,zip对齐。结果是/blaba/project/tests/instructiond/project-debug.apk.
4) 正在将此项目-debug.apk安装到模拟器上。
5) 编译测试项目。编译:[javac]/blabla/android-sdk/android-sedk-linux_x86/tools/ant/main_rules.xml:384:警告:未设置"includeanturntime",默认为build.sysclasspath=last;对于可重复的生成,设置为false[javac]编译110个源文件到/blaba/project/tests/bin/classes
源文件包括所有以前的文件和测试(110=88+测试),如build.properties中所述(多个Source.dir用";"分隔)。
6) 资源、Dex、签名、zip对齐。。。结果是项目Test-debug.apk
7) 正在模拟器上安装projectTest-debug.apk。
8) 在指定"覆盖范围打开"的am中运行测试。它告诉
[exec] Generated code coverage data to /data/data/blabla.project/files/coverage.ec
9) 此coverage.ec不包含任何相关数据。它有37个字节长。报告告诉
processing input file [/home/ubuntu/projects/ppf2/workspace/PPF2/tests/coverage.ec] ...
loaded 0 coverage data entries
...
no collected coverage data found in any of the data files [all reports will be empty]
除了最后一步,一切对我来说似乎都很好。
我遇到了同样的问题,我想我理解这里发生的事情。
我看起来正在测试的包的源也在测试包的内部(或被引用为源)。
结果是,如果你打开你的包apk,它们看起来如下:
PackageUnderTest/ClassFileUnderTest
TestPackage/TestClass
TestPackage/ClassFileUnderTest
ClassFileUnderTest:
pluclic class ClassFileUnderTest{
public int foo(){
...
}
}
测试类别:
pluclic class TestClass{
public void testFoo(){
int result = foo();
assert...
}
}
这里发生的情况是,每当您的TestClass从testFoo()调用foo()方法时,就会在TestClass/ClassFileUnderTest而不是PackageUnderTest/ClassFileUnderTest上调用foo。
因此,记录的PackageUnderTest/ClassFileUnderTest从未运行过,也没有记录在覆盖率报告中。
从TestPackage中删除引用PackageUnderTest代码强制PackageUnderTest从PackageUnderTest运行并计入覆盖率报告。
经过几个小时的战斗,问题终于解决了。决议是非常简单和无法想象的。
在TEST项目的build.properties中,我有这样的东西:
tested.project.dir=..
env.WORKSPACE= /bla/bla
source.dir=${env.WORKSPACE}/first/src;${env.WORKSPACE}/second/src;${env.WORKSPACE}/andsoon/src;
但是!我不应该在这里指定source.dir!指定tested.project.dir
就足以成功编译测试项目。
此外,如果我在TEST项目中这样指定source.dir,测试运行良好,但emma报告零覆盖率,正如问题所述。