Emma reports 0% coverage

2019-07-10 16:42发布

I want to get code coverage when running unit tests. I run ant coverage using standard android build.xml for tests.

Tests run well. The last strings from ant coverage are

Tests run: 59,  Failures: 1,  Errors: 4

Generated code coverage data to /data/data/my.package/files/coverage.ec

But the coverage.ec file is only 37 bytes long and is almost empty.

Running emma report on it tells

no collected coverage data found in any of the data files [all reports will be empty]

and generates beautiful report with ZEROES in every field of it.

I suppose that emma should generate a bigger coverage.ec.

What am I doing wrong?

--- update ---

Did some deep digging. It seems that most of things are well except coverage result generation.

1) It compiles everything saying

[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) It is doing <instr> with mode="overwrite" for the project that is under test. The path is ok.

-emma-instrument: [echo] Instrumenting classes from /blabla/project/tests/instrumented/classes...

As a result, there is a *.em file with metadata for 98 classes.

3) Some standard android conversion to dex, package to unaligned, zip align. Result is /blabla/project/tests/instrumented/project-debug.apk.

4) Installing this project-debug.apk onto emulator.

5) Compiling the tests project. compile: [javac] /blabla/android-sdk/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 110 source files to /blabla/project/tests/bin/classes

Source files include all the previous files plus tests (110 = 88 + tests), as stated in build.properties (multiple source.dir separated by ";").

6) Resources, Dex, signing, zip align... Result is projectTest-debug.apk

7) Installing projectTest-debug.apk onto emulator.

8) Running tests through am where "coverage on" specified. It tells that

[exec] Generated code coverage data to /data/data/blabla.project/files/coverage.ec

9) This coverage.ec contains no relevant data. It is 37 bytes long. Report on it tells that

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]

Everything seems good for me except the last step.

2条回答
劳资没心,怎么记你
2楼-- · 2019-07-10 17:05

I ran into the same issue and I think I understand what happened here.

I looks like the sources of the package under test were also inside (or referenced as being sources) of the test package.

The result is that your package apks looked like the following if you opened them up:

PackageUnderTest/ClassFileUnderTest

TestPackage/TestClass
TestPackage/ClassFileUnderTest

ClassFileUnderTest:

pluclic class ClassFileUnderTest{
    public int foo(){
       ...
    }
}

TestClass:

pluclic class TestClass{
    public void testFoo(){
       int result = foo();
       assert...
    }
}

What is happening here is that whenever your TestClass called the foo() method from testFoo(), foo() got called on TestClass/ClassFileUnderTest instead of PackageUnderTest/ClassFileUnderTest.

As a result, the instumented PackageUnderTest/ClassFileUnderTest never got run and didn't get tallied in the coverage report.

Removing the reference PackageUnderTest code from the TestPackage enforced that the PackageUnderTest code got run from PackageUnderTest and tallied into the coverage report.

查看更多
Ridiculous、
3楼-- · 2019-07-10 17:06

Finally, after many hours of fighting, question resolved. Resolution is very simple and unexpectable.

In build.properties of the TEST project I had something like:

tested.project.dir=..
env.WORKSPACE= /bla/bla
source.dir=${env.WORKSPACE}/first/src;${env.WORKSPACE}/second/src;${env.WORKSPACE}/andsoon/src;

But! I should NOT specify source.dir here! Specifying tested.project.dir is enough to compile test project successfully.

Moreover, if I specify source.dir in TEST project like this - tests run well but emma reports zero coverage, just as stated in question.

查看更多
登录 后发表回答