Friday, November 5, 2010

Milena Velba Ho Ho Ho Gallery

Couverture de code : Mise en œuvre de Cobertura pour une application Web

This note presents the implementation of Cobertura for a Web application. You will find a brief overview of Cobertura, followed by a tutorial for its use in testing a Web application running on Tomcat.

Presentation Cobertura Cobertura

is a tool that measures code coverage of a test set. It does not perform the tests or automate them: Cobertura fair measure the relevance and completeness of those tests.

tools that measure the coverage of your Java code all work the same way:

  1. it is not necessary to modify the Java code: the solutions are not intrusive.
  2. there is first a phase manipulation of compiled files (class, jar or war): This phase occurs after the compilation seems to build a layer of proxies on existing binaries in order to intercept all calls.
  3. it runs the tests with the instrumented binaries by adding a jar for the proper functioning of the layer proxy.
  4. it completes the test by an output violent (often Ctrl C) to the proxy layer is to resume the hand creates the reporting
  5. running out, converting the file record in HTML pages: one obtains a site that shows for each Java class: the percentage code executed, the number of conditional branches executed and details of the code executed or not.

The outcome of the process is a report that indicates whether all of the code has been tested and which allows detection of code not executed.

Below is a sample index.html page is a summary of the report is the starting point of the various pages of analysis.

CoberturaRapportIndex

We note that for each package was a summary of covered code:

  • was the number of classes that make up the package
  • was the percentage of lines code executed (comment lines are not counted)
  • was the number of lines executed and the total number of lines of code in this package (all grades)
  • what Cobertura branch is called conditional branch ( if, else ...): it measures if for each test, we had to the case of true and false. If you only had the case of true, you'll be only 50% test coverage of the branches.
  • the last column is the complexity "cyclotimique" code (I admit not having used this information)

For a class, it is possible to have detail. This point can be very useful when trying to improve its test: we must understand what part of the code has not been tested to build the test which will cover.

CoberturaDetail

is found that the top was a summary of the coverage of the class with the percentage and number of lines tested on the number of total lines of the class.

was then the code executed in green lines with the number of times, the red lines that have not been: in the example above only the constructor and the method getSolde were executed.

Implementation of a Web application for Cobertura

The majority of this documentation using Cobertura in phases JUnit unit tests. Implementing a web application deployed on a JEE application server like Tomcat is more delicate: the proper functioning of Cobertura is based on good management of the data file (called datafile and whose default name is cobertura.ser) . However, this management is based on what the application server sees as the starting point of its file system and this parameter varies enormously from one configuration to another and from one server to another.

Configuring Tomcat 6.0

The test was done on a Tomcat 6.0 server. The server is launched with the startup.bat and not as a Windows service: it has a significant impact on the location or the file must be cobertura.ser.

For my part, I downloaded from the site http://tomcat.apache.org/download-60.cgi core version for Windows 32-bit 32-bit Windows.zip. The directory

obtained during the unzip: apache-tomcat-6.0.29 has been copied to a new folder on my desktop TestCouverture created for the occasion. So I have a dedicated environment for my tests.

catalina.bat I open the bin located in the very beginning and I add the following file:

Set JAVA_HOME = C: \\ Program Files \\ Java \\ jdk1.6.0_18

The advantage of this solution is to free myself of any rights restrictions on the directories: default, Tomcat is usually installed in Program Files which is subject to recent versions of Windows (Vista and Seven) has a policy of restrictive rights may prevent the update from the data file Cobertura cobertura.ser.

Installing Cobertura

I used the last version available (at the time of my tests), version 1.9.4.1.

It can be downloaded from the following site: http://cobertura.sourceforge.net/download.html

Just unzip in the directory, in my case the same file TestCouverture office.

Manipulation of Classes with Cobertura

Before exploit my classes of my project TestCobertura Eclipse JEE, I generate the war file from Eclipse.

I deployed to my Tomcat server configured for the test: Desktop \\ apache-tomcat-6.0.29 \\ webapps. Think about any jar to be installed in Tomcat / lib as those of drivers database.

I run the application after starting Tomcat with startup.bat. It exploded the war file TestCobertura. Stop the server.

To exploit Java classes, we will build from the Eclipse project directory that contains the class and we will crush these class TestCobertura exploded directory of the Tomcat server (hence the importance of application execution )

  • my project directory Eclipse is in My Documents \\ eclipsewsp, the class files are in C: \\ Users \\ MONCOMPTEWINDOWS \\ Documents \\ eclipsewsp \\ TestCobertura \\ build \\ classes.
  • The repertoire of war exploded in Tomcat is: C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat-6.0.29 \\ webapps \\ TestCobertura.
  • cobertura.ser The data file will be created in the Tomcat bin directory: C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat-6.0.29 \\ bin

Think:

  • MONCOMPTEWINDOWS must be replaced by the string for your configuration.
  • TestCobertura is the name of my Eclipse project.
  • eclipsewsp is the name of my Eclipse workspace directory.

It opens a DOS command file. it is positioned in the directory Cobertura:

cd C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ cobertura-1.9.4.1

We type the following command:

cobertura-instrument.bat - datafile "C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat-6.0.29 \\ bin \\ cobertura.ser" - destination "C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat -6.0.29 \\ webapps \\ TestCobertura \\ WEB-INF \\ classes " "C: \\ Users \\ MONCOMPTEWINDOWS \\ Documents \\ eclipsewsp \\ TestCobertura \\ build \\ classes"

careful to use the quotation marks "to avoid problems in areas of potential long names. The result should be:

Cobertura 1.9.4.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file Instrumenting

1 file to C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat-6.0.29 \\ webapps \\ TestCobertura \\ WEB-INF \\ classes

Cobertura: Saved information is 131 classes.

Instrument time: 4129ms

In the bin directory of your Tomcat server, you should find a file cobertura.ser. This file is necessary for the proper functioning of Cobertura: it indicates the list of classes it must exploit and test results. This file will be read / write during test execution.

If you want to repeat the tests to zero, it is possible to save this version of the file that contains classes manipulated with a usage count to zero. The

. Class files from WEB-INF \\ classes have been changed (the date was changed).

The classes are manipulated.

Test the application exploited

If you try to restart the application, you will get an error in the log localhost:

Caused by: java.lang.NoClassDefFoundError: net / sourceforge / cobertura / coveragedata / HasBeenInstrumented
java.lang.ClassLoader.defineClass1 at (Native Method) at
java.lang.ClassLoader.defineClassCond (ClassLoader.java : 632) at
java.lang.ClassLoader.defineClass (ClassLoader.java: 616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2733)
    at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1124)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1612)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:192)
    at org.hibernate.cfg.AnnotationConfiguration.parseMappingElement(AnnotationConfiguration.java:647)
    ... 57 more
Caused by: java.lang.ClassNotFoundException: net.sourceforge.cobertura.coveragedata.HasBeenInstrumented
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645) Has
org.apache.catalina.loader.WebappClassLoader.loadClass (WebappClassLoader.java: 1491)
... 69 more

This error means that the lack cobertura jar that is used by classes manipulated.

the extent where they built a Tomcat server for the tests, simply add cobertura.jar in the bin directory of Tomcat.

The jar is in the cobertura directory TestCouverture \\ cobertura-1.9.4.1. Simply copy TestCouverture \\ apache-tomcat-6.0.29 \\ lib. You can restart

Tomcat with Startup.bat and run your test.

At the end of your test, you stop putting yourself in Tomcat console will open it and press Ctrl C. Tomcat stops and updates the file cobertura.ser with logs of your use.

generate report HTML

The final phase is the generation of the report in HTML format.

The report uses the file cobertura.ser updated when you use. For this to work requires that when running your application, Tomcat has found the file cobertura.ser well established during the manipulation. If not found, it will create a file cobertura.ser in apache-tomcat-6.0.29 \\ bin but it will not contain any information.

The location of this file depends on the mechanism for starting tomcat: with startup.bat, it is in apache-tomcat-6.0.29 \\ bin.

careful what Tomcat can edit this file: it will probably be a problem if Tomcat service is running or if he is in a Program Files directory. For all these reasons I have encouraged you to start to install your own version of Tomcat test.

For the report is the maximum detail, you need sources.

In my example, they are in the Eclipse project: C: \\ Users \\ MONCOMPTEWINDOWS \\ Documents \\ eclipsewsp \\ TestCobertura \\ src.

It will generate the report in the subdirectory of the directory rapportCobertura TestCouverture. To do this we create the subdirectory rapportCobertura

We replace the directory TestCouverture \\ cobertura-1.9.4.1 and you type the following command:

cobertura-report.bat-source C: \\ Users \\ MONCOMPTEWINDOWS \\ Documents \\ eclipsewsp \\ TestCobertura \\ src "- datafile" C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ apache-tomcat-6.0.29 \\ bin \\ cobertura.ser " - Destination C: \\ Users \\ MONCOMPTEWINDOWS \\ Desktop \\ TestCouverture \\ rapportCobertura "" C: \\ Users \\ MONCOMPTEWINDOWS \\ Documents \\ eclipsewsp \\ TestCobertura \\ build \\ classes "

For information, options used are:

  • source: the source directory
  • datafile: file location cobertura.ser
  • destination directory where the report is generated

The last parameter is the location of the original class files .

careful to use quotation marks "to avoid problems in areas of potential long names. The result should be:

Cobertura 1.9.4.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file Cobertura
: Loaded information is 23 classes.
Report time: 569ms

TestCouverture In the directory \\ rapportCobertura you should see a series of html file with the file index.html.

If the directory is empty, check the name and path of your various files and directories. Unfortunately the message is the same between success and failure.

To view the report, double click index.html.

So when you see the detail of a class, you do not code for the class but the message

fr/natsystem/demonatjet/gettingstarted/DemoNatJet40.java Unable to locate. Have you spécifié The source directory?

is that you forgot to specify the source option of the command or the name of the directory containing your source is incorrect.

Cobertura and AspectJ and Spring

Cobertura and AspectJ module of spring both use proxy mechanisms colliding. It is therefore possible that when running a class exploited, you get the following message (where the same class not manipulated works perfectly):

org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$ Proxy17 ministre net.sourceforge.cobertura.coveragedata.HasBeenInstrumented, org. springframework.aop.SpringProxy, org.springframework.aop.framework.Advised 'to required type' fr.j2ltho.impression.ImpressionManager 'for property' impressionManager ';
nested exception IS java.lang.IllegalStateException: Can not convert value of type [$ Proxy17 ministre net.sourceforge.cobertura.coveragedata.HasBeenInstrumented, org.springframework.aop.SpringProxy, org.springframework.aop.framework.Advised] required to type [fr.j2ltho.impression.ImpressionManager] for property 'impressionManager': no matching editors or conversion Strategy found
org.springframework.beans.BeanWrapperImpl.convertForProperty (BeanWrapperImpl.java: 462)

In my Spring configuration files j 'had the following statement:

\u0026lt;context:annotation-config/>

For Spring this is the second flight with AspectJ \u0026lt;aop:aspectj-autoproxy/> following default.

To solve the problem I just added the following line in bold:

\u0026lt;context:annotation-config/>

\u0026lt;aop:aspectj-autoproxy proxy-target-class="true" />

This was my error disappear and I could continue my tests. Conclusion

We did a quick tour of using Cobertura in a JEE context. You can now validate that your tests cover all of your code.

The functioning of these tests rely on the ability of the application server to find the right file cobertura.ser and update it. The location where a server application seeks to file remains a mystery to me. In the case of a Tomcat server started with startup.bat it is in the Tomcat directory / bin. In the other ace, I'll let you discover its location. One solution is to run your server on classes manipulated without adding the file cobertura.ser. It will at the end of executing a new file cobertura.ser empty but will indicate its location.

Another difficulty with using an application server is the termination mechanism to be used. Cobertura appears to place some sort of hook on a certain type of violent output (including the Ctrl C). It must pass through this hook, to put an Updated file cobertura.ser. For certain server and some configuration, stop triggering the hook can be difficult to implement. For Tomcat, simply start with Startup.bat and stop it with Ctrl C.

I plan to write quickly, a second post that will focus on the desirability and value of using Cobertura in a project.

0 comments:

Post a Comment