Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing code coverage using Clover on a Play! Framework Application using Ant

I'm writing an Ant script to do some additional checks on my Play! Framework Application.

Currently, I am executing my tests from my Ant script by simply making an exec call to "play auto-test".

    <exec executable="${play.dir}/play.bat">
        <arg line="auto-test"/>
    </exec>

Would anyone know how to integrate Clover into a Play test suite? Obviously I am not tied to having to run my tests using the above.

I also tried writing the Ant script using the traditional way of executing JUnit tests (i.e. using Ant's junit target) and I got two problems:

  • When executing all my tests, only the first would execute successfully while the others would fail for strange reasons
  • If I just expose one test in my suite and have the test run successfully, it would say I have code coverage of 0%. I then thought I set up clover incorrectly, however, I created a simple class that tested a production class that did nothing and the coverage went up as I would expect.

So if I were to go down the junit route, I would need to know how to execute all my tests so that they can run one after another successfully (it works when using the Play way of running play auto-test) and I would need to know why Clover does not seem to pick up lines of code touched by Play tests.

(I know there is a Cobertura module for Play, however, I find that Clover does a better job telling me an accurate coverage figure)

Update: Unfortunately I am unable to replicate the exact error I was getting before as I have run into compilation issues when I try and compile things manually. I've started to use the Secure module and it only contains Java source files. So in my Ant script, I call play precompile which produces the byte code for the Secure module (as well as everything else in the system including my code). So now when I try and compile my app code using Clover, I think the compiler gets into a bit of a tangle as I have two versions of my classes - one produced by the precompile command (non-clover) and one produced by my own ant compilation (with clover):

[javac] C:\projects\testproject\out\clover\classes\clover8583527041716431332.tmp\model\HouseTest.java:45: incompatible types
[javac] found   : play.db.jpa.JPABase
[javac] required: models.House
[javac]         __CLR2_5_115y15ygoxiz3dv.R.inc(1527);House found = House.findById(id);

So I essentially have two problems now:

  • I need to be able to compile my source code that also depends on Play provided modules (e.g. CRUD, Secure) which do not have compiled versions hence my attempt at getting around it by calling play precompile myself in my Ant script
  • Once I get compilation working, I will undoubtedly have my original issue again of not being able to execute the tests using the junit target.

Update #2: It turns out that the error I got was due to the findById call required a cast from JPABase to House (not that the IDE or play seemed to care about it). So after I went in and put a cast for all of play's "find*" methods, I actually got JUnit and Clover reports! However... I am now getting two kinds of errors:

  • Entity classes created in Play can be created by extending the Model class which provides magic methods such as those find methods mentioned before as well as the count method. The Model superclass actually extends GenericModel which implements those methods by throwing an UnsupportedOperationException. So obviously Play! does some more magic behind the scenes to provide actual implementations of these methods. Unfortunately, my tests (and production code) rely on methods such as count but they are throwing the exception in my ant/junit scenario (note: everything works fine when running play auto-test.

  • The other error I am getting is due to the fact that I use the Spring module. In one of my classes (the root class), I call Spring.getBeanOfType(Some.class). Now I use auto-scanning, but in the ant/junit testing environment, the Spring module has yet to set up my spring container and therefore the call just returns null.

I have a feeling there is one magic fix that will resolve both of my issues however I am unsure what that magic fix is.

like image 662
digiarnie Avatar asked Jun 06 '11 06:06

digiarnie


1 Answers

Clover does source level instrumentation, so it needs source code available. Everything you do before activating clover that generates bytecode will not be "clovered".

Clover for ant intercepts ant-compiler calls, so if you do a <clover-setup/> before any other compilation tasks in your ant script, everything sould be instrumented by clover.

You can execute the resulting compiled code in any way you want, e.g. executing from script or from junit, it does not matter, as long as the code is instrumented (and of course clover.jar is available in the classpath). Clover hard-codes the location of the clover-database into the instrumented code, so you do not have to specify anything when executing.

It would really help, if you could outline how you are using clover, and you could also do a recheck at clover documentation at http://confluence.atlassian.com/display/CLOVER/1.+QuickStart+Guide.

like image 185
Ron Avatar answered Sep 19 '22 15:09

Ron