| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
| <html> | |
| <head> | |
| <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
| <title>Automating Eclipse PDE Unit Tests using Ant</title> | |
| <link href="../article.css" rel="stylesheet" type="text/css"> | |
| <body> | |
| <h1>Automating Eclipse PDE Unit Tests using Ant</h1> | |
| <div class="summary"> | |
| <h2>Summary</h2> | |
| <p>This article outlines how to integrate your PDE unit tests into | |
| an Ant based automated build, using a simple Eclipse plug-in as an | |
| example, some simple java classes, basic Eclipse plug-in techniques and | |
| some standard Ant tasks.</p> | |
| <div class="author">By Brian Joyce, <a target="_blank" | |
| href="http://www.duolog.com">Duolog Technologies Ltd., Galway, | |
| Ireland</a></div> | |
| <div class="copyright">Copyright © 2008, Brian Joyce</div> | |
| <div class="date">June 13, 2008</div> | |
| </div> | |
| <div class="content"> | |
| <h2><a name="Introduction"></a>Introduction</h2> | |
| <p>It's generally accepted that writing tests as part of software | |
| development is a very good thing indeed. It's also generally accepted | |
| that automating the running of tests in an automated or nightly build is | |
| good engineering practice. Let's face it, if tests are not run | |
| automatically then there's a good chance they won't be run at all, and | |
| tests that are not run are next to useless.</p> | |
| <p>The Eclipse Plug-in Development Environment (PDE) provides a | |
| excellent framework for developing plug-ins and also provides facilities | |
| to write and run PDE unit tests for your plug-ins that can be run from | |
| within the Eclipse environment.</p> | |
| <p>Once you have taken the time and effort to write these valuable | |
| PDE unit tests, how do you automate the running of these PDE unit tests | |
| so that you can integrate them into your automated build?</p> | |
| <p>Searching the web provides several options for automating PDE | |
| tests such as: </p> | |
| <ul> | |
| <li>Markus Barchfeld's excellent <a | |
| href="http://www.eclipse.org/articles/Article-PDE-Automation/automation.html" | |
| target="_blank">Build and Test Automation for plug-ins and | |
| features</a> article which details setting up automatic building and | |
| testing for an Eclipse plug-in using the Eclipse headless build.</li> | |
| <li><a | |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.test/testframework.html?view=co" | |
| target="_blank">Eclipse Test Framework</a>.</li> | |
| <li>Patrick Paulin's RCP Quickstart post on <a | |
| href="http://rcpquickstart.wordpress.com/2007/08/06/running-automated-tests-with-pde-build/" | |
| target="_blank">Running Automated Tests with PDE Build.</a></li> | |
| <li>Some more excellent links can be found at <a | |
| href="http://eclipsenuggets.blogspot.com/2007/09/6-great-links-for-eclipse-build.html" | |
| target="_blank">6 Great Links for Eclipse Build Automation with | |
| PDE Build</a>.</li> | |
| </ul> | |
| <p>As you can see writing PDE Tests can be complex, running PDE | |
| Tests from the command line can be complex too, but running them and | |
| collecting the results in a format that can be easily interpreted (e.g. | |
| Junitreport format) is even more difficult.</p> | |
| <p>This article provides a detailed example application, the | |
| enabling technology to collect and format test results (see <a | |
| href="#PDE_Test_Utilities">PDE Test Utilities</a> ), and a build system | |
| that demonstrates a generic mechanism for running PDE Tests using Ant, | |
| allowing you to integrate it with any Ant build system.</p> | |
| <p>This PDE Test technique provides the following benefits:</p> | |
| <ol> | |
| <li>Allows you to run your PDE Tests from the command line</li> | |
| <li>Allows you to collect the PDE Tests results in a format that | |
| can be easily interpreted (i.e. Junitreport format)</li> | |
| <li>Allows you to integrate PDE Tests into any Ant-based build | |
| system</li> | |
| </ol> | |
| <p><strong>Note:</strong> all the techniques and examples detailed | |
| in this article have been tested against Eclipse 3.3 (specifically | |
| Eclipse 3.3.2 and 3.3.1.1) on Windows XP only and using <a | |
| href="http://ant.apache.org/bindownload.cgi" target="_blank">Ant | |
| 1.7.0</a> . There is also an <a href="PDETestExampleProjects-3.1.zip">Eclipse | |
| 3.1 version</a> of the example code.</p> | |
| <h2><a name="Overview"></a>Overview</h2> | |
| <p>PDE unit tests are automated as follows:</p> | |
| <h3>Prerequisites:</h3> | |
| <ol> | |
| <li>A dedicated PDE test Eclipse installation that is only used by | |
| the automated build system.</li> | |
| <li>For each Eclipse plug-in <i style="color: rgb(255, 0, 0);">A</i> | |
| that is to be tested, an Eclipse plug-in fragment <i | |
| style="color: rgb(255, 0, 0);">A-test</i> for <i | |
| style="color: rgb(255, 0, 0);">A</i> that only contains the PDE unit | |
| tests and their test dependencies for the plug-in <i | |
| style="color: rgb(255, 0, 0);">A</i>.</li> | |
| <li>A pre-defined (or specified) PDE test port.</li> | |
| <li>A PDE test listener class to listen on the PDE test port for | |
| the results from the PDE test run.</li> | |
| <li>A list of PDE test classes to be run as part of the PDE Test | |
| run</li> | |
| </ol> | |
| <h3>Running the PDE unit tests:</h3> | |
| <p>See <a href="#Figure_1_-_Overview_diagram_of_the_PDE">Figure 1</a> | |
| below for a visual representation of the PDE test steps.</p> | |
| <ol> | |
| <li>Deploy plug-in <i style="color: rgb(255, 0, 0);">A</i> and | |
| plug-in fragment <i style="color: rgb(255, 0, 0);">A-test</i> into a | |
| pristine PDE test Eclipse installation.</li> | |
| <li>Select PDE test port (or use predefined reserved port).</li> | |
| <li>Start the PDE test listener process that listens on the PDE | |
| test port.Startup the PDE test Eclipse installation, specifying the | |
| list of unit test classes to be run, and the PDE test port to output | |
| test progress and results to.</li> | |
| <li>The PDE test Eclipse installation starts up and automatically | |
| runs the specified tests and outputs the results to the PDE test port | |
| where the PDE test listener process captures the results and outputs | |
| them in standard Ant <a target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> | |
| task XML format.</li> | |
| <li>Run the regular Ant <a target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> | |
| task on the generated test results XML files.</li> | |
| <li>That's it: you now have a typical Ant JUnit HTML report | |
| containing your PDE unit test results.</li> | |
| </ol> | |
| <div class="figure"><a name="Figure_1_-_Overview_diagram_of_the_PDE"></a><img src="images/PDETestProcessFlow.jpg" | |
| style="border: 2px solid; width: 1121px; height: 610px;" | |
| alt="PDE Test process flow diagram" | |
| title="PDE Test process flow diagram"> | |
| <p class="caption">Figure 1 - Overview diagram of the PDE Test steps</p></div> | |
| <h2>Prerequisites</h2> | |
| <p>This section describes the prerequisites for using this technique | |
| in more detail.</p> | |
| <h3>Dedicated PDE test Eclipse installation</h3> | |
| <p>In order to run the PDE Tests you need a separate Eclipse installation | |
| whose sole purpose is for running the PDE Tests. Having a dedicated | |
| Eclipse installation provides a pristine and repeatable test environment | |
| and avoids any possible conflicts or corruption that might occur with a | |
| typical development Eclipse installation. </p> | |
| <h3>Use an Eclipse plug-in fragment for the PDE Unit Tests for a | |
| plug-in</h3> | |
| <p>This technique promotes the use of <a | |
| href="http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/guide/product_def_plugins.htm" | |
| target="_blank">Eclipse plug-in fragments</a> to develop PDE Unit tests | |
| for plug-ins, so for each Eclipse plug-in <i | |
| style="color: rgb(255, 0, 0);">A</i> that is to be tested, an Eclipse | |
| plug-in fragment <i style="color: rgb(255, 0, 0);">A-test</i> for <i | |
| style="color: rgb(255, 0, 0);">A</i> that only contains the PDE unit | |
| tests and their test dependencies for the plug-in <i | |
| style="color: rgb(255, 0, 0);">A</i>.</p> | |
| <p>You can of course develop the PDE tests directly in the plug-in | |
| (in a test directory), but this can lead to unwanted dependencies in | |
| your plug-in and involves slightly more complicated packaging for | |
| your plug-in (i.e. without test classes and test dependencies).</p> | |
| <p>The Eclipse plug-in fragment approach avoids these | |
| pitfalls and although it requires a little more setup initially it | |
| provides a cleaner and clearer mechanism for defining PDE Tests and also | |
| provides a straightforward way for the build system of identifying which | |
| plug-ins have PDE Tests associated with them.</p> | |
| <p>For a good description and more general discussion of using | |
| Eclipse plug-in fragments for testing, see Patrick Paulin's RCP | |
| Quickstart article <a | |
| href="http://rcpquickstart.wordpress.com/2007/06/20/unit-testing-plug-ins-with-fragments/" | |
| target="_blank">Testing Plug-ins with Fragments</a>.</p> | |
| <h3>PDE test port</h3> | |
| <p>In order for the PDE test runner and the PDE test listener | |
| processes to communicate, both processes need to use a predefined or | |
| specified port so that the PDE test runner can send the test progress | |
| and results to the PDE test listener process. In the example code | |
| we use a utility class <a href="#PDETestPortLocator"><code>pde.test.utils.PDETestPortLocator</code></a> | |
| in the <a href="article.html#PDE_Test_Utilities">pde.test.utils</a> | |
| plug-in to find an available port and this is used by the PDE test runner | |
| and PDE test listener processes to communicate.</p> | |
| <h3>PDE test listener process</h3> | |
| <p>In order to be able to monitor and record the progress | |
| and results of the PDE test run, you need a PDE test listener | |
| process that listens on the specified port to collect PDE test progress | |
| and results from the PDE test runner process. Ideally the PDE test | |
| listener process should provide the results of the PDE test run in a | |
| manner that is easy to interpret should any of the tests fail.</p> | |
| <p>The <a href="#PDETestResultsCollector"><code>pde.test.utils.PDETestResultsCollector</code></a> | |
| class (using the <a href="#PDETestListener"><code>pde.test.utils.PDETestListener</code></a> | |
| class) in the <a href="article.html#PDE_Test_Utilities">pde.test.utils</a> | |
| plug-in, provides the PDE test listener process that listens on the | |
| specifed port for test results from the PDE test runner process and | |
| handles them using the <code>org.apache.tools.ant.taskdefs.optional.junit.JUnitTest</code> | |
| and <code>org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter</code> | |
| classes (available from Apache Ant API) to provide the results in the | |
| same XML format that is output by the Ant <a target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> | |
| task. These XML result files can then be used by the Ant <a | |
| target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> | |
| task to provide an <a href="reports/test/index.html">HTML report</a> of | |
| the PDE test run that is very easily interpreted.</p> | |
| <p>For example to run the PDE test listener process from the command | |
| line for our example PDE tests would similar to:</p> | |
| <pre> java -classpath ... pde.test.utils.PDETestResultsCollector PhoneBookExample-test 1623</pre> | |
| <h3>PDE test runner process</h3> | |
| <p>Eclipse provides a mechanism for running tests from the command | |
| line using the main Eclipse launcher class to launch the <code>org.eclipse.pde.junit.runtime.uitestapplication</code> | |
| application, this is the PDE test runner process. The PDE test runner | |
| process is passed details of the port to publish test progress and | |
| results to for listeners to analyse, the plug-in name being tested and | |
| the names of the PDE test classes to run.</p> | |
| <p>For example to run the PDE test runner process from the command | |
| line for our example PDE tests would similar to:</p> | |
| <pre>java -classpath ...\eclipse\plugins\org.eclipse.equinox.launcher_1.0.1.R33x_v20080118.jar | |
| org.eclipse.equinox.launcher.Main | |
| -application org.eclipse.pde.junit.runtime.uitestapplication | |
| -data ...\PhoneBookExample-test\target\reports\test/output/ws | |
| -dev bin | |
| -clean | |
| -port 1623 | |
| -testpluginname PhoneBookExample | |
| -classnames phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</pre> | |
| <h3>PDE Tests classes list</h3> | |
| <p>The PDE test runner process takes as a parameter a comma | |
| separated list of the test classes to run in a PDE test run. In the | |
| example code, the name of the single test class to be | |
| run is hardcoded i.e. <code>phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</code> | |
| but the generation of the list of PDE test classes could easily be | |
| automated.</p> | |
| <h2>Running PDE Unit Tests in Ant</h2> | |
| <p>This section describes the Ant build file in the example code | |
| that runs the PDE Tests and explains the key Ant targets involved. See <a | |
| href="article.html#Figure_1_-_Overview_diagram_of_the_PDE">Figure 1</a> | |
| above for a visual representation of the steps involved in running PDE | |
| tests in Ant.</p> | |
| <p>The example code featuring full source and Ant build files | |
| for a project containing PDE unit tests can be found in the | |
| accompanying <a href="PDETestExampleProjects-3.3.zip">PDETestExampleProjects-3.3.zip</a> | |
| ZIP file.</p> | |
| <p><strong>Note:</strong> that the <a | |
| href="PDETestExampleProjects-3.3.zip">PDETestExampleProjects-3.3.zip</a> | |
| ZIP file contains a full standalone project complete with an Ant | |
| build system (see <a | |
| href="article.html#PDETestExampleProjects.zip_Contents">zip | |
| contents</a> below for more details). Unzip the contents into | |
| a directory that is separate from your Eclipse installation and workspace.</p> | |
| <h3>Ant script that runs PDE Unit tests</h3> | |
| <p>The following Ant excerpt is from the Ant build file used to run | |
| the PDE unit tests in the <i>PhoneBookExample-test</i> plug-in fragment | |
| for the <i>PhoneBookExample</i> plug-in (see <i>projects\PhoneBookExample-test\build.xml</i> | |
| in the accompanying ZIP file):</p> | |
| <pre><!-- Build file for the Phonebook Example plug-in PDE unit test fragment --> | |
| <project name="phonebookexampletest" default="help" basedir="."> | |
| ... | |
| <target name="pde_test"> | |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> <delete> | |
| <fileset dir="${test.eclipse.dir}/configuration" includes="**/*" excludes="config.ini"/> | |
| <fileset dir="${test.eclipse.dir}/plugins" includes="PhoneBookExample*.jar"/> | |
| <fileset dir="${test.eclipse.dir}/plugins" includes="pde.test.utils*.jar"/> | |
| </delete> | |
| <!-- Load plugin and pde tests plugin fragment into test eclipse installation --> | |
| <img src="images/tag_2.gif" align="middle" height="13" width="24"> <copy todir="${test.eclipse.dir}/plugins" overwrite="true"> | |
| <fileset dir="${published.plugins.dir}"/> | |
| </copy> | |
| <delete file="pde_test_port.properties"/> <!-- properties file generated by PDETestPortLocator class in pde.test.utils --> | |
| <img src="images/tag_3.gif" style="width: 24px; height: 13px;" | |
| align="middle"> <java classname="pde.test.utils.PDETestPortLocator" fork="yes" classpathref="pde.test.port.locator.class.path"/> | |
| <waitfor maxwait="10" maxwaitunit="second" checkevery="100" checkeveryunit="millisecond"> | |
| <available file="pde_test_port.properties"/> | |
| </waitfor> | |
| <property file="pde_test_port.properties"/> | |
| <echo message="Using port ${pde.test.port} for listening to PDE Test run"/> | |
| <parallel> | |
| <daemons> | |
| <img src="images/tag_4.gif" align="middle" height="13" width="24"> <antcall target="run_pde_test_listener"/> | |
| </daemons> | |
| <sequential> | |
| <sleep seconds="5"/> <!-- Give the listener a few seconds to start up --> | |
| <img src="images/tag_5.gif" align="middle" height="13" width="24"> <antcall target="run_pde_tests"/> | |
| </sequential> | |
| </parallel> | |
| <img src="images/tag_6.gif" align="middle" height="13" width="24"> <delete> | |
| <fileset dir="${test.eclipse.dir}/plugins" includes="PhoneBookExample*.jar"/> | |
| <fileset dir="${test.eclipse.dir}/plugins" includes="pde.test.utils*.jar"/> | |
| </delete> | |
| <mkdir dir="${test.reports.dir}"/> | |
| <img src="images/tag_7.gif" align="middle" height="13" width="24"> <move todir="${test.reports.dir}"> | |
| <fileset dir="."> | |
| <include name="**/TEST-*.xml"/> | |
| </fileset> | |
| </move> | |
| </target> | |
| <img src="images/tag_4.gif" align="middle" height="13" width="24"> <target name="run_pde_test_listener"> | |
| <java classname="pde.test.utils.PDETestResultsCollector" fork="yes" classpathref="pde.test.listener.class.path"> | |
| <arg line="${plugin.name} ${pde.test.port}"/> | |
| </java> | |
| </target> | |
| <img src="images/tag_5.gif" align="middle" height="13" width="24"> <target name="run_pde_tests"> | |
| <property name="test.classes.list" value="phonebookexample.dialogs.PhoneBookEntryEditorDialogTest"/> | |
| <mkdir dir="${test.reports.dir}/output/ws"/> | |
| <java dir="${plugin.dir}" classname="org.eclipse.equinox.launcher.Main" fork="yes" classpathref="equinox.launcher.class.path"> | |
| <arg line="-application org.eclipse.pde.junit.runtime.uitestapplication -data ${test.reports.dir}/output/ws -dev bin -clean -port ${pde.test.port} -testpluginname PhoneBookExample -classnames ${test.classes.list}"/> | |
| </java> | |
| </target> | |
| ... | |
| </project></pre> | |
| <p>The key elements of this Ant build file are identified above:</p> | |
| <table cellpadding="2" cellspacing="2"> | |
| <tbody> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_1.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">This prepares for the PDE test run by | |
| deleting all previously deployed plug-ins from the plugins directory | |
| of the dedicated test installation of Eclipse.</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_2.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">This copies the set of plug-ins under | |
| test (including the test fragment) into the plugins directory of the | |
| test installation of Eclipse.</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_3.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">This discovers an available port for the | |
| PDETestListener to listen on - it does it by launching a simple java | |
| class (PDETestPortLocator) to detect the next available port and | |
| stores it as a property pde.test.port in the pde_test_port.properties | |
| file. This property is then loaded from the pde_test_port.properties | |
| file and is used in the test run.</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_4.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">This step launches the PDETestListener | |
| in a separate thread (using the Ant parallel & daemons tasks) to | |
| listen for test results on the port identified by the pde.test.port | |
| property (see Label 3 above)</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_5.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">This is the actual step that runs the | |
| PDE Unit tests and specified that the results should be published to | |
| a listener using the port identified by the pde.test.port property | |
| (see Label 3 above).<br> | |
| Note: that the list of test classes needs to be specified for the | |
| test run, this can easily be automatically generated.</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_6.gif" | |
| style="width: 24px; height: 13px;" align="middle"></td> | |
| <td style="width: 90%;">After the PDE test run the test | |
| installation of Eclipse is cleaned up by deleting all the deployed | |
| plug-ins from the plugins directory.</td> | |
| </tr> | |
| <tr> | |
| <td style="width: 10%;"><img src="images/tag_7.gif" | |
| align="middle" height="13" width="24"></td> | |
| <td style="width: 90%;">Copy the test results to a directory for | |
| processing by the Junitreport Ant task.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h2><a name="PDETestExampleProjects.zip_Contents"></a>PDETestExampleProjects-3.3.zip | |
| Contents</h2> | |
| <p>The ZIP file contains 3 separate plug-ins (each with their own Ant | |
| build.xml file) and an overall Ant build.xml file that coordinates the | |
| build and test of the 3 plug-ins.</p> | |
| <table cellpadding="2" cellspacing="2"> | |
| <tbody> | |
| <tr> | |
| <th>Contents</th> | |
| <th>Type</th> | |
| <th>Description</th> | |
| </tr> | |
| <tr> | |
| <td>pde.test.utils</td> | |
| <td>Plug-in</td> | |
| <td>Provides the PDE test utilities used by Ant to run the PDE | |
| unit tests, including the following classes:<br> | |
| <ul> | |
| <li>pde.test.utils.PDETestListener</li> | |
| <li>pde.test.utils.PDETestPortLocator</li> | |
| <li>pde.test.utils.PDETestResultsCollector</li> | |
| </ul> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>PhoneBookExample</td> | |
| <td>Plug-in</td> | |
| <td>This is the main Eclipse plug-in PhoneBook example | |
| application, including the following classes:<br> | |
| <ul> | |
| <li>phonebookexample.PhoneBookExamplePlugin</li> | |
| <li>phonebookexample.actions.PhoneBookAction</li> | |
| <li>phonebookexample.data.PhoneBook</li> | |
| <li>phonebookexample.data.PhoneBookEntry</li> | |
| <li>phonebookexample.dialogs.PhoneBookEditorDialog</li> | |
| <li>phonebookexample.dialogs.PhoneBookEntryEditorDialog</li> | |
| </ul> | |
| <br> | |
| For further details on the example application see <a | |
| href="#Simple_Phonebook_Application">Appendix A</a> below.</td> | |
| </tr> | |
| <tr> | |
| <td>PhoneBookExample-test</td> | |
| <td>Plug-in Fragment</td> | |
| <td>This is the Eclipse plug-in fragment for the PhoneBook plug-in | |
| that contains the PDE unit tests for the PhoneBook GUI, including the | |
| following test classes:<br> | |
| <ul> | |
| <li>phonebookexample.dialogs.PhoneBookEntryEditorDialogTest</li> | |
| </ul> | |
| <br> | |
| For further details on PDE Unit tests for the example application see | |
| <a href="#Example_PDE_Unit_Tests">Appendix B</a> below.</td> | |
| </tr> | |
| <tr> | |
| <td>build.xml</td> | |
| <td>Ant build file</td> | |
| <td>Overall Ant build file, that provides targets that | |
| coordinates the building and testing of the 3 plug-ins</td> | |
| </tr> | |
| <tr> | |
| <td>readme.txt</td> | |
| <td>Readme file</td> | |
| <td>Provide basic information on how to run the example</td> | |
| </tr> | |
| <tr> | |
| <td>project.properties</td> | |
| <td>properties file</td> | |
| <td>Specifies the target Eclipse and pde.test.utils versions | |
| used in this project.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h2><a name="PDE_Test_Utilities"></a>PDE Test Utilities | |
| (pde.test.utils)</h2> | |
| <p>This plug-in contains a set of utilities that help automate the | |
| running and monitoring of PDE Unit tests. </p> | |
| <h3><a name="PDETestPortLocator"></a>PDETestPortLocator</h3> | |
| <p>This class is responsible for discovering the next available port | |
| on a system, creating a properties file called <i>pde_test_port.properties</i> | |
| and writing a property called <i>pde.test.port</i> into the file and | |
| setting it to the value of the next available port. This port is then | |
| used by the Eclipse test runner process when publishing the progress and | |
| results of tests and the PDE test listener process listens on the port | |
| and processes the test results. </p> | |
| <h3><a name="PDETestListener"></a>PDETestListener</h3> | |
| <p>This class is responsible for listening on a specified port as an | |
| Eclipse test listener and outputting the results of the test | |
| run in the same XML format that is output by the Ant <a | |
| target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junit.html">junit</a> | |
| task. The test result XML files can then be | |
| converted into an easily interpreted HTML JUnit report by the Ant <a | |
| target="_blank" | |
| href="http://ant.apache.org/manual/OptionalTasks/junitreport.html">junitreport</a> | |
| task.</p> | |
| <h3><a name="PDETestResultsCollector"></a>PDETestResultsCollector</h3> | |
| <p>This class is responsible for starting the PDETestListener on the | |
| specified port, for a PDE test run. The PDETestResultsCollector | |
| process takes 2 parameters as follows: </p> | |
| <ol> | |
| <li>PDE Test suite name - this is just a string that identifies | |
| the PDE test suite name - usually the plug-in fragment name, e.g. | |
| PhoneBookExample-test in our example code.</li> | |
| <li>port number - specifies the port that the PDE test | |
| runner process uses to publish PDE test progress and results, the PDE | |
| test listener process listens on the port to process the test results.</li> | |
| </ol> | |
| <h2>Conclusion</h2> | |
| <p>As stated in the introduction, there are several options available | |
| for automating PDE tests; some more complex than others. The technique | |
| detailed in this article provides another choice for build system | |
| engineers. It delivers the following benefits: | |
| </p> | |
| <ol> | |
| <li>Allows you to run your PDE Tests from the command line</li> | |
| <li>Allows you to collect the PDE Tests results in a format that | |
| can be easily interpreted (i.e. Junitreport format)</li> | |
| <li>Allows you to integrate PDE Tests into any Ant-based build | |
| system</li> | |
| </ol> | |
| <h2><a name="Simple_Phonebook_Application"></a>Appendix A: Example | |
| Application - Simple Phonebook Application (PhoneBookExample)</h2> | |
| <p>The example application is a simple PhoneBook | |
| application and some simple GUI PDE Tests. The aim of this article is | |
| to show how you can integrate your PDE unit tests into an Ant build. In | |
| consideration of this, the | |
| example application and it's PDE unit tests have been deliberately kept | |
| as simple as possible. </p> | |
| <p>The PhoneBook application is simple tool to store names and their | |
| associated phone numbers. The application adds a simple "Phone" menu | |
| item to the main menu as follows:</p> | |
| <p><img src="images/phonebook_menu.gif" | |
| style="width: 718px; height: 350px;" alt="Image of phonebook menu item"> | |
| </p> | |
| <p>Clicking on "Edit Phone Book" menu item causes the Edit PhoneBook | |
| Dialog to be displayed:</p> | |
| <p><img src="images/phonebook_editor.gif" | |
| style="width: 524px; height: 309px;" | |
| alt="Image of PhoneBook editor dialog"></p> | |
| <p>Clicking on "New" button causes the Edit PhoneBook Entry Dialog | |
| to be displayed:</p> | |
| <p><img src="images/phonebook_entry_editor.gif" | |
| style="width: 523px; height: 298px;" | |
| alt="Image of PhoneBook Entry Editor dialog"></p> | |
| <h3><a name="Making_GUI_Classes_testable_using"></a>Making GUI | |
| Classes testable using package protection</h3> | |
| <p><img src="images/tip.gif" alt=""> Throughout the simple GUI | |
| examples provided here, a deliberate style of making all | |
| fields in GUI classes <em>package protected</em> has been followed. Making the | |
| fields package protected allows the unit tests to access the GUI | |
| components during a test run.</p> | |
| <p>For example, the local variables <img src="images/tag_1.gif" | |
| align="middle" height="13" width="24"> are all package protected.</p> | |
| <pre>package phonebookexample.dialogs;<br>...<br>public class PhoneBookEntryEditorDialog extends TitleAreaDialog { | |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> PhoneBookEntry phoneBookEntry; | |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Composite phoneBookEntryComposite; | |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Text nameText; | |
| <img src="images/tag_1.gif" align="middle" height="13" width="24"> Text numberText; | |
| ... | |
| }</pre> | |
| <p>Note that this is not an ideal solution for making your GUI | |
| classes testable, but it is simple and it works.</p> | |
| <h2><a name="Example_PDE_Unit_Tests"></a>Appendix B: Example PDE | |
| Unit Tests (PhoneBookExample-test)</h2> | |
| <p>There is just a single PDE JUnit test class provided in the example | |
| (PhoneBookEntryEditorDialogTest) and most of the tests there are pretty | |
| straightforward, but there are a few tricks or techniques that do | |
| require some further explanation. </p> | |
| <h3>Accessing the active shell</h3> | |
| <p><img src="images/tip.gif" alt=""> The active shell for your | |
| GUI under test can be accessed using the following:</p> | |
| <pre> PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()</pre> | |
| <h3>Extending the GUI class under test to access protected methods</h3> | |
| <p><img src="images/tip.gif" alt=""> This is a simple | |
| technique to allow your test to gain access to protected methods in the | |
| class under test or one of it's super classes. In the example the local | |
| class MyPhoneBookEntryEditorDialog extends the class under test | |
| PhoneBookEntryEditorDialog so that the tests can access the, | |
| getButton(int id), buttonPressed() and cancellPressed() methods these | |
| methods can then be used in the tests.</p> | |
| <pre>class MyPhoneBookEntryEditorDialog extends PhoneBookEntryEditorDialog { | |
| public MyPhoneBookEntryEditorDialog(Shell parent, PhoneBookEntry phoneBookEntry) { | |
| super(parent, phoneBookEntry); | |
| } | |
| @Override | |
| protected void buttonPressed(int buttonId) { | |
| super.buttonPressed(buttonId); | |
| } | |
| @Override | |
| protected void cancelPressed() { | |
| super.cancelPressed(); | |
| } | |
| @Override | |
| protected Button getButton(int id) { | |
| return super.getButton(id); | |
| } | |
| }</pre> | |
| <h3>Making GUI Classes testable using package protection</h3> | |
| <p>Making the local variables package protected allows the unit | |
| tests to access the GUI components during the rest run (see the <a | |
| href="article.html#Making_GUI_Classes_testable_using">earlier | |
| section</a> for further details).</p> | |
| <h2>Acknowledgements</h2> | |
| <p>This technique for automating PDE unit tests was first developed | |
| by David Bosschaert at IONA Technologies.</p> | |
| <p>I'd like to thank Edwin Dankert and Sean Boylan, both of Duolog | |
| Technologies who helped refine the technique and the article. | |
| I'd also like to thank the reviewers Edwin Dankert, David | |
| Bosschaert, Andrew Niefer of IBM and Wayne Beaton of Eclipse | |
| for taking the time to read the article and provide all the excellent | |
| feedback.</p> | |
| </div> | |
| <div class="notices"> | |
| <h3>Legal Notices</h3> | |
| <p>Java and all Java-based trademarks and logos are trademarks or | |
| registered trademarks of Sun Microsystems, Inc. in the United States, | |
| other countries, or both.</p> | |
| </div> | |
| </body> | |
| </html> |