You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by bu...@apache.org on 2013/07/18 09:14:43 UTC

svn commit: r869932 - in /websites/staging/isis/trunk: cgi-bin/ content/ content/core/specsupport-and-integtestsupport.html

Author: buildbot
Date: Thu Jul 18 07:14:43 2013
New Revision: 869932

Log:
Staging update by buildbot for isis

Modified:
    websites/staging/isis/trunk/cgi-bin/   (props changed)
    websites/staging/isis/trunk/content/   (props changed)
    websites/staging/isis/trunk/content/core/specsupport-and-integtestsupport.html

Propchange: websites/staging/isis/trunk/cgi-bin/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Thu Jul 18 07:14:43 2013
@@ -1 +1 @@
-1503780
+1504377

Propchange: websites/staging/isis/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Thu Jul 18 07:14:43 2013
@@ -1 +1 @@
-1503780
+1504377

Modified: websites/staging/isis/trunk/content/core/specsupport-and-integtestsupport.html
==============================================================================
--- websites/staging/isis/trunk/content/core/specsupport-and-integtestsupport.html (original)
+++ websites/staging/isis/trunk/content/core/specsupport-and-integtestsupport.html Thu Jul 18 07:14:43 2013
@@ -292,9 +292,17 @@ or regular integration tests.</p>
 
 <p>Like the <code>IsisSystemForTest</code> class, the <code>ScenarioExecution</code> class also binds an instance of itself onto a <code>ThreadLocal</code>.  It can then be accessed in both BDD step defs and in integration tests using <code>ScenarioExecution.current()</code> static method.</p>
 
-<h3>CukeStepDefsAbstract and IntegrationTestAbstract</h3>
+<h3>CukeGlueAbstract and IntegrationTestAbstract</h3>
 
-<p>The <code>CukeStepDefsAbstract</code> acts as a convenience superclass for writing BDD step definitions.  Similarly, the <code>IntegrationTestAbstract</code> acts as a convenience subclass for writing integration tests.  These two classes are very similar in that they both delegate to an underlying <code>ScenarioExecution</code>.</p>
+<p>The <code>CukeGlueAbstract</code> acts as a convenience superclass for writing BDD step definitions.  Similarly, the <code>IntegrationTestAbstract</code> acts as a convenience subclass for writing integration tests.  These two classes are very similar in that they both delegate to an underlying <code>ScenarioExecution</code>.</p>
+
+<h3>Separate Glue from Specs</h3>
+
+<p>The "glue" (step definitions) are intended to be reused across features.  We therefore recommend that they reside in a separate package, and are organized by the entity type upon which they act.  </p>
+
+<p>For example, given a feature that involves <code>Customer</code> and <code>Order</code>, have the step definitions pertaining to <code>Customer</code> reside in <code>CustomerGlue</code>, and the step definitions pertaining to <code>Order</code> reside in <code>OrderGlue</code>.</p>
+
+<p>The Cucumber-JVM spec runner allows you to indicate which package(s) should be recursively searched to find any glue.</p>
 
 <h3>Integration- vs Unit- Scope</h3>
 
@@ -444,12 +452,12 @@ or regular integration tests.</p>
 
 <ul>
 <li>a <code>XxxSpec.feature</code> file, describing the feature and the scenarios (given/when/then)s that constitute its acceptance criteria</li>
-<li>a <code>XxxSpec.java</code> class file to run the specification (all boilerplate).  This must have the same basename as the <code>.feature</code> file</li>
-<li>one or several <code>XxxStepDefs</code> constituting the step definitions to be matched against.  (I believe...) these must reside in the same package as the specification.</li>
+<li>a <code>RunSpecs.java</code> class file to run the specification (all boilerplate).  This will run all <code>.feature</code> files in the same package or subpackages.</li>
+<li>one or several <code>XxxGlue</code> constituting the step definitions to be matched against.  These are normally placed in a separate package(s) to the specifications; the <code>glue</code> attribute of the Cucumber-JVM JUnit runner indicates which package(s) to search in.</li>
 <li>a system initializer class.  This can be reused with any integration tests (eg the <code>ToDoSystemInitializer</code> class, shown above).</li>
 </ul>
 
-<p>It's usually more convenient to place the <code>.feature</code> files in <code>src/test/java</code>, rather than <code>src/test/resources</code>.  If you wish to do this, then your integration test module's <code>pom.xml</code> must contain:</p>
+<p>You may find it more convenient to place the <code>.feature</code> files in <code>src/test/java</code>, rather than <code>src/test/resources</code>.  If you wish to do this, then your integration test module's <code>pom.xml</code> must contain:</p>
 
 <pre><code>&lt;build&gt;
     &lt;testResources&gt;
@@ -473,7 +481,8 @@ or regular integration tests.</p>
 
 <p>Let's now look at the a specification for the <code>ToDoItem'</code>s "completed" feature.  Firstly, the <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/specs/todoitem/ToDoItemSpec_findAndComplete.feature"><code>ToDoItemSpec_findAndComplete.feature</code></a>:</p>
 
-<pre><code>Feature: Find And Complete ToDo Items
+<pre><code>@ToDoItemsFixture
+Feature: Find And Complete ToDo Items
 
     @integration
     Scenario: Todo items once completed are no longer listed
@@ -483,22 +492,29 @@ or regular integration tests.</p>
       Then  the item is no longer listed as incomplete 
 </code></pre>
 
-<p>The corresponding <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/specs/todoitem/ToDoItemSpec_findCompletedAndMarkAsNotYetComplete.java"><code>ToDoItemSpec_findAndComplete</code></a> class is just boilerplate:</p>
+<p>The <code>@ToDoItemsFixture</code> is a custom tag we've specified to indicate the prerequisite fixtures to be loaded; more on this in a moment.  The <code>@integration</code> tag, meanwhile, says that this feature should be run with integration-level scope.  (If we wanted to run at unit-level scope, the tag would be <code>@unit</code>).</p>
+
+<p>The <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/specs/todoitem/RunSpecs.java"><code>RunSpecs</code></a> class to run this feature (and any other features in this package or subpackages) is just boilerplate:</p>
 
 <pre><code>@RunWith(Cucumber.class)
 @Cucumber.Options(
         format = {
-                "html:target/cucumber-html-report"
+                "html:target/cucumber-html-report",
+                "json:target/cucumber.json"
         },
+        glue={"classpath:com.mycompany.integration.glue"},
         strict = true,
         tags = { "~@backlog", "~@ignore" })
-public class ToDoItemSpec_findAndComplete {
+public class RunSpecs {
+    // intentionally empty 
 }
 </code></pre>
 
-<p>The heavy lifting is done in the <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/specs/todoitem/ToDoItemStepDefs.java"><code>ToDoItemStepDefs</code></a> class:</p>
+<p>The JSON formatter allows integration with enhanced reports, for example as provided by <a href="http://www.masterthought.net/section/cucumber-reporting">Masterthought.net</a> (screenshots at end of page).  (Commented out) configuration for this is provided in the example todo app <code>integtests</code> module's <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/pom.xml">pom.xml</a>.</p>
 
-<pre><code>public class ToDoItemStepDefs extends CukeStepDefsAbstract {
+<p>The bootstrapping of Isis can be moved into a <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/glue/BootstrappingGlue.java"><code>BootstrappingGlue</code></a> step definition:</p>
+
+<pre><code>public class BootstrappingGlue extends CukeGlueAbstract {
 
     @Before(value={"@integration"}, order=100)
     public void beforeScenarioIntegrationScope() {
@@ -514,12 +530,29 @@ public class ToDoItemSpec_findAndComplet
         after(sc);
     }
 
-    @Before(value={"@integration"}, order=20000)
+    // bootstrapping of @unit scope omitted
+}
+</code></pre>
+
+<p>The fixture to run also lives in its own step definition, <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/glue/CatalogOfFixturesGlue.java"><code>CatalogOfFixturesGlue</code></a>:</p>
+
+<pre><code>public class CatalogOfFixturesGlue extends CukeGlueAbstract {
+
+    @Before(value={"@integration", "@ToDoItemsFixture"}, order=20000)
     public void integrationFixtures() throws Throwable {
         scenarioExecution().install(new ToDoItemsFixture());
-    }
+    }        
+
+    // fixture for @unit, @ToDoItemsFixture omitted
+
+}
+</code></pre>
+
+<p>Note that this is annotated with a tag (<code>@ToDoItemsFixture</code>) so that the correct fixture runs.  (We might have a whole variety of these).</p>
+
+<p>The step definitions pertaining to <code>ToDoItem</code> then reside in the <a href="https://github.com/apache/isis/blob/master/example/application/quickstart_wicket_restful_jdo/integtests/src/test/java/integration/glue/todoitem/ToDoItemGlue.java"><code>ToDoItemGlue</code></a> class.  This is where the heavy lifting gets done:</p>
 
-    // //////////////////////////////////////
+<pre><code>public class ToDoItemGlue extends CukeGlueAbstract {
 
     @Given("^there are a number of incomplete ToDo items$")
     public void there_are_a_number_of_incomplete_ToDo_items() throws Throwable {