incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Sling Testing Tools
Date Wed, 23 Mar 2011 13:34:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+Testing+Tools">Sling
Testing Tools</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bdelacretaz">Bertrand
Delacretaz</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        OSGi services injection<br />
    </div>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >To supply tests from your own bundles,
simply export the tests classes and add the {{Sling-Test-Regexp}} header to the bundle so
that the Sling JUnit core services register them as tests. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h3.
Injection of OSGi services <br>The {{@TestReference}} annotation is used to inject OSGi
services in tests that are executed server side.The {{BundleContext}} can also be injected
in this way, see the [OsgiAwareTest|http://svn.apache.org/repos/asf/sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareTest.java]
for an example. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. Curl examples <br>Here&#39;s
an example executing a few tests using curl: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="SlingTestingTools-SlingTestingTools"></a>Sling Testing
Tools</h1>
<p>Sling provides a number of testing tools to support the following use cases:</p>
<ul>
	<li>Run JUnit tests contributed by OSGi bundles in an OSGi system. This does not require
Sling and should work in other OSGi  environments.</li>
	<li>Run scriptable tests in a Sling instance, using any supported scripting language.</li>
	<li>Run integration tests via HTTP against a Sling instance that is started during
the Maven build cycle, or independently.</li>
</ul>


<p>This page describes those tools, and points to the bundles that implement them.</p>

<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/samples/integration-tests"
class="external-link" rel="nofollow">testing/samples/integration-tests</a> module
demonstrates these tools, and is also meant as a sample project to show how to run integration
tests for Sling-based applications.</p>

<p>The main Sling integration tests at <a href="https://svn.apache.org/repos/asf/sling/trunk/launchpad/integration-tests"
class="external-link" rel="nofollow">launchpad/integration-tests</a> were created
before this testing framework, and do not use it yet (as of March 2011). The new testing tools
are simpler to use, but the "old" tests (all 400 of them as I write this) fulfill their validation
role for testing Sling itself, there's no real need to modify them to use the new tools.</p>

<h1><a name="SlingTestingTools-ServersideJUnittestscontributedbybundles"></a>Server-side
JUnit tests contributed by bundles</h1>
<p>The services provided by the <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/junit/core"
class="external-link" rel="nofollow">org.apache.sling.junit.core</a> bundle allow
bundles to register JUnit tests, which are executed server-side by the JUnitServlet registered
by default at <tt>/system/sling/junit</tt>. This bundle is not dependent on Sling,
it should work in other OSGi environments.</p>

<div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/forbidden.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>JUnit servlet
security</b><br />Note that the JUnitServlet does not require authentication,
so it would allow any client to run tests. The servlet can be disabled by configuration if
needed, but in general the <tt>/system</tt> path should not be accessible to website
visitors anyway.</td></tr></table></div>

<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/warning.gif" width="16" height="16"
align="absmiddle" alt="" border="0"></td><td><b>SlingJUnitServlet</b><br
/>For tighter integration with Sling, the alternate <tt>SlingJUnitServlet</tt>
is registered with the <tt>sling/junit/testing</tt> resource type and <tt>.junit</tt>
selector, if the bundle is running in a Sling system. Using this servlet instead of the plain
JUnitServlet also allows Sling authentication to be used for running the tests, and the standard
Sling request processing is used, including servlet filters for example.</td></tr></table></div>

<p>To try the JUnitServlet interactively, install the <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/samples/sample-tests"
class="external-link" rel="nofollow">org.apache.sling.testing.samples.sampletests</a>
bundle.</p>

<p>This bundle contains a number of test classes, which are registered with the <tt>org.apache.sling.junit.core</tt>
services by way of the <tt>Sling-Test-Regexp=.*Test</tt> bundle header, defined
in the bundle's <tt>pom.xml</tt>. The JUnit core services use this regular expression
to select which classes of the test bundle should be executed as JUnit tests.</p>

<p>To list the available tests, open <a href="http://localhost:8080/system/sling/junit/"
class="external-link" rel="nofollow">http://localhost:8080/system/sling/junit/</a>
. The servlet shows available tests, and allows you to execute them via a POST request.</p>

<p>Adding a path allows you to select a specific subset of tests, as in <a href="http://localhost:8080/system/sling/junit/org.apache.sling.junit.remote.html"
class="external-link" rel="nofollow">http://localhost:8080/system/sling/junit/org.apache.sling.junit.remote.html</a>
- the example integration tests described below use this to selectively execute server-side
tests. The JUnitServlet provides various output formats, including in particular JSON, see
<a href="http://localhost:8080/system/sling/junit/.json" class="external-link" rel="nofollow">http://localhost:8080/system/sling/junit/.json</a>
for example.</p>

<p>To supply tests from your own bundles, simply export the tests classes and add the
<tt>Sling-Test-Regexp</tt> header to the bundle so that the Sling JUnit core services
register them as tests.</p>

<h3><a name="SlingTestingTools-InjectionofOSGiservices"></a>Injection of
OSGi services</h3>
<p>The <tt>@TestReference</tt> annotation is used to inject OSGi services
in tests that are executed server side.The <tt>BundleContext</tt> can also be
injected in this way, see the <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/samples/sample-tests/src/main/java/org/apache/sling/testing/samples/sampletests/OsgiAwareTest.java"
class="external-link" rel="nofollow">OsgiAwareTest</a> for an example.</p>

<h2><a name="SlingTestingTools-Curlexamples"></a>Curl examples</h2>
<p>Here's an example executing a few tests using curl:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Running tests with curl</b></div><div
class="codeContent panelContent">
<pre class="code-java">
$ curl -X POST http:<span class="code-comment">//localhost:8080/system/sling/junit/org.apache.sling.testing.samples.sampletests.JUnit.json
</span>[{
    <span class="code-quote">"INFO_TYPE"</span>: <span class="code-quote">"test"</span>,
    <span class="code-quote">"description"</span>: <span class="code-quote">"testPasses(org.apache.sling.testing.samples.sampletests.JUnit3Test)"</span>
  },{
    <span class="code-quote">"INFO_TYPE"</span>: <span class="code-quote">"test"</span>,
    <span class="code-quote">"description"</span>: <span class="code-quote">"testPasses(org.apache.sling.testing.samples.sampletests.JUnit4Test)"</span>
  },{
    <span class="code-quote">"INFO_TYPE"</span>: <span class="code-quote">"test"</span>,
    <span class="code-quote">"description"</span>: <span class="code-quote">"testRequiresBefore(org.apache.sling.testing.samples.sampletests.JUnit4Test)"</span>
  }
]
</pre>
</div></div>

<p>And another example with a test that fails:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Failing tests with curl</b></div><div
class="codeContent panelContent">
<pre class="code-java">
$ curl -X POST http:<span class="code-comment">//localhost:8080/system/sling/junit/org.apache.sling.testing.samples.failingtests.JUnit4FailingTest.json
</span>[continuous integration|SLINGxSITE:Project Information]
</pre>
</div></div>

<h1><a name="SlingTestingTools-Scriptableserversidetests"></a>Scriptable
server-side tests</h1>
<p>If the <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/junit/scriptable"
class="external-link" rel="nofollow">org.apache.sling.junit.scriptable</a> bundle
is active in a Sling system, (in addition to the <tt>org.apache.sling.junit.core</tt>
bundle), scriptable tests can be executed by the <tt>JUnitServlet</tt> according
to the following rules:</p>

<ul>
	<li>A node that has the <tt>sling:Test</tt> mixin is a scriptable test
node.</li>
	<li>For security reasons, scriptable test nodes are only executed as tests if they
are found under <tt>/libs</tt> or <tt>/apps</tt>, or more precisely
under a path that's part of Sling's <tt>ResourceResolver</tt> search path.</li>
	<li>To execute a test, the scriptable tests provider makes an HTTP requests to the
test node's path, with a <tt>.test.txt</tt> selector and extension, and expects
the output to contain only the string <tt>TEST_PASSED</tt>. Empty lines and comment
lines starting with a hash sign (#) are ignored in the output, and other lines are reported
as failures.</li>
</ul>


<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/samples/integration-tests/src/test/java/org/apache/sling/testing/samples/integrationtests/serverside/scriptable/ScriptableTestsTest.java"
class="external-link" rel="nofollow">ScriptableTestsTest</a> class, from the integration
test samples module described below, sets up such a test node and its accompanying script,
and calls the JUnitServlet to execute the test. It can be used as a detailed example of how
this works.</p>

<h1><a name="SlingTestingTools-Integrationtestsexample"></a>Integration
tests example</h1>
<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/samples/integration-tests"
class="external-link" rel="nofollow">testing/samples/integration-tests</a> module
runs some simple integration tests against a Sling Launchpad instance that's setup from scratch
before running the tests.</p>

<p>This module's pom and Java code can be used as examples to setup your own integration
testing modules for Sling-based apps - or for any other runnable jar that provides an http
service.</p>

<p>Besides serving as examples, some of the tests in this module are used to validate
the testing tools. They run as part of the full Sling <a href="/confluence/display/SLINGxSITE/Project+Information"
title="Project Information">continuous integration</a> build, so they're guaranteed
to be correct examples if that build is successful.</p>

<p>The sample uses the <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/tools"
class="external-link" rel="nofollow">testing/tools</a> to make the test code simpler.
See the <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/samples/integration-tests/src/test/java/org/apache/sling/testing/samples/integrationtests/http/OsgiConsoleTest.java"
class="external-link" rel="nofollow">OsgiConsoleTest</a> class for an example of
a test that's very readable and requires no test setup or boilerplate code.</p>

<p>The following steps are executed in the <tt>integration-test</tt> phase
of this module's Maven  build:</p>
<ol>
	<li>A random port number for the Sling server is selected by the Maven build helper
plugin, unless explicitely set (see pom.xml for such options).</li>
	<li>Additional bundles, defined in the module's pom, are downloaded from the Maven
repository in the <tt>target/sling/additional-bundles</tt> folder.</li>
	<li>The first test that inherits from the <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/tools/src/main/java/org/apache/sling/testing/tools/sling/SlingTestBase.java"
class="external-link" rel="nofollow">SlingTestBase</a> class causes the Sling runnable
jar (defined as a dependency in the module's pom) to be started.
	<ol>
		<li>The <tt>SlingTestBase</tt> class waits for the Sling server to be
ready, based on URLs and expected responses defined in the pom.</li>
		<li>The <tt>SlingTestBase</tt> class installs and starts the bundles found
in the <tt>target/sling/additional-bundles</tt> folder.</li>
	</ol>
	</li>
	<li>The test can now either test Sling directly via its http interface, or use the
JUnitServlet to execute server-side tests contributed by bundles or scripts, as described
above.</li>
	<li>The Sling runnable jar is stopped when the test VM exits.</li>
	<li>The test results are reported via the usual Maven mechanisms.</li>
</ol>


<p>If <tt>-DkeepJarRunning</tt> is used on the Maven command line, the Sling
runnable jar does not exit, to allow for running individual tests against this instance, for
example when debugging the tests or the server code. See the pom for details.</p>

<h1><a name="SlingTestingTools-Remotetestexecution"></a>Remote test execution</h1>
<p>The testing tools support two types of remote test execution.</p>

<h2><a name="SlingTestingTools-SlingRemoteTestRunner"></a>SlingRemoteTestRunner</h2>
<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/testrunner/SlingRemoteTestRunner.java"
class="external-link" rel="nofollow">SlingRemoteTestRunner</a> is used to run tests
using the <tt>JUnitServlet</tt> described above. In this case, the client-side
JUnit test only defines which tests to run and some optional assertions. Checking the number
of tests executed, for example, can be useful to make sure all test bundles have been activated
as expected, to avoid ignoring missing test bundles.</p>

<p>See the <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/samples/integration-tests/src/test/java/org/apache/sling/testing/samples/integrationtests/serverside/ServerSideSampleTest.java"
class="external-link" rel="nofollow">ServerSideSampleTest</a> class for an example.</p>

<h2><a name="SlingTestingTools-SlingRemoteExecutionRule"></a>SlingRemoteExecutionRule</h2>
<p>The <a href="http://svn.apache.org/repos/asf/sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/ide/SlingRemoteExecutionRule.java"
class="external-link" rel="nofollow">SlingRemoteExecutionRule</a> is a JUnit Rule
that allows tests to be executed remotely in a Sling instance from an IDE, assuming the test
is available on both sides.</p>

<p>The <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/junit/remote/src/main/java/org/apache/sling/junit/remote/exported/ExampleRemoteTest.java"
class="external-link" rel="nofollow">ExampleRemoteTest</a> class demonstrates this.
To run it from your IDE, set the <tt>sling.remote.test.url</tt> in the IDE to
the URL of the JUnitServlet, like <a href="http://localhost:8080/system/sling/junit" class="external-link"
rel="nofollow">http://localhost:8080/system/sling/junit</a> for example.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+Testing+Tools">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=26116321&revisedVersion=6&originalVersion=5">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Sling+Testing+Tools?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message