blob: aae628f7f231d4ac74ac642920fc626f6f0f57ae [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>3.3&nbsp;Testing Highlights</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="A Guide to the GreenPages Sample"><link rel="up" href="ch03.html" title="3.&nbsp;GreenPages Highlights"><link rel="prev" href="ch03s02.html" title="3.2&nbsp;Middle Tier Highlights"><link rel="next" href="ch03s04.html" title="3.4&nbsp;Automated Build Highlights"><!--Begin Google Analytics code--><script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
var pageTracker = _gat._getTracker("UA-2728886-3");
pageTracker._setDomainName("none");
pageTracker._setAllowLinker(true);
pageTracker._trackPageview();
</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3.3&nbsp;Testing Highlights</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s02.html">Prev</a>&nbsp;</td><th width="60%" align="center">3.&nbsp;GreenPages Highlights</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ch03s04.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="highlights.testing"></a>3.3&nbsp;Testing Highlights</h2></div></div></div><p>
Testing is one of the most important aspects of software development. Without testing it would be difficult
to determine if a piece of code worked properly, changes would have undetected consequences, and the quality
of the code would generally be lower.
</p><p>
There are two major categories of testing generally recognised today: unit testing
and integration testing. In the context of the
GreenPages application, <span class="emphasis"><em>unit testing</em></span> means testing a single class in isolation from other application code.
This type of testing does not change at all when developing for Virgo and so the GreenPages sample does not include any unit tests.
</p><p>
In our application <span class="emphasis"><em>integration testing</em></span> means testing an application or
portion of an application with other code. This kind of testing does look a bit different when developing
for Virgo. In most cases Virgo applications are made up of small bundles that consume services through the
OSGi registry. The following highlights show how a single bundle and the entire GreenPages
application can be integration tested outside the OSGi container.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1109"></a>Single Bundle Integration Test</h3></div></div></div><p>
One of the most common forms of integration testing is ensuring that the object relational mapping in an
application is working properly. This kind of testing typically uses a data access object to retrieve data
from a live database.
</p><p>
The <code class="classname">greenpages.jpa.JpaDirectorySpringContextTests</code> class in the
<code class="filename">src/test/java</code> source folder of the <code class="literal">greenpages.jpa</code> project
is such a test case for the <code class="classname">JpaDirectory</code> class.
The class uses JUnit to run the test and tests that a directory search completes
correctly. Rather than instantiate
this class directly in the test, the Spring Test Framework is used to instantiate and inject a
<code class="classname">JpaDirectory</code> bean defined in the <code class="literal">META-INF/spring/module-context.xml</code> file.
Spring Test Framework declarations are used to run the test with the
<code class="classname">SpringJunit4ClassRunner</code> and configure the test with the files
<code class="literal">classpath:/META-INF/spring/module-context.xml</code> and
<code class="literal">classpath:/META-INF/spring/test-context.xml</code>:
</p><pre class="programlisting">@RunWith(SpringJUnit4ClassRunner.<span class="hl-keyword">class</span>)
@ContextConfiguration(locations = { <span class="hl-string">"classpath:/META-INF/spring/module-context.xml"</span>,
<span class="hl-string">"classpath:/META-INF/spring/test-context.xml"</span> })
@TestExecutionListeners(value = DependencyInjectionTestExecutionListener.<span class="hl-keyword">class</span>)
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> JpaDirectorySpringContextTests {
@Autowired
<span class="hl-keyword">private</span> Directory directory;
@Test
<span class="hl-keyword">public</span> <span class="hl-keyword">void</span> search() {
</pre><p>
</p><p>
The <code class="filename">test-context.xml</code> file in the
<code class="literal">src/test/resources/META-INF/spring</code> folder defines two beans: a
<code class="interfacename">DataSource</code> and a <code class="classname">TestDataPopulator</code>:
</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"dataSource"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.apache.commons.dbcp.BasicDataSource"</span>
<span class="hl-attribute">p:driverClassName</span>=<span class="hl-value">"org.h2.Driver"</span> <span class="hl-attribute">p:url</span>=<span class="hl-value">"jdbc:h2:.~/greenpages-db/greenpages"</span>
<span class="hl-attribute">p:username</span>=<span class="hl-value">"greenpages"</span> <span class="hl-attribute">p:password</span>=<span class="hl-value">"pass"</span> <span class="hl-attribute">init-method</span>=<span class="hl-value">"createDataSource"</span>
<span class="hl-attribute">destroy-method</span>=<span class="hl-value">"close"</span> /&gt;
&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"greenpages.jpa.TestDataPopulator"</span> <span class="hl-attribute">init-method</span>=<span class="hl-value">"populate"</span>&gt;
&lt;<span class="hl-tag">constructor-arg</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"dataSource"</span> /&gt;
&lt;<span class="hl-tag">constructor-arg</span> <span class="hl-attribute">value</span>=<span class="hl-value">"file:../../db/db.sql"</span> /&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
</pre><p>
These two beans provide a test <code class="interfacename">DataSource</code> complete with test data.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="d0e1166"></a>Multi Bundle Integration Test</h3></div></div></div><p>
The single bundle integration test provides a test implementation of its <code class="interfacename">DataSource</code> dependency.
When integration testing, it is often a good idea to test the entire application outside of the container.
GreenPages includes such a test case for the
entire application, starting with the <code class="classname">GreenPagesController</code> class
and descending all the way to a database.
Although it would be sensible for this test case to reside in a separate test bundle,
one of the bundles involved is a web bundle and so it is more convenient to locate the test case in the <code class="literal">greenpages.web</code> project.
</p><p>
Since this test case will be testing the GreenPages application as a whole, it needs to depend on the bundles
that make up the application.
The <code class="filename">pom.xml</code> file for the <code class="literal">greenpages.web</code>
project contains a dependency declaration for the <code class="literal">greenpages.jpa</code> bundle:
</p><pre class="programlisting">&lt;<span class="hl-tag">dependency</span>&gt;
&lt;<span class="hl-tag">groupId</span>&gt;com.springsource.dmserver&lt;<span class="hl-tag">/groupId</span>&gt;
&lt;<span class="hl-tag">artifactId</span>&gt;greenpages.jpa&lt;<span class="hl-tag">/artifactId</span>&gt;
&lt;<span class="hl-tag">version</span>&gt;${project.version}&lt;<span class="hl-tag">/version</span>&gt;
&lt;<span class="hl-tag">scope</span>&gt;test&lt;<span class="hl-tag">/scope</span>&gt;
&lt;<span class="hl-tag">/dependency</span>&gt;
</pre><p>
Note that the scope of the dependency is <code class="literal">test</code>.
</p><p>
The <code class="classname">GreenPagesSpringContextTests</code> class in the
<code class="literal">src/test/java/greenpages/web</code> folder
contains Spring Test Framework declarations to run the test with the
<code class="classname">SpringJunit4ClassRunner</code> and configure the test with the files
<code class="literal">classpath*:/META-INF/spring/module-context.xml</code>,
<code class="literal">file:src/main/webapp/WEB-INF/greenpages-servlet.xml</code>, and
<code class="literal">classpath:/META-INF/spring/test-context.xml</code>. Note the use of
<code class="literal">classpath*:</code> which causes Spring to look for files that match the specified path in all of the bundles on the classpath.
</p><pre class="programlisting">@RunWith(SpringJUnit4ClassRunner.<span class="hl-keyword">class</span>)
@ContextConfiguration(locations = {
<span class="hl-string">"classpath*:/META-INF/spring/module-context.xml"</span>,
<span class="hl-string">"file:src/main/webapp/WEB-INF/greenpages-servlet.xml"</span>,
<span class="hl-string">"classpath:/META-INF/spring/test-context.xml"</span> })
@TestExecutionListeners(value = DependencyInjectionTestExecutionListener.<span class="hl-keyword">class</span>)
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> GreenPagesSpringContextTests {
</pre><p>
</p></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
_lf_cid = "LF_48be82fa";
_lf_remora();
</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s02.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ch03s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.2&nbsp;Middle Tier Highlights&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;3.4&nbsp;Automated Build Highlights</td></tr></table></div></body></html>