[jboss-svn-commits] JBoss Common SVN: r3994 - in arquillian/trunk/doc: reference and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Feb 7 23:43:04 EST 2010
Author: dan.j.allen
Date: 2010-02-07 23:43:04 -0500 (Sun, 07 Feb 2010)
New Revision: 3994
Added:
arquillian/trunk/doc/reference/
arquillian/trunk/doc/reference/pom.xml
arquillian/trunk/doc/reference/src/
arquillian/trunk/doc/reference/src/main/
arquillian/trunk/doc/reference/src/main/docbook/
arquillian/trunk/doc/reference/src/main/docbook/en-US/
arquillian/trunk/doc/reference/src/main/docbook/en-US/author_group.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/book_info.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/containers.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/debugging.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/enrichment.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/examples.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/execution.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/extend.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/gettingstarted.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/images/
arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png
arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.svg
arquillian/trunk/doc/reference/src/main/docbook/en-US/intro.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/master.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/preface.xml
arquillian/trunk/doc/reference/src/main/docbook/en-US/scenarios.xml
Log:
first draft of user guide
Property changes on: arquillian/trunk/doc/reference
___________________________________________________________________
Name: svn:ignore
+ target
Added: arquillian/trunk/doc/reference/pom.xml
===================================================================
--- arquillian/trunk/doc/reference/pom.xml (rev 0)
+++ arquillian/trunk/doc/reference/pom.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,92 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <!-- Parent -->
+ <parent>
+ <groupId>org.jboss.arquillian</groupId>
+ <artifactId>arquillian-build</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../build/pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>arquillian-reference-guide</artifactId>
+ <packaging>jdocbook</packaging>
+ <name>Arquillian Reference Guide</name>
+
+ <properties>
+ <mpjdocbook.version>2.2.0</mpjdocbook.version>
+ <pdf.name>${project.artifactId}.pdf</pdf.name>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-jdocbook-plugin</artifactId>
+ <version>${mpjdocbook.version}</version>
+ <extensions>true</extensions>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jbossorg-docbook-xslt</artifactId>
+ <version>1.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss</groupId>
+ <artifactId>jbossorg-jdocbook-style</artifactId>
+ <version>1.1.0</version>
+ <type>jdocbook-style</type>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <sourceDocumentName>master.xml</sourceDocumentName>
+ <masterTranslation>en-US</masterTranslation>
+ <imageResource>
+ <directory>${pom.basedir}/src/main/docbook/en-US</directory>
+ <includes>
+ <include>images/*.png</include>
+ <include>images/*.jpg</include>
+ </includes>
+ </imageResource>
+ <formats>
+ <format>
+ <formatName>pdf</formatName>
+ <stylesheetResource>classpath://xslt/org/jboss/pdf.xsl</stylesheetResource>
+ <finalName>${pdf.name}</finalName>
+ </format>
+ <format>
+ <formatName>html</formatName>
+ <stylesheetResource>classpath://xslt/org/jboss/xhtml.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ <format>
+ <formatName>html_single</formatName>
+ <stylesheetResource>classpath://xslt/org/jboss/xhtml-single.xsl</stylesheetResource>
+ <finalName>index.html</finalName>
+ </format>
+ </formats>
+ <options>
+ <xincludeSupported>true</xincludeSupported>
+ <xmlTransformerType>saxon</xmlTransformerType>
+ <docbookVersion>1.72.0</docbookVersion>
+ <transformerParameters>
+ <property>
+ <name>javax.xml.parsers.DocumentBuilderFactory</name>
+ <value>org.apache.xerces.jaxp.DocumentBuilderFactoryImpl</value>
+ </property>
+ <property>
+ <name>javax.xml.parsers.SAXParserFactory</name>
+ <value>org.apache.xerces.jaxp.SAXParserFactoryImpl</value>
+ </property>
+ </transformerParameters>
+ <localeSeparator>-</localeSeparator>
+ </options>
+ </configuration>
+
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/author_group.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/author_group.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/author_group.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<authorgroup>
+ <author>
+ <firstname>Aslak</firstname>
+ <surname>Knutsen</surname>
+ <email>aslak at conduct.no</email>
+ </author>
+ <author>
+ <firstname>Pete</firstname>
+ <surname>Muir</surname>
+ </author>
+ <author>
+ <firstname>Andrew</firstname>
+ <surname>Rubinger</surname>
+ </author>
+ <author>
+ <firstname>Dan</firstname>
+ <surname>Allen</surname>
+ <email>dan.j.allen at gmail.com</email>
+ </author>
+</authorgroup>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/book_info.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/book_info.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/book_info.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+
+<bookinfo>
+ <title>Arquillian: An integration testing framework for Java EE</title>
+ <subtitle>Reference Guide</subtitle>
+
+ <xi:include href="author_group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</bookinfo>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/containers.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/containers.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/containers.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="containers">
+ <title>Target containers</title>
+
+ <para>
+ Arquillian's power is not only in its ease of use, but also in its flexibility. Good integration testing is not
+ just about testing in <emphasis>any</emphasis> container, but rather testing in the container you are targeting.
+ It's all too easy to kid ourselves by tweaking our components to run in a specialized testing container, only to
+ realize that certain assumptions don't apply in the real environment and ultimately the components fail when it
+ comes time to deploy for real.
+ </para>
+
+ <para>
+ Arquillian supports a variety of target containers out of the box, which will be covered in this chapter. If the
+ container you are using isn't supported, Arquillian makes it very easy to plug in your own implementation.
+ </para>
+
+ <section>
+ <title>Container varieties</title>
+
+ <para>
+ There are three types of target containers that you can use to run your Arquillian tests:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>A standalone (remote) container</para>
+ </listitem>
+ <listitem>
+ <para>An embedded container</para>
+ </listitem>
+ <listitem>
+ <para>A Java SE bean container</para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ Arquillian provides SPIs that handle each of the tasks involved in controlling the runtime environment,
+ executing the tests and aggregating the results. So in theory, you can support just about any environment that
+ can be controlled with the set of hooks you are given.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Supported containers</title>
+
+ <para>
+ The implementations provided so far are shown in the table below. Also listed is the artifactId of the JAR that
+ provides the implementation.
+ </para>
+
+ <table frame="all">
+ <title>Target containers supported by Arquillian</title>
+ <tgroup cols="3">
+ <colspec colnum="1" colname="name" colwidth="1*"/>
+ <colspec colnum="2" colname="type" colwidth="1*"/>
+ <colspec colnum="3" colname="artifactId" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Container name</entry>
+ <entry>Container type</entry>
+ <entry>artifactId</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>JBoss AS 5.1</entry>
+ <entry>standalone</entry>
+ <entry>arquillian-jboss-remote-51</entry>
+ </row>
+ <row>
+ <entry>JBoss AS 6.0</entry>
+ <entry>standalone container</entry>
+ <entry>arquillian-jboss-remote-60</entry>
+ </row>
+ <row>
+ <entry>JBoss Embedded AS</entry>
+ <entry>embedded container</entry>
+ <entry>arquillian-jboss-embedded</entry>
+ </row>
+ <row>
+ <entry>Weld SE</entry>
+ <entry>Java SE bean container</entry>
+ <entry>arquillian-weld-embedded</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Support for other containers is planned, including GlassFish V3, Embedded GlassFish V3, Tomcat and Jetty. We
+ don't plan to provide implementations for Spring or Guice, but we welcome a contribution from the community,
+ because it's certainly possible.
+ </para>
+
+ </section>
+
+ <!-- FIXME: this chapter may not be complete -->
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/debugging.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/debugging.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/debugging.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="debugging">
+
+ <title>Debugging remote tests</title>
+
+ <para>
+ While Arquillian tests can be easily executing using existing IDE, Ant and Maven test plugins, debugging tests are
+ not as straightforward (but by no means difficult). The extra steps documented in this chapter are only relevant
+ for tests which are not executed in the same JVM as the test runner. These steps to not apply to tests that are
+ run in a local bean container (e.g., Weld SE), which can be debugged just like any other unit test.
+ </para>
+
+ <para>
+ We'll assume in this chapter that you are already using Eclipse and you already have the test plugin installed for
+ the testing framework you are using (JUnit or TestNG).
+ </para>
+
+ <section>
+ <title>Debugging in Eclipse</title>
+
+ <para>
+ If you set a break point and execute the test in debug mode using a remote container, your break point won't be
+ hit. That's because when you debug an in-container test, you're actually debugging the container. The test
+ runner and the test are executing in different JVMs. Therefore, to setup debugging, you must first attach the
+ IDE debugger to the container, then execute the test in debug mode (i.e., debug as test). That puts the
+ debugger on both sides of the fence, so to speak, and allows the break point to be discovered.
+ </para>
+
+ <para>
+ Let's begin by looking at how to attach the IDE debugger to the container. This isn't specific to Arquillian.
+ It's the same setup you would use to debug a deployed application.
+ </para>
+
+ <section>
+ <title>Attaching the IDE debugger to the container</title>
+
+ <para>
+ There are two ways to attach the IDE debugger to the container. You can either start the container in debug
+ mode from within the IDE, or you can attach the debugger over a socket connection to a standalone container
+ running with JPDA enabled.
+ </para>
+
+ <para>
+ The Eclipse Server Tools, a subproject of the Eclipse Web Tools Project (WTP), has support for launching most
+ major application servers, including JBoss AS 5. However, if you are using JBoss AS, you should consider using
+ JBoss Tools instead, which offers tighter integration with JBoss technologies. See either the <ulink
+ src="http://www.eclipse.org/webtools/server/server.php">Server Tools documentation</ulink> or the <ulink
+ src="http://docs.jboss.org/tools/3.0.1.GA/en/as/html/index.html">JBoss Tools documentation</ulink> for
+ instructions on how to setup a container and start it in debug mode.
+ </para>
+
+ <para>
+ <!-- TODO migration the documentation from this blog entry into this guide -->
+ See <ulink
+ src="http://maverikpro.wordpress.com/2007/11/26/remote-debug-a-web-application-using-eclipse">this blog
+ entry</ulink> to learn how to start JBoss AS with JPDA enabled and how to get the Eclipse debugger to
+ connect to the remote process.
+ </para>
+
+ <section>
+ <title>Starting JBoss AS in debug mode</title>
+
+ <para>
+ If you are using JBoss AS, the quickest way to setup debug mode is to add the following line to the end
+ of $JBOSS_AS_HOME/bin/run.conf (Unix/Linux):
+ </para>
+
+ <programlisting><![CDATA[JAVA_OPTS="$JAVA_OPTS
+ -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"]]></programlisting>
+
+ <para>
+ or before the line :JAVA_OPTS_SET in $JBOSS_AS_HOME/bin/run.conf.bat (Windows)
+ </para>
+
+ <programlisting><![CDATA[set JAVA_OPTS="%JAVA_OPTS% -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"]]></programlisting>
+
+ <para>
+ Keep in mind your container will always run with debug mode enabled after making this change. You might
+ want to consider putting some logic in the run.conf* file.
+ </para>
+
+ </section>
+ </section>
+
+ <section>
+ <title>Launching the test in debug mode</title>
+
+ <para>
+ Once Eclipse is debugging the container, you can set a breakpoint in the test and debug it just like a unit
+ test. Let's give it a try.
+ </para>
+
+ <para>
+ Open an Arquillian test in the Java editor, right click in the editor view, and select Debug As > TestNG (or
+ JUnit) Test. When the IDE hits the breakpoint, it halts the JVM thread of the container rather than the
+ thread that launched the test. You are now debugging remotely.
+ </para>
+ </section>
+
+ <section>
+ <title>Stepping into external libraries</title>
+
+ <para>
+ If you plan to step into a class in an external library (code outside of your application), you must ensure
+ that the source is properly associated with the library. Below are the steps to follow to associate the
+ source of a library with the debug configuration:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>Select the Run > Debug Configurations... menu from the main menubar</para>
+ </listitem>
+ <listitem>
+ <para>Select the name of the test class in the TestNG (or JUnit) category</para>
+ </listitem>
+ <listitem>
+ <para>Select the Source tab</para>
+ </listitem>
+ <listitem>
+ <para>Click the Add... button on the right</para>
+ </listitem>
+ <listitem>
+ <para>Select Java Project</para>
+ </listitem>
+ <listitem>
+ <para>Check the project the contains the class you want to debug</para>
+ </listitem>
+ <listitem>
+ <para>Click OK on the Project Selection window</para>
+ </listitem>
+ <listitem>
+ <para>Click Close on the Debug Configurations window</para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ You'll have to complete those steps for any test class you are debugging, though you only have to do it once
+ (the debug configuration hangs around indefinitely).
+ </para>
+
+ <tip>
+ <para>
+ These steps may not be necessary if you have a Maven project and the sources for the library are
+ availalbe in the Maven repository.
+ </para>
+ </tip>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>Assertions in remote tests</title>
+
+ <para>
+ The first time you try Arquillian, you may find that assertions that use the Java assert keyword are not
+ working. Keep in mind that the test is not executing the same JVM as the test runner.
+ </para>
+
+ <para>
+ In order for the Java keyword "assert" to work you have to enable assertions (using the -ea flag) in the JVM
+ that is running the container. You may want to consider specifying the package names of your test classes to
+ avoid assertions to be enabled throughout the container's source code.
+ </para>
+
+ <section>
+ <title>Enabling assertions in JBoss AS</title>
+
+ <para>
+ If you are using JBoss AS, the quickest way to setup debug mode is to add the following line to the end of $JBOSS_AS_HOME/bin/run.conf (Unix/Linux):
+ </para>
+
+ <programlisting>JAVA_OPTS="$JAVA_OPTS -ea"</programlisting>
+
+ <para>
+ or before the line :JAVA_OPTS_SET in $JBOSS_AS_HOME/bin/run.conf.bat (Windows)
+ </para>
+
+ <programlisting>set "JAVA_OPTS=%JAVA_OPTS% -ea"</programlisting>
+
+ <para>
+ Keep in mind your container will always run with assertions enabled after making this change. You might want to consider putting some logic in the run.conf* file.
+ </para>
+ </section>
+
+ <para>
+ As an alternative, we recommend using the 'Assert' object that comes with your test framework instead to avoid
+ the whole issue. Also keep in mind that if you use System.out.println statements, the output is going to show
+ up in the log file of the container rather than in the test output.
+ </para>
+
+ </section>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/enrichment.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/enrichment.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/enrichment.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="enrichment">
+ <title>Test enrichment</title>
+
+ <para>
+ When you use a unit testing framework like JUnit or TestNG, your test case lives in a world all its own. That
+ makes integration testing pretty difficult because it means the environment in which the business logic
+ executes must be self-contained within the scope of the test case (whether at the suite, class or method
+ level). The onus of setting up this environment in the test falls on the developer's shoulders.
+ </para>
+
+ <para>
+ With Arquillian, you no longer have to worry about setting up the execution environment because that is all
+ handled for you. The test will either be running in a container or a local CDI environment. But you still
+ need some way to hook your test into this environment.
+ </para>
+
+ <para>
+ A key part of in-container integration testing is getting access the container-managed components that you plan to
+ test. Using the Java new operator to instantiate the business class is not suitable in this testing scenario
+ because it leaves out the declaratives services that get applied to the component at runtime. We want the real
+ deal. Arquillian uses test enrichment to give us access to the real deal. The visable result of test enrichment is
+ injection of container resources and beans directly into the test class.
+ </para>
+
+ <section>
+ <title>Injection into the test case</title>
+
+ <para>
+ Before Arquillian negotiates the execution of the test, it enriches the test class by satisfying injection
+ points specified declaratively using annotations. There are three injection-based enrichers provided by
+ Arquillian out of the box:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>@Resource</literal> - Java EE resource injections</para>
+ </listitem>
+ <listitem>
+ <para><literal>@EJB</literal> - EJB session bean reference injections</para>
+ </listitem>
+ <listitem>
+ <para><literal>@Inject</literal> - CDI injections</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The first two enrichers use JNDI to lookup the instance to inject. The CDI injections are handled by treating
+ the test class as a bean capable of receiving standard CDI injections.
+ </para>
+
+ <para>
+ The <literal>@Resource</literal> annotation gives you access to any object which is available via JNDI. If the
+ <literal>mappedName</literal> attribute is specified, that value is used to perform a lookup in the
+ <literal>InitialContext</literal>. If, instead, the <literal>name</literal> attribute is specified, the name is
+ added to the <literal>java:comp/env/</literal> namespace prefix and passed to the
+ <literal>InitialContext</literal>. If neither the <literal>mappedName</literal> or <literal>name</literal>
+ attributes are specified, the JNDI name is constructed using the <literal>java:comp/env/</literal> prefix
+ followed by the fully qualified bean class name followed by a slash and then the name of the field. The result
+ is passed to the <literal>InitialContext</literal>.
+ </para>
+
+ <para>
+ The <literal>@EJB</literal> annotation performs a JNDI lookup for the EJB session bean reference using the
+ following equation:
+ </para>
+
+ <programlisting>"test/" + unqualified interface name + "Bean/local"</programlisting>
+
+ <para>
+ If a local bean is not found, then the enricher attempts a lookup for a remote bean.
+ </para>
+
+ <programlisting>"test/" + unqualified interface name + "Bean/local"</programlisting>
+
+ <note>
+ <para>
+ At the moment, the lookup for an EJB session reference relies on standard JNDI naming conventions
+ established in Java EE 6.
+ </para>
+ </note>
+
+ <para>
+ In order for CDI injections to work, the test archive defined with ShrinkWrap must be a bean archive. That
+ means adding beans.xml to the META-INF directory. Here's a <literal>@Deployment</literal> method that shows
+ one way to add a beans.xml to the archive:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Deployment
+public static JavaArchive createTestArchive() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClass(NameOfClassUnderTest.class)
+ .addManifestResource(new ByteArrayAsset(new byte[0]), Paths.create("beans.xml"))]]></programlisting>
+
+ <para>
+ In an application that takes full advantage of CDI, you can likely get by only using injections defined with
+ the <literal>@Inject</literal> annotation. Regardless, the other two types of injection come in handy from
+ time-to-time.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Active scopes</title>
+
+ <para>
+ When running your tests the embedded Weld SE container, Arquillian activates scopes as follows:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Application scope - Active during the execution of all tests</para>
+ </listitem>
+ <listitem>
+ <para>Session scope - Active for all methods in a test class</para>
+ </listitem>
+ <listitem>
+ <para>Request scope - Active for a single test method</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Scope control is experimental at this point and may be altered in a future release of Arquillian.
+ </para>
+
+ </section>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/examples.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/examples.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/examples.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="examples">
+ <title>Introductory examples</title>
+
+ <para>
+ The following examples demonstrate the use of Arquillian. The full source code for these examples can be found in
+ the demo and demo-testng modules in the Arquillian source repository or source distribution.
+ </para>
+
+ <section id="examples.ejb">
+ <title>Testing an EJB</title>
+ <para>
+ Here's a JUnit Arquillian test that validates the behavior of the EJB session bean
+ <literal>GreetingManager</literal>. Arquillian looks up an instance of the EJB session bean in the test archive
+ and injects it into the matching field type annotated with <literal>@EJB</literal>.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[import javax.ejb.EJB;
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archives;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+ at RunWith(Arquillian.class)
+public class InjectionTestCase {
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(GreetingManager.class, GreetingManagerBean.class);
+ }
+
+ @EJB
+ private GreetingManager greetingManager;
+
+ @Test
+ public void shouldBeAbleToInjectEJB() throws Exception {
+ String userName = "Earthlings";
+ Assert.assertEquals(Hello " + userName, greetingManager.greet(userName));
+ }
+}]]></programlisting>
+
+ <para>
+ The TestNG version of this test looks identical, except that it extends the
+ <literal>org.jboss.arquillian.testng.Arquillian</literal> class rather than being annotated with
+ <literal>@RunWith</literal>.
+ </para>
+
+ </section>
+
+ <section id="examples.cdi">
+ <title>Testing CDI beans</title>
+ <para>
+ Here's an example of an JUnit Arquillian test that validates the <literal>GreetingManager</literal> EJB session
+ bean again, but this time it's injected into the test class using the <literal>@Inject</literal> annotation.
+ You could also make <literal>GreenManager</literal> a basic managed bean and inject it with the same
+ annotation. The test also verifies that the CDI <literal>BeanManager</literal> instance is available and gets
+ injected. Notice that to inject beans with CDI, you have to add a beans.xml file to the test archive.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archives;
+import org.jboss.shrinkwrap.api.Paths;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.impl.base.asset.ByteArrayAsset;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.acme.ejb.GreetingManager;
+import com.acme.ejb.GreetingManagerBean;
+
+ at RunWith(Arquillian.class)
+public class InjectionTestCase
+{
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(GreetingManager.class, GreetingManagerBean.class)
+ .addManifestResource(new ByteArrayAsset("<beans/>".getBytes()), Paths.create("beans.xml"));
+ }
+
+ @Inject GreetingManager greetingManager;
+
+ @Inject BeanManager beanManager;
+
+ @Test
+ public void shouldBeAbleToInjectCDI() throws Exception {
+ String userName = "Earthlings";
+ Assert.assertNotNull("Should have the injected the CDI bean manager", beanManager);
+ Assert.assertEquals("Hello " + userName, greetingManager.greet(userName));
+ }
+}]]></programlisting>
+ </section>
+
+ <section id="examples.jpa">
+ <title>Testing JPA</title>
+ <para>
+ In order to test JPA, you need both a database and a persistence unit. For the sake of example, let's assume we
+ are going to use the default datasource provided by the container and that the tables will be created
+ automatically when the persistence unit starts up. Here's a persistence unit configuration that satisfies that
+ scenario.
+ </para>
+
+ <programlisting role="XML"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="1.0"
+ xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/persistence
+ http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
+ <persistence-unit name="users" transaction-type="JTA">
+ <provider>org.hibernate.ejb.HibernatePersistence</provider>
+ <jta-data-source>java:/DefaultDS</jta-data-source>
+ <class>com.acme.jpa.User</class>
+ <exclude-unlisted-classes>true</exclude-unlisted-classes>
+ <properties>
+ <property name="hibernate.hbm2ddl.auto" value="create-drop" />
+ <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
+ </properties>
+ </persistence-unit>
+</persistence>]]></programlisting>
+
+ <para>
+ Now let's assume that we have an EJB session bean that injects a persistence context and is responsible for
+ storing and retrieving instances of our domain class, <literal>User</literal>. We've catered it a bit to the
+ test for purpose of demonstration.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @Stateless class UserRepositoryBean implements UserRepository {
+ @PersistenceContext EntityManager em;
+
+ public void storeAndFlush(User u) {
+ em.persist(u);
+ em.flush();
+ }
+
+ public List<User> findByLastName(String lastName) {
+ return em.createQuery("select u from User u where u.lastName = :lastName")
+ .setParameter("lastName", lastName)
+ .getResultList();
+ }
+}]]></programlisting>
+
+ <para>
+ Now let's create an Arquillian test to ensure we can persist and subsequently retrieve a user. Notice that
+ we'll need to add the persistence unit descriptor to the test archive so that the persistence unit is
+ booted in the test archive.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class UserRepositoryTest extends Arquillian {
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(User.class, UserRepository.class, UserRepositoryBean.class)
+ .addManifestResource("test-persistence.xml", Paths.create("persistence.xml"));
+ }
+
+ private static final String FIRST_NAME = "Agent";
+ private static final String LAST_NAME = "Kay";
+
+ @EJB
+ private UserRepository userRepository;
+
+ @Test
+ public void testCanPersistUserObject() {
+ User u = new User(FIRST_NAME, LAST_NAME);
+ userRepository.storeAndFlush(u);
+
+ List<User> users = userRepository.findByLastName(LAST_NAME);
+
+ Assert.assertNotNull(users);
+ Assert.assertTrue(users.size() == 1);
+
+ Assert.assertEquals(users.get(0).getLastName(), LAST_NAME);
+ Assert.assertEquals(users.get(0).getFirstName(), FIRST_NAME);
+ }
+}
+ ]]></programlisting>
+ </section>
+
+ <section id="examples.jms">
+ <title>Testing JMS</title>
+ <!-- Is this the recommended approach for testing JMS/MDB? -->
+ <para>
+ Here's another JUnit Arquillian test that exercises with JMS, something that may have previously seemed very
+ tricky to test. The test uses a utility class <literal>QueueRequestor</literal> to encapsulate the low-level
+ code for sending and receiving a message using a queue.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[import javax.annotation.Resource;
+import javax.jms.*;
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archives;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.acme.ejb.MessageEcho;
+import com.acme.util.jms.QueueRequestor;
+
+ at RunWith(Arquillian.class)
+public class InjectionTestCase {
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(MessageEcho.class, QueueRequestor.class);
+ }
+
+ @Resource(mappedName = "/queue/DLQ")
+ private Queue dlq;
+
+ @Resource(mappedName = "/ConnectionFactory")
+ private ConnectionFactory factory;
+
+ @Test
+ public void shouldBeAbleToSendMessage() throws Exception {
+
+ String messageBody = "ping";
+
+ Connection connection = factory.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ QueueRequestor requestor = new QueueRequestor((QueueSession) session, dlq);
+
+ connection.start();
+
+ Message request = session.createTextMessage(messageBody);
+ Message response = requestor.request(request, 5000);
+
+ Assert.assertEquals("Should have responded with same message", messageBody, ((TextMessage) response).getText());
+ }
+}]]></programlisting>
+ </section>
+
+ <para>
+ That should give you a taste of what Arquillian tests look like. To learn how to setup Arquillian in your
+ application and start developing tests with it, refer to the <xref linkend="gettingstarted"/> chapter.
+ </para>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/execution.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/execution.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/execution.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="execution">
+ <title>Test execution</title>
+
+ <para>
+ This chapter walks through the details of test execution, covering both the remote and local container cases.
+ </para>
+
+ <section>
+ <title>Anatomy of a test</title>
+
+ <para>
+ In both JUnit 4 and TestNG 5, a test case is a class which contains at least one test method. The test method
+ is designated using the <literal>@Test</literal> annotation from the respective framework. An Arquillian test
+ case looks just like a regular JUnit or TestNG test case with two declarative enhancements:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The class contains a static method annotated with <literal>@Deployment</literal> that returns a <literal>JavaArchive</literal></para>
+ </listitem>
+ <listitem>
+ <para>
+ The class is annotated with <literal>@RunWith(Arquillian.class)</literal> (JUnit) or extends
+ <literal>Arquillian</literal> (TestNG)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ With those two modifications in place, the test is recognized by the Arquillian test runner and will be
+ executed in the target container. It can also use the extra functionality that Arquillian provides—namely
+ container resource injections and the injection of beans.
+ </para>
+
+ </section>
+
+ <section>
+ <title>ShrinkWrap packaging</title>
+
+ <para>
+ When the Arquillian test runner processes a test class, the first thing it does is retrieve the definition of
+ the Java archive from the <literal>@Deployment</literal> method, appends the test class to the archive and
+ packages the archive using ShrinkWrap.
+ </para>
+
+ <para>
+ The name of the archive is irrelevant, so the base name "test" is typically choosen (e.g., test.jar, test.war).
+ Once you have created the shell of the archive, the sky is really the limit of how you can assemble it. You are
+ customizing the layout and contents of the archive to suit the needs of the test. Essentially, you creating a
+ micro application in which to execute the code under test.
+ </para>
+
+ <para>
+ You can add the following artifacts to the test archive:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Java classes</para>
+ </listitem>
+ <listitem>
+ <para>A Java package (which adds all the Java classes in the package)</para>
+ </listitem>
+ <listitem>
+ <para>Classpath resources</para>
+ </listitem>
+ <listitem>
+ <para>File system resources</para>
+ </listitem>
+ <listitem>
+ <para>A programmatically-defined file</para>
+ </listitem>
+ <listitem>
+ <para>Java libraries (JAR files)</para>
+ </listitem>
+ <listitem>
+ <para>Other Java archives defined by ShrinkWrap</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Consult the ShrinkWrap API to discover all the options you have available for constructing the test archive.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Test archive deployment</title>
+
+ <para>
+ After the Arquillian test runner packages the test archive, it deploys it to the container. For a remote
+ container, this means copying the archive the hot deployment directory or deploying the archive using the
+ container's remote deployment service. In the case of a local container, such as Weld SE, deploying the archive
+ simply means registering the contents of the archive with the runtime environment.
+ </para>
+
+ <para>
+ <emphasis>How does Arquillian support multiple containers? And how are both remote and local cases
+ supported?</emphasis> The answer to this question gets into the extensibility of Arquillian.
+ </para>
+
+ <para>
+ Arquillian delegates to an SPI (service provider interface) to handle starting and stopping the server and
+ deploying and undeploying archives. In this case, the SPI is the interface
+ <literal>org.jboss.arquillian.spi.DeployableContainer</literal>. If you recall from the getting started
+ section, we included an Arquillian library according to the target container we wanted to us. That library
+ contains an implementation of this interface, thus controlling how Arquillian handles deployment. If you wanted to
+ introduce support for another container in Arquillian, you would simply provide an implementation of this
+ interface.
+ </para>
+
+ <para>
+ With the archive deployed, all is left is negotiating execution of the test and capturing the results. As you
+ would expect, once all the methods in the test class have be run, the archive is undeployed.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Enriching the test class</title>
+
+ <para>
+ The last operation that Arquillian performs before executing the individual test methods is "enriching" the
+ test class instance. This means hooking the test class to the container environment by satisfying its injection
+ points. The enrichment is provided by any implementation of the
+ <literal>org.jboss.arquillian.spi.TestEnricher</literal> SPI on the classpath. <xref linkend="enrichment"/>
+ details the injection points that Arquillian supports.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Negotiating test execution</title>
+
+ <para>
+ The question at this point is, how does Arquillian negotiate with the container to execute the test
+ when the test framework is being invoked locally? Technially the mechanism is pluggable using another SPI,
+ <literal>org.jboss.arquillian.spi.ContainerMethodExecutor</literal>. Arquillian provides a default
+ implementation for remote servers which uses HTTP communication and an implementation for local tests, which
+ works through direct execution of the test in the same JVM. Let's have a look at how the remote execution
+ works.
+ </para>
+
+ <para>
+ The archive generator bundles and registers (in the web.xml descriptor) an HttpServlet,
+ org.jboss.arquillian.protocol.servlet.ServletTestRunner, that responds to test execution GET requests. The test
+ runner on the client side delegates to the <literal>org.jboss.arquillian.spi.ContainerMethodExecutor</literal>
+ SPI implementation, which originates these test execution requests to transfer control to the container JVM.
+ The name of the test class and the method to be executed are specified in the request query parameters named
+ className and methodName, respectively.
+ </para>
+
+ <para>
+ When the test execution request is received, the servlet delegates to an implementation of the
+ <literal>org.jboss.arquillian.spi.TestRunner</literal> SPI, passing it the name of the test class and the test
+ method. <literal>TestRunner</literal> generates a test suite dynamically from the test class and method name
+ and runs the suite (now within the context of the container).
+ </para>
+
+ <para>
+ The <literal>ServletTestRunner</literal> translates the native test result object of JUnit or TestNG into a
+ <literal>org.jboss.arquillian.spi.TestResult</literal> and passes it back to the test executor on the client
+ side by serializing the translated object into the response. The object gets encoded as either html or a
+ serialized object, depending on the value of the outputMode request parameter that was passed to the servlet.
+ Once the result has been transfered to the client-side test runner, the testing framework (JUnit or TestNG)
+ wraps up the run of the test as though it had been executed in the same JVM.
+ </para>
+
+ <para>
+ Now you should have an understanding for how tests can be executed inside the container, but still be executed
+ using existing IDE, Ant and Maven test plugins without any modification. Perhaps you have even started thinking
+ about ways in which you can enhance or extend Arquillian. But there's still one challenge that remains for
+ developing tests with Arquillian. How do you debug test? We'll look at how to hook a debugger into the test
+ execution process in the next chapter.
+ </para>
+
+<!--
+There's one piece missing. How does TestNG on the client side know to submit a request to the
+ServletTestRunner servlet to get TestNG to execute the test in the container JVM? That's the
+role of the test launcher.
+
+The test launcher is the API that allows test suite to launch the test in a pluggable fashion.
+AbstractTest, the super class of AbtractJSR299Test, implements IHookable, a TestNG
+interface which allows the execution of the test method to be intercepted. Using that mechanism,
+AbstractTest delegates execution of the test method (a method annotated with @Test in
+an @Artifact class) to an implementation of org.jboss.testharness.api.TestLauncher
+if the tests are being executed in-container. As you might anticipate, the implementation is
+specified using a property with the same name as the interface in a META-INF/jboss-test-
+launcher.properties resource. The JBoss Test Harness provides a default implementation,
+org.jboss.testharness.impl.runner.servlet.ServletTestLauncher, that hooks into the
+HTTP communication infrastructure described above. It invokes the ServletTestRunner servlet
+for each method annotated with @Test in the @Artifact that is not otherwise disabled.
+-->
+
+ </section>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/extend.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/extend.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/extend.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="extend">
+ <title>Extending Arquillian</title>
+
+ <!-- TODO -->
+
+ <section id="extend.deployment">
+ <title>@Deployment</title>
+ <para></para>
+ </section>
+
+ <section id="extend.container">
+ <title>DeployableContainers</title>
+ <para></para>
+ </section>
+
+ <section id="extend.testenrichers">
+ <title>TestEnrichers</title>
+ <para></para>
+ </section>
+
+ <section id="extend.testrunners">
+ <title>TestRunners</title>
+ <section id="extend.testrunners.testng">
+ <title>TestNG</title>
+ <para>..</para>
+ </section>
+ <section id="extend.testrunners.junit">
+ <title>JUnit</title>
+ <para>..</para>
+ </section>
+ </section>
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/gettingstarted.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/gettingstarted.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/gettingstarted.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="gettingstarted">
+
+ <title>Getting started</title>
+
+ <para>
+ We've promised you that integration testing with Arquillian is no more complicated than writing a unit test. Now
+ it's time to prove it to you. In this chapter, we'll look at what is required to setup Arquillian in your
+ project, how to write an Arquillian test case, how to execute the test case and produce the test results, and
+ finally how to debug an test. That sounds like a lot, but you'll be writing your own Arquillian tests in no time.
+ </para>
+
+ <section>
+ <title>Setting up Arquillian in your Maven 2 project</title>
+
+ <para>
+ The quickest way to get started with Arquillian is to add it to an existing Maven 2 project. Regardless of
+ whether you plan to use Maven 2 as your project build, we recommend that you take your first steps with
+ Arquillian this way so as to get to your first green bar with the least amount of distraction.
+ </para>
+
+ <para>
+ You'll first need to decide whether you are going to write tests in JUnit 4.x or TestNG 5.x. Once you make that
+ decision (use TestNG if you're not sure), you'll need to add either the JUnit or TestNG library to your test
+ build path and the corresponding Arquillian library.
+ </para>
+
+ <para>
+ If you plan to use <emphasis>JUnit 4</emphasis>, begin by adding the following two test-scoped dependencies to
+ the <literal><dependencies></literal> section of your pom.xml.
+ </para>
+
+ <programlisting role="XML"><![CDATA[<dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.6</version>
+ <scope>test</scope>
+</dependency>
+
+<dependency>
+ <groupId>org.jboss.arquillian</groupId>
+ <artifactId>arquillian-junit</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <scope>test</scope>
+</dependency>]]></programlisting>
+
+ <para>
+ If you plan to use <emphasis>TestNG</emphasis>, add these two test-scoped dependencies instead:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.10</version>
+ <classifier>jdk15</classifier>
+ <scope>test</scope>
+</dependency>
+
+<dependency>
+ <groupId>org.jboss.arquillian</groupId>
+ <artifactId>arquillian-testng</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <scope>test</scope>
+</dependency>]]></programlisting>
+
+ <para>
+ That covers the libraries you need to write your first Arquillian test case. We'll revisit the pom.xml file in a
+ moment to add the library you need to execute the test.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Writing your first Arquillian test</title>
+
+ <para>
+ You're now going to write your first Arquillian test. But in order to write a test, we need to have something
+ to test. So let's first create an stateless EJB session bean that we can invoke. Let's help out those Americans
+ still trying to convert to the metric system by providing a Fahrenheit to Celsius converter. Although
+ not required in Java EE 6, we'll include a local interface for the bean to ensure maximum portability.
+ </para>
+
+ <para>
+ Here's our <literal>TemperatureConverter</literal> interface:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @Local interface TemperatureConverter {
+ double convertToCelsius(double f);
+ double convertToFarenheight(double c);
+}]]></programlisting>
+
+ <para>
+ And here's the <literal>TemperatureConverterBean</literal> implementation:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @Stateless class TemperatureConverterBean
+ implements TemperatureConverter {
+ public double convertToCelsius(double f) {
+ return ((f - 32) * 5 / 9);
+ }
+
+ public double convertToFarenheight(double c) {
+ return ((c * 9 / 5) + 32);
+ }
+}]]></programlisting>
+
+ <para>
+ Now we need to validate that this code runs. We'll create a test in the <literal>src/test/java</literal>
+ classpath of the project.
+ </para>
+
+ <para>
+ In this trivial case, we could simply instantiate the implementation class in a unit test to test the
+ calculations. However, let's assume that this bean is more complex, needing to access enterprise services. We
+ want to test it as a full-blown EJB, not just as a simple bean instance. Therefore, we'll inject the EJB into
+ the test class using the <literal>@EJB</literal> annotation.
+ </para>
+
+ <para>
+ You're probably very familiar with writing tests using either JUnit or TestNG. A regular JUnit or TestNG test
+ class requires two enhancements to make it an Arquillian integration test:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Define the deployment archive for the test using ShrinkWrap</para>
+ </listitem>
+ <listitem>
+ <para>Declare for the test to use the Arquillian test runner</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The deployment archive for the test is defined using a static method annotated with Arquillian's
+ <literal>@Deployment</literal> annotation that has the following signature:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public static JavaArchive createTestArchive();]]></programlisting>
+
+ <para>
+ We'll add both the EJB session bean's interface and implementation class to the archive so that we have
+ something to test.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Deployment
+public static JavaArchive createTestArchive() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(TemperatureConverter.class, TemperatureConverter.class);
+}]]></programlisting>
+
+ <para>
+ The JUnit and TestNG versions of our test class will be nearly identical. They will only differ in how they
+ hook into the Arquillian test runner.
+ </para>
+
+ <para>
+ When creating the JUnit version of the Arquillian test case, you will define at least one test method annotated
+ with the JUnit <literal>@Test</literal> annotation and also annotate the class with the
+ <literal>@RunWith</literal> annotation to indicate that Arquillian should be used as the test runner for this
+ class.
+ </para>
+
+ <para>
+ Here's the JUnit version of our test class:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@RunWith(Arquillian.class)
+public class TemperatureConverterTest {
+ @EJB
+ private TemperatureConverter converter;
+
+ @Deployment
+ public static JavaArchive createTestArchive() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(TemperatureConverter.class, TemperatureConverter.class);
+ }
+
+ @Test
+ public void testConvertToCelcius() {
+ Assert.assertEquals(converter.convertToCelcius(32d), 0d);
+ Assert.assertEquals(converter.convertToCelcius(212d), 100d);
+ }
+
+ @Test
+ public void testConvertToFarenheight() {
+ Assert.assertEquals(converter.convertToFarenheight(0d), 32d);
+ Assert.assertEquals(converter.convertToFarenheight(100d), 212d);
+ }
+}]]></programlisting>
+
+ <para>
+ TestNG doesn't provide anything like JUnit's <literal>@RunWith</literal> annotation, so instead the TestNG
+ version of the Arquillian test case must extend the Arquillian class and define at least one method annotated
+ with TestNG's <literal>@Test</literal> annotation.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class TemperatureConverterTest extends Arquillian {
+ @EJB
+ private TemperatureConverter converter;
+
+ @Deployment
+ public static JavaArchive createTestArchive() {
+ return Archives.create("test.jar", JavaArchive.class)
+ .addClasses(TemperatureConverter.class, TemperatureConverter.class);
+ }
+
+ @Test
+ public void testConvertToCelcius() {
+ Assert.assertEquals(converter.convertToCelcius(32d), 0d);
+ Assert.assertEquals(converter.convertToCelcius(212d), 100d);
+ }
+
+ @Test
+ public void testConvertToFarenheight() {
+ Assert.assertEquals(converter.convertToFarenheight(0d), 32d);
+ Assert.assertEquals(converter.convertToFarenheight(100d), 212d);
+ }
+}]]></programlisting>
+
+ <para>
+ As you can see, we are not instantiating the bean implementation class directly, but rather using the EJB
+ reference provided by the container, just as it would be used in the application. Now let's see if this baby
+ passes!
+ </para>
+
+ </section>
+
+ <section>
+ <title>Selecting a target container and running the test</title>
+
+ <para>
+ As we've been emphasizing, this test is going to run inside of a container. That means you have to have a
+ container running somewhere. While you can execute tests in an embedded container or a Java SE CDI environment,
+ we're going to start off by testing using the real deal.
+ </para>
+
+ <para>
+ If you haven't already, download the latest version of JBoss AS 6.0 from the <ulink
+ src="http://www.jboss.org/jbossas/downloads/">JBoss AS download page</ulink>, extract the distribution and
+ start the container.
+ </para>
+
+ <para>
+ Since Arquillian needs to perform JNDI lookups to get references to the components under test, we need to
+ include a <literal>jndi.properties</literal> file on the test classpath. Create the file
+ <literal>src/test/resources/jndi.properties</literal> and populate it with the following contents:
+ </para>
+
+ <programlisting><![CDATA[java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
+java.naming.provider.url=jnp://localhost:1099]]></programlisting>
+
+ <para>
+ Next, we're going to return to pom.xml to add another dependency. Arquillian picks which container it's going
+ to use to deploy the test archive and negotiate test execution using the service provider mechanism, meaning
+ which implementation of the <literal>ContainerDeployers</literal> SPI is on the classpath. We'll control
+ that through the use of Maven profiles. Add the following profiles to pom.xml:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<profiles>
+ <profile>
+ <id>jboss-remote-60</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.arquillian</groupId>
+ <artifactId>arquillian-jboss-remote-60</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </profile>
+</profiles>]]></programlisting>
+
+ <para>
+ You would setup a similar profile for each Arquillian-supported container in which you want your tests
+ executed.
+ </para>
+
+ <para>
+ All that's left is to execute the tests. In Maven, that's easy. Simply run the Maven test goal with the
+ <literal>jboss-remote-60</literal> profile activated:
+ </para>
+
+ <programlisting><![CDATA[mvn test -Pjboss-remote-60]]></programlisting>
+
+ <para>
+ You should see that the two tests pass.
+ </para>
+
+ </section>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png
===================================================================
(Binary files differ)
Property changes on: arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.svg
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.svg (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.svg 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,561 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="876"
+ height="616"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="architecture-overview.svg">
+ <metadata
+ id="metadata171">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1680"
+ inkscape:window-height="970"
+ id="namedview169"
+ showgrid="false"
+ inkscape:zoom="1.0836182"
+ inkscape:cx="345.89422"
+ inkscape:cy="289.69153"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 308 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="876 : 308 : 1"
+ inkscape:persp3d-origin="438 : 205.33333 : 1"
+ id="perspective173" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#g0"
+ id="linearGradient3074"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.5679073,0.6377928)"
+ x1="74.940651"
+ y1="-38.413731"
+ x2="74.940651"
+ y2="149.73515" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#g1"
+ id="linearGradient3076"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.86704847,1.1533381)"
+ x1="60.550247"
+ y1="-30.996983"
+ x2="60.550247"
+ y2="121.82031" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#g2"
+ id="linearGradient3078"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.72243501,1.3842075)"
+ x1="89.973488"
+ y1="-45.694016"
+ x2="89.973488"
+ y2="180.96997" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#g3"
+ id="linearGradient3080"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.88843463,1.1255752)"
+ x1="61.659996"
+ y1="-31.555611"
+ x2="61.659996"
+ y2="124.00135" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#g4"
+ id="linearGradient3082"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.6820429,0.59451516)"
+ x1="34.184624"
+ y1="-18.081961"
+ x2="34.184624"
+ y2="68.122734" />
+ </defs>
+ <rect
+ style="fill:#ffffff;stroke:none"
+ id="rect3084"
+ width="466.13278"
+ height="267.72339"
+ x="14.714625"
+ y="29.026678"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012" />
+ <g
+ transform="matrix(1.0022272,0,0,1.0022272,84.833159,191.20002)"
+ id="g8"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012">
+ <defs
+ id="defs10">
+ <linearGradient
+ id="g0"
+ x1="74.940651"
+ y1="-38.413731"
+ x2="74.940651"
+ y2="149.73515"
+ gradientTransform="scale(1.5679073,0.6377928)"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="white"
+ offset="0%"
+ id="stop13" />
+ <stop
+ stop-color="#f8f4e7"
+ offset="100%"
+ id="stop15" />
+ </linearGradient>
+ </defs>
+ <g
+ transform="translate(4,4)"
+ id="g17">
+ <rect
+ width="235"
+ height="95"
+ id="rect19"
+ x="0"
+ y="0"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:0;stroke-opacity:0.6" />
+ </g>
+ <rect
+ width="235"
+ height="95"
+ style="fill:url(#linearGradient3074);stroke:#fae4bf;stroke-width:1"
+ id="rect21"
+ x="0"
+ y="0" />
+ <g
+ transform="translate(0,33.5)"
+ id="g23">
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="117.5"
+ style="font-size:12px;text-anchor:middle"
+ y="-3"
+ id="text25">
+ <tspan
+ id="tspan27">
+ <tspan
+ font-size="18"
+ font-weight="bold"
+ id="tspan29"
+ style="font-size:18px;font-weight:bold;fill:#000000;font-family:Arial">Unit testing framework</tspan>
+ </tspan>
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="117.5"
+ style="font-size:12px;text-anchor:middle"
+ y="9.3999996"
+ id="text31">
+ <tspan
+ id="tspan33" />
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="117.5"
+ style="font-size:12px;text-anchor:middle"
+ y="23.200001"
+ id="text35">
+ <tspan
+ id="tspan37">
+ <tspan
+ font-size="12"
+ id="tspan39"
+ style="font-size:12px;fill:#000000;font-family:Arial">JUnit</tspan>
+ </tspan>
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="117.5"
+ style="font-size:12px;text-anchor:middle"
+ y="37"
+ id="text41">
+ <tspan
+ id="tspan43">
+ <tspan
+ font-size="12"
+ id="tspan45"
+ style="font-size:12px;fill:#000000;font-family:Arial">TestNG</tspan>
+ </tspan>
+ </text>
+ </g>
+ </g>
+ <g
+ transform="matrix(1.0022272,0,0,1.0022272,214.12047,35.854807)"
+ id="g47"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012">
+ <defs
+ id="defs49">
+ <linearGradient
+ id="g1"
+ x1="60.550247"
+ y1="-30.996983"
+ x2="60.550247"
+ y2="121.82031"
+ gradientTransform="scale(0.86704847,1.1533381)"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="white"
+ offset="0%"
+ id="stop52" />
+ <stop
+ stop-color="#f8f4e7"
+ offset="100%"
+ id="stop54" />
+ </linearGradient>
+ </defs>
+ <g
+ transform="translate(4,4)"
+ id="g56">
+ <rect
+ width="105"
+ height="140"
+ id="rect58"
+ x="0"
+ y="0"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:0;stroke-opacity:0.6" />
+ </g>
+ <rect
+ width="105"
+ height="140"
+ style="fill:url(#linearGradient3076);stroke:#fae4bf;stroke-width:1"
+ id="rect60"
+ x="0"
+ y="0" />
+ <g
+ transform="translate(0,78)"
+ id="g62">
+ <text
+ text-rendering="auto"
+ font-size="18px"
+ x="52.5"
+ style="font-size:18px;text-anchor:middle"
+ y="-3"
+ id="text64">
+ <tspan
+ id="tspan66">
+ <tspan
+ font-size="18"
+ font-weight="bold"
+ id="tspan68"
+ style="font-size:18px;font-weight:bold;fill:#000000;font-family:Arial">Arquillian</tspan>
+ </tspan>
+ </text>
+ </g>
+ </g>
+ <g
+ transform="matrix(1.0022272,0,0,1.0022272,338.89775,35.854807)"
+ id="g70"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012">
+ <defs
+ id="defs72">
+ <linearGradient
+ id="g2"
+ x1="89.973488"
+ y1="-45.694016"
+ x2="89.973488"
+ y2="180.96997"
+ gradientTransform="scale(0.72243501,1.3842075)"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="white"
+ offset="0%"
+ id="stop75" />
+ <stop
+ stop-color="#f8f4e7"
+ offset="100%"
+ id="stop77" />
+ </linearGradient>
+ </defs>
+ <g
+ transform="translate(4,4)"
+ id="g79">
+ <rect
+ width="130"
+ height="250"
+ id="rect81"
+ x="0"
+ y="0"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:0;stroke-opacity:0.6" />
+ </g>
+ <rect
+ width="130"
+ height="250"
+ style="fill:url(#linearGradient3078);stroke:#fae4bf;stroke-width:1"
+ id="rect83"
+ x="0"
+ y="0" />
+ <g
+ transform="translate(0,103)"
+ id="g85">
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="65"
+ style="font-size:12px;text-anchor:middle"
+ y="-3"
+ id="text87">
+ <tspan
+ id="tspan89">
+ <tspan
+ font-size="18"
+ font-weight="bold"
+ id="tspan91"
+ style="font-size:18px;font-weight:bold;fill:#000000;font-family:Arial">Container</tspan>
+ </tspan>
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="65"
+ style="font-size:12px;text-anchor:middle"
+ y="9.3999996"
+ id="text93">
+ <tspan
+ id="tspan95" />
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="65"
+ style="font-size:12px;text-anchor:middle"
+ y="23.200001"
+ id="text97">
+ <tspan
+ id="tspan99">
+ <tspan
+ font-size="12"
+ id="tspan101"
+ style="font-size:12px;fill:#000000;font-family:Arial">Java EE app server</tspan>
+ </tspan>
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="65"
+ style="font-size:12px;text-anchor:middle"
+ y="37"
+ id="text103">
+ <tspan
+ id="tspan105">
+ <tspan
+ font-size="12"
+ id="tspan107"
+ style="font-size:12px;fill:#000000;font-family:Arial">Servlet container</tspan>
+ </tspan>
+ </text>
+ <text
+ text-rendering="auto"
+ font-size="12px"
+ x="65"
+ style="font-size:12px;text-anchor:middle"
+ y="50.799999"
+ id="text109">
+ <tspan
+ id="tspan111">
+ <tspan
+ font-size="12"
+ id="tspan113"
+ style="font-size:12px;fill:#000000;font-family:Arial">Weld SE</tspan>
+ </tspan>
+ </text>
+ </g>
+ </g>
+ <g
+ transform="matrix(1.0022272,0,0,1.0022272,84.332046,36.35592)"
+ id="g115"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012">
+ <defs
+ id="defs117">
+ <linearGradient
+ id="g3"
+ x1="61.659996"
+ y1="-31.555611"
+ x2="61.659996"
+ y2="124.00135"
+ gradientTransform="scale(0.88843463,1.1255752)"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="white"
+ offset="0%"
+ id="stop120" />
+ <stop
+ stop-color="#f8f4e7"
+ offset="100%"
+ id="stop122" />
+ </linearGradient>
+ </defs>
+ <g
+ transform="translate(4,4)"
+ id="g124">
+ <polygon
+ points="109.56175,32.450331 109.56175,139.07285 0,139.07285 0,0 94.223108,0 "
+ id="polygon126"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:1;stroke-opacity:0.6" />
+ <line
+ x1="94.223106"
+ y1="0"
+ x2="94.223106"
+ y2="32.450333"
+ id="line128"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:1;stroke-opacity:0.6" />
+ <line
+ x1="94.223106"
+ y1="32.450333"
+ x2="109.56175"
+ y2="32.450333"
+ id="line130"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:1;stroke-opacity:0.6" />
+ </g>
+ <polygon
+ points="109.56175,32.450331 109.56175,139.07285 0,139.07285 0,0 94.223108,0 "
+ style="fill:url(#linearGradient3080);stroke:#f8e4bf;stroke-width:1"
+ id="polygon132" />
+ <line
+ x1="94.223106"
+ y1="0"
+ x2="94.223106"
+ y2="32.450333"
+ id="line134"
+ style="fill:#f8f4e7;stroke:#f8e4bf;stroke-width:1" />
+ <line
+ x1="94.223106"
+ y1="32.450333"
+ x2="109.56175"
+ y2="32.450333"
+ id="line136"
+ style="fill:#f8f4e7;stroke:#f8e4bf;stroke-width:1" />
+ <g
+ transform="translate(0,78)"
+ id="g138">
+ <text
+ text-rendering="auto"
+ font-size="18px"
+ x="55"
+ style="font-size:18px;text-anchor:middle"
+ y="-3"
+ id="text140">
+ <tspan
+ id="tspan142">
+ <tspan
+ font-size="18"
+ font-weight="bold"
+ id="tspan144"
+ style="font-size:18px;font-weight:bold;fill:#000000;font-family:Arial">Test case</tspan>
+ </tspan>
+ </text>
+ </g>
+ </g>
+ <g
+ transform="matrix(1.0022272,0,0,1.0022272,23.697302,45.877079)"
+ id="g146"
+ inkscape:export-xdpi="96.144012"
+ inkscape:export-ydpi="96.144012"
+ inkscape:export-filename="/home/dallen/projects/arquillian-trunk/doc/reference/src/main/docbook/en-US/images/architecture-overview.png">
+ <defs
+ id="defs148">
+ <linearGradient
+ id="g4"
+ x1="34.184624"
+ y1="-18.081961"
+ x2="34.184624"
+ y2="68.122734"
+ gradientTransform="scale(1.6820429,0.59451516)"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ stop-color="white"
+ offset="0%"
+ id="stop151" />
+ <stop
+ stop-color="#f8f4e7"
+ offset="100%"
+ id="stop153" />
+ </linearGradient>
+ </defs>
+ <g
+ transform="translate(4,4)"
+ id="g155">
+ <rect
+ width="115"
+ height="40"
+ id="rect157"
+ x="0"
+ y="0"
+ style="fill:#a8a8a8;fill-opacity:0.6;stroke:#a8a8a8;stroke-width:0;stroke-opacity:0.6" />
+ </g>
+ <rect
+ width="115"
+ height="40"
+ style="fill:url(#linearGradient3082);stroke:#fae4bf;stroke-width:1"
+ id="rect159"
+ x="0"
+ y="0" />
+ <g
+ transform="translate(0,28)"
+ id="g161">
+ <text
+ text-rendering="auto"
+ font-size="18px"
+ x="57.5"
+ style="font-size:18px;text-anchor:middle"
+ y="-3"
+ id="text163">
+ <tspan
+ id="tspan165">
+ <tspan
+ font-size="18"
+ font-weight="bold"
+ id="tspan167"
+ style="font-size:18px;font-weight:bold;fill:#000000;font-family:Arial">ShrinkWrap</tspan>
+ </tspan>
+ </text>
+ </g>
+ </g>
+</svg>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/intro.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/intro.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/intro.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="intro">
+ <title>Introduction</title>
+
+ <para>
+ We believe that integration testing should be no more complex than writing a simple unit test. We created
+ Arquillian to realize that goal. One of the major complaints we heard about Seam 2 testing (i.e., SeamTest) was,
+ not that it wasn't possible, but that it wasn't flexible and it was difficult to setup.
+ </para>
+
+ <para>
+ People test in a myriad of ways, which is why it's so vital that, with Arquillian (and ShrinkWrap), we have
+ decomposed the problem into its essential elements. The result is a completely flexible and portable integration
+ testing framework.
+ </para>
+
+ <section id="mission">
+ <title>Mission statement</title>
+ <para>
+ The mission of the Arquillian project is to provide a simple mechanism to test application code inside a
+ container. But the last thing Java developers want is yet another testing framework to make their life more
+ complicated. That's why Arquillian integrates transparently with familiar testing frameworks (JUnit 4 and
+ TestNG 5), performs runtime packaging and deployment of tests within Java EE archives and executes the tests
+ inside the container. Tests can be launched using existing IDE, Ant and Maven test plugins, thus minimizing the
+ burden on the developer to <!-- validate the behavior of managed and enterprise beans or POJOs that use
+ enterprise services --> perform integration testing. And the environment in which the tests are run is
+ pluggable, so the developer is not locked in to a proprietary testing container.
+ </para>
+ </section>
+
+ <section id="overview">
+ <title>Architecture overview</title>
+ <para>
+ Arquillian combines a unit testing framework (JUnit or TestNG), ShrinkWrap, and one or more supported target
+ containers (Java EE container, servlet container, Java SE CDI environment, etc) to provide a simple, flexible
+ and pluggable integration testing environment for normal test cases.
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/architecture-overview.png" format="PNG" align="center"/>
+ </imageobject>
+ <caption>
+ <para>The Arquillian test infrastructure</para>
+ </caption>
+ </mediaobject>
+
+ <para>
+ At the core, Arquillian provides a <emphasis>custom test runner for JUnit and TestNG</emphasis> that allows
+ test methods in a test case to be executed inside of a container environment. An Arquillian test case looks
+ just like a regular JUnit or TestNG test case with two declarative enhancements, which will be covered later.
+ </para>
+
+ <para>
+ Since Arquillian works by replacing the test runner, Arquillian tests can be executed using existing test IDE,
+ Ant and Maven test plugins without any special configuration. Test results are reported just like you would
+ expect. That's what we mean when we say using Arquillian is no more complicated than basic unit testing.
+ </para>
+
+ <para>
+ The test case is transferred into the container's environment through coordination with
+ <emphasis>ShrinkWrap</emphasis>, which is used to declaratively define a custom Java EE archive that
+ encapsulates the test class and its dependent resources. Arquillian packages the ShrinkWrap-defined archive at
+ runtime and deploys it to the <emphasis>target container</emphasis>. It then negotiates the execution of the
+ test methods and captures the test results using remote communication with the server. Finally, Arquillian
+ undeploys the test archive. We'll go into more detail about how Arquillian works in a later chapter.
+ </para>
+
+ <para>
+ So what is the target container? Some proprietary testing container that emulates the behavior of the technology
+ (Java EE)? Nope, it's pluggable. It can be your actual target runtime, such as JBoss AS, GlassFish or Tomcat.
+ It can even been an embedded container such as JBoss Embedded AS, GlassFish Embedded or Weld SE. All of this is
+ made possible by a RPC-style (or local, if applicable) communication between the test runner and the
+ environment, negotiating which tests are run, the execution, and communicating back the results. This means two
+ things for the developer:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>You develop Arquillian tests just like you would a regular unit test and</para>
+ </listitem>
+ <listitem>
+ <para>the container in which you run the tests can be easily swapped, or you can use each one.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ With that in mind, let's consider where we are today with integration testing in Java EE and why an easy
+ solution is needed.
+ </para>
+
+ </section>
+
+ <!-- consider a chapter on Motivation or Benefits -->
+ <section id="motivation">
+ <title>Integration testing in Java EE</title>
+
+ <para>
+ Integration testing is very important in Java EE. The reason is two-fold:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Business components often interact with resources or sub-system provided by the container</para>
+ </listitem>
+ <listitem>
+ <para>Many declarative services get applied to the business component at runtime</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The first reason is inherent in enterprise applications. For the application to perform any sort of meaningful
+ work, it has to pull the strings on other components, resources (e.g., a database) or systems (e.g., a web
+ service). Having to write any sort of test that requires an enterprise resource (database connection, entity
+ manager, transaction, injection, etc) is a non-starter because the developer has no idea what to even use.
+ Clearly there is a need for a simple solution, and Arquillian fills that void.
+ </para>
+
+ <para>
+ Some might argue that, as of Java EE 5, the business logic performed by most Java EE components can now be
+ tested outside of the container because they are POJOs. But let's not forget that in order to isolate the
+ business logic in Java EE components from infrastructure services (transactions, security, etc), many of those
+ services were pushed into declarative programming constructs. At some point you want to make sure that the
+ infrastructure services are applied correctly and that the business logic functions properly within that
+ context, justifying the second reason that integration testing is important in Java EE.
+ </para>
+
+ <section>
+ <title>Testing the real component</title>
+
+ <para>
+ The reality is that you aren't really testing your component until you test it in situ. It's all to easy to
+ create a test that puts on a good show but doesn't provide any real guarantee that the code under test
+ functions properly in a production environment. The show typically involves mock components and/or bootstrapped
+ environments that cater to the test. Such "unit tests" can't verify that the declarative services kick in as
+ they should. While unit tests certainly have value in quickly testing algorithms and business calculations
+ within methods, there still need to be tests that exercise the component as a complete service.
+ </para>
+
+ <para>
+ Rather than instantiating component classes in the test using Java's new operator, which is customary in a unit
+ test, Arquillian allows you to inject the container-managed instance of the component directly into your test
+ class (or you can look it up in JNDI) so that you are testing the actual component, just as it runs inside the
+ application.
+ </para>
+ </section>
+
+ <section>
+ <title>Finding a happy medium</title>
+ <para>
+ Do you really need to run the test in a real container when a Java SE CDI environment would do?
+ </para>
+
+ <para>
+ It's true, some tests can work without a full container. For instance, you can run certain tests in a Java
+ SE CDI environment with Arquillian. Let's call these "standalone" tests, whereas tests which do require a
+ full container are called "integration" tests. Every standalone test can also be run as an integration test,
+ but not the other way around. While the standalone tests don't need a full container, it's also important to
+ run them as integration tests as a final check just to make sure that there is nothing they conflict with
+ (or have side effects) when run in a real container.
+ </para>
+
+ <para>
+ It might be a good strategy to make as many tests work in standalone mode as possible to ensure a quick test
+ run, but ultimately you should consider running all of your tests in the target container. As a result, you'll
+ likely enjoy a more robust code base.
+ </para>
+
+ <para>
+ We've established that integration testing is important, but how can integration testing being accomplished
+ without involving every class in the application? That's the benefit that ShrinkWrap brings to Arquillian.
+ </para>
+ </section>
+
+ <section id="microdeployments">
+ <title>Controlling the test classpath</title>
+
+ <para>
+ One huge advantage ShrinkWrap brings to Arquillian is classpath control. The classpath of a test run has
+ traditionally been a kitchen sink of all production classes and resources with the test classes and resources
+ layered on top. This can make the test run indeterministic, or it can just be hard to isolate test resources
+ from the main resources.
+ </para>
+
+ <para>
+ Arquillian uses ShrinkWrap to create "micro deployments" for each test, giving you fine-grained control over
+ what you are testing and what resources are available at the time the test is executed. An archive can
+ include classes, resources and libraries. This not only frees you from the classpath hell that typically
+ haunts test runners (Eclipse, Maven), it also gives you the option to focus on the interaction between an
+ subset of production classes, or to easily swap in alternative classes. Within that grouping you get the
+ self-assembly of services provided by Java EE—the very integration which is being tested.
+ </para>
+
+ </section>
+
+ <para>
+ Let's move on and consider some typical usage scenarios for Arquillian.
+ </para>
+
+ </section>
+
+ <section id="usage">
+ <title>Usage scenarios</title>
+ <para>
+ With the strategy defined above, where the test case is executed in the container, you should get the sense of
+ the freedom you have to test a broad range of situations that may have seemed unattainable when you only had
+ the primitive unit testing environment. In fact, anything you can do in an application you can now do in your
+ test class.
+ </para>
+
+ <para>
+ A fairly common scenario is testing an EJB session bean. As you are inside the container, you can simply do a
+ JNDI lookup to get the EJB reference and your test becomes a client of the EJB. But having to use JNDI to get
+ a reference to the EJB is inconvenient (at least to Java EE 5 developers that have become accustomed to
+ annotation-based dependency injection). Arquillian allows you to use the <literal>@EJB</literal> annotation to
+ inject the reference to an EJB session bean into your test class.
+ </para>
+
+ <para>
+ EJB session beans are one type of Java EE resource you may want to access. But that's just the beginning.
+ You can access any resource available in a Java EE container, from a <literal>UserTransaction</literal> to
+ a <literal>DataSource</literal> to a mail session. Any of these resources can be injected directly into
+ your test class using the Java EE 5 <literal>@Resource</literal> annotation.
+ </para>
+
+ <para>
+ Resource injections are convenient, but they are <emphasis>so</emphasis> Java EE 5. In Java EE 6, when you
+ think dependency injection, you think JSR-299: CDI. Your test class can access any bean in the
+ ShrinkWrap-defined archive, provided the archive contains a beans.xml file to make it a bean archive. And you
+ can inject bean instances directly into your class using the <literal>@Inject</literal> annotation, or you can
+ inject an <literal>Instance</literal> reference to the bean, allowing you to create a bean instance when needed
+ in the test. Of course, you can do anything else you can do with CDI within your test as well.
+ </para>
+
+ <para>
+ Another important scenario in integration testing is performing data access. If the ShrinkWrap-defined archive
+ contains a persistence.xml descriptor, the persistence unit will be started when the archive is deployed
+ and you can perform persistence operations. You can obtain a reference to an <literal>EntityManager</literal>
+ by injecting it into your class with <literal>@PersistenceContext</literal> or from a CDI producer-field.
+ Alternatively, you can execute the persistence operation indirectly through an EJB session bean or a managed bean.
+ </para>
+
+ <!-- eliminate burden of packaging using build -->
+
+ <para>
+ Those examples should give you an idea of some of the tasks that are possible from within an
+ Arquillian-enhanced test case. Now that you have plenty of motivation for using Arquillian, let's
+ look at how to get started using Arquillian.
+ </para>
+
+ </section>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/master.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/master.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/master.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<book lang="en">
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="book_info.xml" />
+
+ <toc />
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="preface.xml" />
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="intro.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="examples.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="gettingstarted.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="containers.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="enrichment.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="execution.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="debugging.xml" />
+ <!--
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="scenarios.xml" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="extend.xml" />
+ -->
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</book>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/preface.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/preface.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/preface.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<preface>
+ <title>Preface: Test in the container!</title>
+ <para>
+ Ever since the inception of Java EE, testing enterprise applications has been a big pain point. Testing business
+ components, in particular, can be very challenging. Often, a vanilla unit test isn't sufficient for validating
+ such a component's behavior. <emphasis>Why is that?</emphasis> The reason is that components in an enterprise
+ application rarely perform operations which are strictly self-contained. Instead, they provide services which
+ intimately tie into the greater system. They also have declarative functionality which gets applied to the
+ component at runtime. You could say "no business component is an island."
+ </para>
+
+ <para>
+ The way the component interacts with the system is just as important as the work it performs. Even with the
+ application separated into more layers than your favorite Mexican dip, to validate the correctness of a component,
+ you have to observe it carrying out its work—<emphasis>in situ</emphasis>. Unit tests and mock testing can only
+ take you so far. Business logic aside, how do you test your component's "enterprise" semantics?
+ </para>
+
+ <para>
+ Especially true of business components, you eventually have to ensure that the declarative services, such as
+ dependency injection and transaction control, actually get applied and work as expected. It means interacting with
+ databases or remote systems and ensuring that the component plays well with its collaborators. What happens when
+ your Message Driven Bean can't parse the XML message? Will the right component be injected? You may just need to
+ write a test to explore how the declarative services behave, or that your application is configured correctly to
+ use them. This style of testing needed here is referred to as integration testing, and it's an essential part of
+ the enterprise development process.
+ </para>
+
+ <para>
+ Arquillian, a new testing framework developed at Jboss.org, empowers the developer to write integration tests for
+ business objects that are executed inside an embedded or remote container—whether it be a servlet container, a
+ Java EE application server or a Java SE CDI environment. Arquillian strives to make integration testing no more
+ complicated than basic unit testing. It turns out, if these tests execute quickly, they're really the only tests
+ you need.
+ </para>
+
+ <para>
+ The importance of Arquillian in the Java EE space cannot be emphasized enough. If writing good tests for Java EE
+ projects is some dark art in which knowledge is shared only by the Java gurus, people are either going to be
+ turned off of Java EE or a lot of fragile applications are going to be written. Arquillian is set to become the
+ first comprehensive solution for testing Java EE applications, namely because it leverages the container rather
+ than a contrived runtime environment.
+ </para>
+
+ <para>
+ This guide documents Arquillian's architecture, how to get started using it and how to extend it. If you have
+ questions, please use the top-level discussions forum in the Arquillian space on JBoss.org. We also provide a JIRA
+ issue tracking system for bug reports and feature requests. If you are interested in the development of
+ Arquillian, or want to translate this documentation into your language, we welcome you to join us in the Arquillian
+ Development subspace on JBoss.org.
+ </para>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</preface>
Added: arquillian/trunk/doc/reference/src/main/docbook/en-US/scenarios.xml
===================================================================
--- arquillian/trunk/doc/reference/src/main/docbook/en-US/scenarios.xml (rev 0)
+++ arquillian/trunk/doc/reference/src/main/docbook/en-US/scenarios.xml 2010-02-08 04:43:04 UTC (rev 3994)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" []>
+<chapter id="scenarios">
+ <title>Advanced testing scenarios</title>
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
More information about the jboss-svn-commits
mailing list