You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by bu...@apache.org on 2014/04/04 03:17:30 UTC

svn commit: r904814 [6/7] - in /websites/staging/flex/trunk: cgi-bin/ content/ content/css/ content/flexunit/tutorial/css/ content/flexunit/tutorial/flexunit/ content/flexunit/tutorial/scripts/

Added: websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-7.html
==============================================================================
--- websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-7.html (added)
+++ websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-7.html Fri Apr  4 01:17:29 2014
@@ -0,0 +1,578 @@
+<!DOCTYPE html>
+<!--[if IE 7 ]><html class="ie ie7" lang="en"><![endif]-->
+<!--[if IE 8 ]><html class="ie ie8" lang="en"><![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!--><html lang="en"><!--<![endif]-->
+
+<head>
+
+    <meta charset="utf-8">
+    <title>Apache Flex® - Unit 7 - Using Suites
</title>
+
+    <!-- For Mobiles  -->
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link href='https://fonts.googleapis.com/css?family=Carrois+Gothic' rel='stylesheet' type='text/css'>
+    <!-- CSS -->
+    <link rel="stylesheet" type="text/css" href="/css/bootstrap.css">
+    <link rel="stylesheet" type="text/css" href="/css/fixed-width.css" id="layout">
+    <link rel="stylesheet" type="text/css" href="/css/style.css">
+
+    <!-- Java Script  -->
+    <script src="/js/jquery.js"></script>
+    <script src="/js/custom.js"></script>
+    <script src="/js/selectnav.js"></script>
+    <script src="/js/flexslider.js"></script>
+    <script src="/js/twitter.js"></script>
+    <script src="/js/fancybox.js"></script>
+    <script src="/js/isotope.js"></script>
+    <script src="/js/bootstrap.js"></script>
+    <script src="/js/showcase.js"></script>
+
+    <!-- Google Analytics -->
+    <script type="text/javascript">
+
+        var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-37926454-1']);
+        _gaq.push(['_trackPageview']);
+
+        (function() {
+            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();
+
+    </script>
+
+
+</head>
+<body>
+
+<!-- Wrapper Start -->
+<div id="wrapper" class="container-fluid">
+
+
+    <!-- Header -->
+
+
+    <div class="ie-dropdown-fix" >
+
+        <!-- Header -->
+        <div class="row-fluid" id="header">
+
+            <!-- Logo -->
+            <div class="span5">
+
+                <a href="#"><img src="/images/logo_01_fullcolor-sm.png" alt="Apache Flex®" title="Apache Flex®" /></a>
+
+            </div>
+
+            <!-- Social / Contact -->
+            <div class="span3 pull-right">
+
+                <!-- Social Icons -->
+                <ul class="social-icons">
+                    <li class="facebook"><a href="https://www.facebook.com/pages/Apache-Flex/174249699342648">Facebook</a></li>
+                    <li class="twitter"><a href="http://twitter.com/ApacheFlex">Twitter</a></li>
+                    <li class="linkedin"><a href="http://www.linkedin.com/groups/Apache-Flex-Developers-4296888">LinkedIn</a></li>
+                </ul>
+
+                <!-- Apache Logo -->
+                <a href="http://www.apache.org" id="contact-top"><img src="http://www.apache.org/images/feather-small.gif" title="An Apache Project" alt="An Apache Project" /> </a>
+            </div>
+
+        </div>
+        <!-- Header / End -->
+
+        <!-- Navigation -->
+        <div id="navigation" class="margintop">
+            <ul id="nav">
+
+                <li><a href="index.html">Home</a></li>
+
+                <li><a href="#">About Flex</a>
+                    <ul>
+
+                        <li><a href="/about-whatis.html">What is Flex?</a></li>
+                        <li><a href="/about-features.html">Features</a></li>
+                        <li><a href="/about-licensing.html">License &amp; Trademarks</a></li>
+                        <li><a href="/about-people.html">The Team</a></li>
+                        <li><a href="/about-history.html">Project History</a></li>
+                        <li><a href="/about-assets.html">Logo and Assets</a></li>
+                    </ul>
+                </li>
+                <li><a href="#">Community</a>
+                    <ul>
+
+                        <li><a href="/community-getinvolved.html">How to get involved</a></li>
+                        <li><a href="/community-mailinglists.html">Mailing Lists</a></li>
+                        <li><a href="/community-showcase.html">Flex Showcase</a></li>
+						<li><a href="/community-3rdparty.html">Third-Party</a></li>
+                        <li><a href="https://cwiki.apache.org/confluence/display/FLEX/Apache+Flex+Wiki">Wiki <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://blogs.apache.org/flex/">Blog <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#">Development</a>
+                    <ul>
+                        <li><a href="/dev-faq.html">Developer FAQ</a></li>
+                        <li><a href="/dev-sourcecode.html">Source Code</a></li>
+                        <li><a href="https://issues.apache.org/jira/browse/FLEX">Bug-Tracker <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#">Documentation</a>
+                    <ul>
+
+                        <li><a href="/doc-getstarted.html">Getting Started</a></li>
+                        <li><a href="/doc-videos.html">Videos</a></li>
+                        <li><a href="/asdoc/">ASDocs</a></li>
+                        <li><a href="http://help.adobe.com/en_US/flex/using/index.html">Documentation Reference (Old) <i class="icon-share icon-white"></i></a></li>
+
+                    </ul>
+                </li>
+
+                <li><a href="#">About Apache</a>
+                    <ul>
+
+                        <li><a href="http://www.apache.org">The Apache Software Foundation Website <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/contributing.html">Donations <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/thanks.html">Thanks <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#" class="download">Download</a>
+                    <ul>
+
+                        <li><a href="/installer.html">Download the SDK Installer (For Application Developers)</a></li>
+                        <li><a href="/download-binaries.html">Download the SDK Binaries (For SDK Developers)</a></li>
+                        <li><a href="/download-source.html">Download the SDK Source Code (For SDK Developers)</a></li>
+                        <li><a href="/download-utilities.html">Download Utilities</a></li>
+                        <li><a href="/download-archive.html">Previous Versions</a></li>
+                    </ul>
+                </li>
+            </ul>
+
+        </div>
+        <div class="nav-shadow"></div>
+        <div class="clear"></div>
+
+    </div>
+    <!-- Navigation / End -->
+
+
+    <!-- Content -->
+
+    
+    <div class="row-fluid">
+
+
+        <!-- Page Title -->
+        <div id="page-title">
+            <h2>Unit 7 - Using Suites
</h2>
+        </div>
+        <!-- Page Title / End -->
+
+
+    </div>
+    
+
+    <div class="row-fluid">
+
+
+
+<!-- Home Page Exception -->
+
+
+<p><a href="../code/unit7.zip"><img src="../images/DownloadIcon.png" alt="Download" /> Download Unit Project Files</a></p>
+<p>As you learned in the last unit, test cases are groups of tests which share a common test fixture. Inherently this means as the number of tests in any project grows, there will become a need for a significant number of test cases which needed to organized and executed.</p>
+
+<p>Suites are the organizational tool used to establish a reasonable scheme for organizing these test cases, allowing you to create a hierarchy of tests that can be executed as one object.</p>
+
+<h3>Objectives:</h3>
+
+<p>After completing this lesson, you should be able to:</p>
+
+<ul>
+    <li>Create new test case files</li>
+    <li>Create new test suite files</li>
+    <li>Apply [RunWith] metadata in test suites</li>
+    <li>Refactor existing cases for better organization and hierarchy</li>
+</ul>
+
+<h3>Topics</h3>
+
+<p>In this unit, you will learn about the following topics:</p>
+
+<ul>
+    <li>Writing test suites</li>
+    <li>Creating a suite</li>
+    <li>Refactoring test cases within suites</li>
+    <li>Understanding hierarchy and test result reporting</li>
+    <li>Discuss directory structure and approach for new projects</li>
+</ul>
+
+<h2>Writing test suites</h2>
+
+<p>In previous lessons, we have run several test methods, but they have always been contained within a single test case. Given the nature of test fixtures, almost any project is going to require more than a single test case. Many production applications run thousands of different tests, which may make up hundreds of different cases. Remembering the functions in each test case and knowing which to run in a given situation would be difficult, if not impossible.</p>
+
+<p>To keep all of our test cases organized, and to allow us to run these tests as a group, we use a special type of class called a Suite. A test suite is primarily a collection of test cases that will be executed together. To allow further organization and a hierarchical organization, a suite may also contain other suites.</p>
+
+<p>The suite runner is org.flexunit.runners.Suite. This runner interrogates a class looking for each public variable. It determines the type (Class) of the variable and attempts to run that class.</p>
+
+<p>While it is possible to sort the order of suites and test cases, by default the order in which they execute is indeterminate and not governed by the order of their definition in the suite class.</p>
+
+<p><code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class SampleSuite {
+    public var testCase:TestCase;
+    public var anotherTestCase:AnotherTestCase;
+    public var yetAnotherTestCase:YetAnotherTestCase;
+    public var anotherSuite:AnotherSuite;
+}</pre></code></p>
+<h2>Walkthrough 1: Creating a new case for the Constructor Test</h2>
+
+<p>In this walkthrough you will reorganize your test cases and prepare to create a new suite. You will perform the following tasks:</p>
+
+<ul>
+    <li>Create a new case named CircleConstructorTest.</li>
+    <li>Move the <code>shouldThrowRangeError()</code> method out of the BasicCircleTest case into the CircleConstructorTest case.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the BasicCircleTest.as file from the previous exercise.</p>
+    </li>
+    <li>
+        <p>Alternatively, if you didn't complete the previous lesson or your code is not functioning properly, you can import the FlexUnit4Training_wt1.fxp project from the Unit 7/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Creating the CircleConstructorTest.as file</h3>
+
+    </li>
+    <li>
+        <p>In Flash Builder's Package Explorer, select the math.testcases package in which your BasicCircleTest.as file is located. Right click on the package and select New &#62; ActionScript Class as shown below:</p>
+
+        <img alt='PackageExplorer' id='shift' src='../images/unit7/image1.png' />
+        <p class='caption' id='shift'>Figure 1: Package Explorer, creating new objects</p>
+    </li>
+    <li>
+        <p>Set the Package to math.testcases and the Name to CircleConstructorTest, and leave all other fields with the defaults. Click Finish to create the file.</p>
+
+        <img alt='NewActionScriptClass' id='shift' src='../images/unit7/image2.png' /> 
+        <p class='caption' id='shift'>Figure 2: New ActionScript Class window</p>
+    </li>
+    <li>
+        <p>Remove the automatically created constructor from the new ActionScript class, so that it reads as shown.</p>
+
+        <code><pre>package math.testcases {
+    public class CircleConstructorTest {        
+    }
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Highlight and cut the <code>shouldThrowRangeError()</code> method from the BasicCircleTest.as file and paste it into the CircleConstructorTest class.</p>
+
+        <code><pre>public class CircleConstructorTest {     
+    [Test(expects="RangeError")]
+    public function shouldThrowRangeError():void {
+        trace("Test");
+        var someCircle:Circle = 
+            new Circle( new Point( 10, 10 ), -5 );
+    }
+}
+        </pre></code>
+
+        <p>Because you cut and pasted the above function into a new class you will need to manually add the appropriate import statements.</p>
+    </li>
+    <li>
+        <p>Add the import statements for <code>flash.geom.Point</code> and <code>net.digitalprimates.math.Circle</code> to the class.</p>
+    </li>
+    <li>
+        <p>Remove the line that reads <code>trace("Test");</code> from the <code>shouldThrowRangeError()</code> method.</p>
+    </li>
+    <li>
+        <p>Save the CircleConstructorTest.as and the BasicCircleTest.as files.</p>
+
+        <code><pre>package flexUnitTests.cases {
+    import flash.geom.Point;
+
+    import net.digitalprimates.math.Circle;
+
+    public class CircleConstructorTest {
+        [Test(expects="RangeError")]
+        public function shouldThrowRangeError():void {
+            var someCircle:Circle = 
+                          new Circle( new Point( 10, 10 ), -5 );
+        }
+    }
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='FlexUnitTestsPassed' id='shift' src='../images/unit7/image3.png' /> 
+        <p class='caption' id='shift'>Figure 3: FlexUnit tests passed</p>
+
+        <p>Notice that only ten tests were run. Although CircleConstructorTest case has been created, the test runner is unaware of the new test case, and therefore it does not run. In the FlexUnit4Training.mxml, which was generated by Flash Builder, the BasicCircleTest case is the only set of tests pushed into the <code>testsToRun</code> array.</p> 
+        <p>In Walkthrough 2, you will create a test suite in order to run both test cases as well as others you will create.</p>
+    </li>
+</ol>
+
+<h2>Creating a suite</h2>
+
+<p>Suites are simply ActionScript class files with public properties. The class is decorated with two very important pieces of metadata. First, the [Suite] tag, which tells Flash Builder and FlexUnit that this class is intended to be a test suite.</p>
+
+<p><p>Second, the [RunWith] metadata tells FlexUnit to use the org.flexunit.runners.Suite class to execute this class. You will learn more about extensibility and the [RunWith] metadata later in this unit.</p></p>
+<p><code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class mySuite</pre></code></p>
+<h3>Test cases within suites</h3>
+
+<p>Within a test suite, all the test cases and other suites are represented by public properties within the class. The sample suite below includes three test cases and additional suite.</p>
+
+<p><code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class MySuite {
+    public var testCase:TestCase;
+    public var anotherTestCase:AnotherTestCase;
+    public var yetAnotherTestCase:YetAnotherTestCase;
+    public var anotherSuite:AnotherSuite;
+}</pre></code></p>
+<p>The <code>anotherSuite</code> variable is another suite that can contain any number of tests and suites. There is no limit to the hierarchy of test suites and each level of suite is only aware of its immediate children</p>
+
+<p><p>An empty suite (one with no tests or no public tests or suites) will throw an <code>InitializationError</code>.</p></p>
+<h2>Understanding the RunWith metadata</h2>
+
+<p>A primary goal of FlexUnit was extensibility based on unknown future requirements. While FlexUnit 4 natively includes support for FlexUnit 4.x, FlexUnit .9 and Fluint 1.0 style tests, it was imperative to provide developers an easy way to accommodate new functionality without restricting their freedom to FlexUnit's concept of a test. The [RunWith] metadata is one of the primary means of accomplishing this goal.</p>
+
+<p>When the [RunWith] metadata is used on a class file, it overrides all internal logic that FlexUnit uses to determine the appropriate type of test. Instead it specifies a class that implements the IRunner interface which should be used to execute the contents of this file.</p>
+
+<p>FlexUnit simply instantiates the specified runner and hands over all control until the runner is complete. In this way new test runners can be developed that act and work in radically different ways than the standard components but will integrate cleanly and easily.</p>
+
+<p>The suite runner uses this technique to create test suites. As you have seen so far, the standard FlexUnit runner looks for methods marked with the [Test] metadata and executes each. However, suites are radically different. They are simply a class of properties wherein the type specifies the case or suite. In this case the [RunWith] metadata indicates that the Suite class understands how to execute the contents of this class, facilitating the concept of suites.</p>
+
+<p>At every level of test, FlexUnit re-performs this same logic. This means that different cases and suites can use different runners while all co-existing in the same project and top-level suite.</p>
+
+<p>Support for new testing environments can be added by creating new custom runners and using the [RunWith] metadata with the new runner. The suite runner is only one example of the provided runners with FlexUnit 4.x.</p>
+
+<h2>Walkthrough 2: Creating a Test Suite</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Create a test suite to run the two test cases for the Circle class.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the testcases package from the previous exercise.</p> 
+        <p>Alternatively, if you didn't complete the previous lesson or your code is not functioning properly, you can import the FlexUnit4Training_wt2.fxp project from the Unit 7/ Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Create a test suite</h3>
+
+    </li>
+    <li>
+        <p>Create an ActionScript class named CircleSuite in the testcases package. Do not specify a superclass or interfaces.</p> 
+        <p>The Package Explorer should look like this after the suite has been created:</p>
+
+        <img alt='PackageDirectoryStructure' id='shift' src='../images/unit7/image4.png' />
+        <p class='caption' id='shift'>Figure 1: Package directory structure after the suite has been created</p>    
+    </li>
+    <li>
+        <p>Remove the automatically created constructor from the new ActionScript class. Mark the class with <code>[Suite]</code> and <code>[RunWith(" org.flexunit.runners.Suite")]</code> metadata tags, which should be placed above the class declaration.</p>
+
+        <code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class CircleSuite {
+...
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a public variable named <code>test1</code> of type <code>BasicCircleTest</code> and another public variable named <code>test2</code> of type <code>CircleConstructorTest</code> to the class.</p>
+
+        <code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class CircleSuite {
+    public var test1:BasicCircleTest;
+    public var test2:CircleConstructorTest;
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Open the FlexUnit4Training.mxml file.</p>
+    </li>
+    <li>
+        <p>Look under the <code>&#60;fx:Script&#62;</code> block.</p>
+        <p>Replace this line:</p>
+        <code><pre>testsToRun.push( BasicCircleTest );</pre></code>
+        <p>with this line:</p>
+        <code><pre>testsToRun.push( CircleSuite );</pre></code>
+        <p>If you did not use code completion, add the import for testcases.CircleSuite at this time.</p>
+    </li>
+    <li>
+        <p>Save FlexUnit4Training.mxml.</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='TestsPassed' id='shift' src='../images/unit7/image5.png' /> 
+        <p class='caption' id='shift'>Figure 2: FlexUnit tests passed</p>
+    </li>
+</ol>
+
+<h2>Understanding hierarchy</h2>
+
+<p>Suites allow for the creation of a hierarchy that can be extremely useful when dealing with large projects. The nature of suites or cases would allow you to execute a particular case in the hierarchy by itself, or execute it as a part of any of the suites where it is contained within. For example, you could execute Suite 1 to run the cases beneath it, or execute Suite 0 to run all of Suite 1 plus additional cases.</p>
+
+<p><img alt='Hierarchy' src='../images/unit7/hierarchy.png' />
+<p>Test results are not organized by suite inside of Flash Builder premium, which simply sees all of the cases as a flat list. However, it does allow you to see the full package name which still provides some understanding of hierarchy.</p>
+<img alt='FlexUnitResults' src='../images/unit7/image6.png' /></p>
+<h2>Possible directory structures</h2>
+
+<p>The unit test package structure for a project should mirror the suite hierarchy, which, in a perfect world, should mirror the hierarchy of the classes being tested.</p>
+
+<p><p>While there are no rules for how to organize your test cases, the following information can be helpful.</p>
+<ol>
+    <li>Think of the organization in terms of an outline. Each topic and subtopic in the outline gets a new package, recursively.</li>
+    <ol type='a'>
+        <li>Just like an outline shouldn't get a subtopic if there is only one item inside of it, do not create a package for just one case.</li>
+        <li>Do not be afraid of making the packages deep with fewer cases in each.</li>
+    </ol>
+    <li>Each time you create a new package, the package should automatically get a test suite to organize the child cases and suites.</li>
+    <li>Avoid reach down, meaning that a Suite should only include cases in its own package.</li>
+    <li>A suite may include other suites from any package one level below.</li>
+</ol>
+<p>Take the family structure presented, for example.</p>
+<img alt='TestStructure' src='../images/unit7/image7.png' />
+<p>The test structure creates test for a nuclear family. The top level package is testcases, which contains the FamilySuite.as file. Because this application objectifies the nuclear family, the FamilySuite.as file can be arranged accordingly.</p></p>
+<p><code><pre>import tests.children.ChildrenSuite;
+import tests.father.FatherSuite;
+import tests.mother.MotherSuite;</p>
+<p>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class FamilySuite {    <br />
+    public var fatherSuite:FatherSuite;
+    public var motherSuite:MotherSuite;
+    public var childrenSuite:ChildrenSuite;
+}</pre></code></p>
+<p>This is a valid suite despite the fact that it only contains other suites and does not directly contain any test cases.</p>
+
+<ul> 
+    <li><p>The <code>FatherSuite</code> may include a <code>FatherCase</code>, which is a case specifically for testing the Father object, as well as cases, or other suites, to test items within the <code>tests.father.parents</code> package and the <code>tests.father.siblings</code> package.</p></li>
+    <li><p>The <code>MotherSuite</code> includes the <code>MotherCase</code> as well as those cases within the <code>tests.mother.parents</code> package, because the Mother has only one sibling, TwinSisterCase is included in the mother package.</p></li>
+    <li><p>The <code>OldestSonSuite</code> includes the <code>OldestSonCase</code> as well as the <code>WifeCase</code> and an empty package named children.</p></li>
+    <li><p>Finally <code>MiddleDaughterCase</code> and <code>YoungestDaughterCase</code> do not require a separate package or suite, because all of their family members are represented in the available test cases.</p></li>
+</ul>
+
+<p>The important thing to note is that the model for organization is based on the actual entity being tested. We could have easily chosen a father-centric model for organization, one where all cases and suites extend in terms of their relationship to the father. In this case, the family is being tested, and the suites and cases are organized as such.</p>
+
+<p>The architecture allows for naming consistency within different packages. Many families have two sets of Grandparents. Fortunately, both the father's parents and the mother's parents can use the names Grandpa.as and Grandma.as for their class files, and ParentsSuite for their suite files.</p>
+
+<p><img alt='NamingConsistency' src='../images/unit7/image8.png' />
+<p>Also, this organization allows for extensibility. The oldestson package contains an empty package named children, which we can assume is eventually going to contain test cases. If we were to include cousins, for instance, we would want to make suites for the siblings and corresponding packages for them and their children.</p>
+<img alt='EmptyChildrenPackage' src='../images/unit7/image9.png' />
+<p>Although Flash Builder makes it fairly easy to reorganize class files and directory structure, it is ideal to plan out the application ahead of time, and use a structure that brings organization and consistency to your testing.</p></p>
+<h2>Summary</h2>
+
+<ul>
+    <li><p>Test suites are used to run multiple FlexUnit cases or suites.</p></li>
+    <li><p>Tests should be refactored into new cases when:</p></li>
+    <ul>
+        <li><p>They require different fixture</p></li>
+        <li><p>They require different inputs (i.e. valid vs. invalid)</p></li>
+    </ul>
+    <li><p><code>[RunWith= ""]</code> metadata can be used to run suites, FlexUnit .9 tests, Fluint 1.x tests and other developer-provided runners.</p></li> 
+    <li><p>Test package hierarchy should ideally reflect the package hierarchy of the project under test.</p></li>
+</ul>
+
+<h2>Navigation</h2>
+
+<ul>
+    <li><a href="Unit-6.html">Unit 6 - Working with the Test Fixture</a></li>
+    <li><a href="Unit-8.html">Unit 8 - FlexUnit Theories</a></li>
+    <li><a href="../index.html">Table of Contents / Introduction</a></li>
+</ul>
+
+<!-- Home Page Exception -->
+
+
+
+
+</div></div>
+<!-- Wrapper / End -->
+
+
+<!-- Footer -->
+
+<!-- Footer Top -->
+<div id="footer" class="container-fluid paddingbottom" >
+
+
+    <div class="row-fluid">
+
+        <!-- About -->
+        <div class="span3">
+            <div class="footer-headline"><h4>About Us</h4></div>
+            <p>Apache Flex® is a highly productive, open source application framework for building and maintaining expressive web applications that deploy consistently on all major browsers, desktops and devices (including smartphones, tablets and tv). It provides a modern, standards-based language and programming model that supports common design patterns suitable for developers from many backgrounds. Flex applications can be deployed to the ubiquitous Adobe® Flash® Player in the browser, Adobe® AIR™ on desktop and mobile or to native Android™, IOS™, QNX®, Windows® or Mac® applications.</p>
+        </div>
+
+        <!-- Subscribe  -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Subscribe</h4></div>
+            <p>We have two mailing lists, one for SDK developers, and one for SDK users.</p>
+            <p>Developers, send an email to <br>
+                <a href="mailto:dev-subscribe@flex.apache.org">dev-subscribe@flex.apache.org</a>
+            </p>
+            <p>Users, send an email to <br>
+                <a href="mailto:users-subscribe@flex.apache.org">users-subscribe@flex.apache.org</a>
+            </p>
+        </div>
+
+        <!-- Latest Releases -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Latest Releases</h4></div>
+            <p>Apache Flex SDK : <a href="/download-binaries.html">4.12.0 (Mar 2014)</a><br />
+                SDK Installer : <a href="/installer.html">2.7.0 (Oct 2013)</a><br />
+                BlazeDS : <a href="http://sourceforge.net/adobe/blazeds/wiki/Home/">4.6.0 (Nov 2011)</a><br />
+                Flex Mavenizer : <a href="http://svn.apache.org/viewvc/flex/utilities/trunk/mavenizer/"> 4.8.0 (Jan 2013)</a></p>
+        </div>
+
+        <!-- Latest Tweets -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Latest Tweets</h4></div>
+            <a class="twitter-timeline" href="https://twitter.com/ApacheFlex" data-chrome="noheader nofooter noborders noscrollbar" data-widget-id="364567612920852480">Tweets by Apache Flex</a>
+            <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+            <div class="clear"></div>
+        </div>
+
+    </div>
+
+</div>
+<!-- Footer / Bottom -->
+<div id="footer" class="container-fluid" style="background: #111;">
+    <div class="row-fluid">
+        <div class="span12">
+            <div id="footer-bottom">
+                Copyright © 2014 The Apache Software Foundation, Licensed under the Apache License, Version 2.0 <br>
+                Apache Flex, Apache and the Apache feather logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
+                Read more about our privacy policy on our <a href="about-privacy.html">Privacy Policy</a> page.
+                <div id="scroll-top-top"><a href="#" title="Go to Top"></a></div>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+<!-- Footer / End -->
+
+</body>
+
+</html>
\ No newline at end of file

Added: websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-8.html
==============================================================================
--- websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-8.html (added)
+++ websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-8.html Fri Apr  4 01:17:29 2014
@@ -0,0 +1,837 @@
+<!DOCTYPE html>
+<!--[if IE 7 ]><html class="ie ie7" lang="en"><![endif]-->
+<!--[if IE 8 ]><html class="ie ie8" lang="en"><![endif]-->
+<!--[if (gte IE 9)|!(IE)]><!--><html lang="en"><!--<![endif]-->
+
+<head>
+
+    <meta charset="utf-8">
+    <title>Apache Flex® - Unit 8 - FlexUnit Theories
</title>
+
+    <!-- For Mobiles  -->
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
+    <link href='https://fonts.googleapis.com/css?family=Carrois+Gothic' rel='stylesheet' type='text/css'>
+    <!-- CSS -->
+    <link rel="stylesheet" type="text/css" href="/css/bootstrap.css">
+    <link rel="stylesheet" type="text/css" href="/css/fixed-width.css" id="layout">
+    <link rel="stylesheet" type="text/css" href="/css/style.css">
+
+    <!-- Java Script  -->
+    <script src="/js/jquery.js"></script>
+    <script src="/js/custom.js"></script>
+    <script src="/js/selectnav.js"></script>
+    <script src="/js/flexslider.js"></script>
+    <script src="/js/twitter.js"></script>
+    <script src="/js/fancybox.js"></script>
+    <script src="/js/isotope.js"></script>
+    <script src="/js/bootstrap.js"></script>
+    <script src="/js/showcase.js"></script>
+
+    <!-- Google Analytics -->
+    <script type="text/javascript">
+
+        var _gaq = _gaq || [];
+        _gaq.push(['_setAccount', 'UA-37926454-1']);
+        _gaq.push(['_trackPageview']);
+
+        (function() {
+            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+        })();
+
+    </script>
+
+
+</head>
+<body>
+
+<!-- Wrapper Start -->
+<div id="wrapper" class="container-fluid">
+
+
+    <!-- Header -->
+
+
+    <div class="ie-dropdown-fix" >
+
+        <!-- Header -->
+        <div class="row-fluid" id="header">
+
+            <!-- Logo -->
+            <div class="span5">
+
+                <a href="#"><img src="/images/logo_01_fullcolor-sm.png" alt="Apache Flex®" title="Apache Flex®" /></a>
+
+            </div>
+
+            <!-- Social / Contact -->
+            <div class="span3 pull-right">
+
+                <!-- Social Icons -->
+                <ul class="social-icons">
+                    <li class="facebook"><a href="https://www.facebook.com/pages/Apache-Flex/174249699342648">Facebook</a></li>
+                    <li class="twitter"><a href="http://twitter.com/ApacheFlex">Twitter</a></li>
+                    <li class="linkedin"><a href="http://www.linkedin.com/groups/Apache-Flex-Developers-4296888">LinkedIn</a></li>
+                </ul>
+
+                <!-- Apache Logo -->
+                <a href="http://www.apache.org" id="contact-top"><img src="http://www.apache.org/images/feather-small.gif" title="An Apache Project" alt="An Apache Project" /> </a>
+            </div>
+
+        </div>
+        <!-- Header / End -->
+
+        <!-- Navigation -->
+        <div id="navigation" class="margintop">
+            <ul id="nav">
+
+                <li><a href="index.html">Home</a></li>
+
+                <li><a href="#">About Flex</a>
+                    <ul>
+
+                        <li><a href="/about-whatis.html">What is Flex?</a></li>
+                        <li><a href="/about-features.html">Features</a></li>
+                        <li><a href="/about-licensing.html">License &amp; Trademarks</a></li>
+                        <li><a href="/about-people.html">The Team</a></li>
+                        <li><a href="/about-history.html">Project History</a></li>
+                        <li><a href="/about-assets.html">Logo and Assets</a></li>
+                    </ul>
+                </li>
+                <li><a href="#">Community</a>
+                    <ul>
+
+                        <li><a href="/community-getinvolved.html">How to get involved</a></li>
+                        <li><a href="/community-mailinglists.html">Mailing Lists</a></li>
+                        <li><a href="/community-showcase.html">Flex Showcase</a></li>
+						<li><a href="/community-3rdparty.html">Third-Party</a></li>
+                        <li><a href="https://cwiki.apache.org/confluence/display/FLEX/Apache+Flex+Wiki">Wiki <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://blogs.apache.org/flex/">Blog <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#">Development</a>
+                    <ul>
+                        <li><a href="/dev-faq.html">Developer FAQ</a></li>
+                        <li><a href="/dev-sourcecode.html">Source Code</a></li>
+                        <li><a href="https://issues.apache.org/jira/browse/FLEX">Bug-Tracker <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#">Documentation</a>
+                    <ul>
+
+                        <li><a href="/doc-getstarted.html">Getting Started</a></li>
+                        <li><a href="/doc-videos.html">Videos</a></li>
+                        <li><a href="/asdoc/">ASDocs</a></li>
+                        <li><a href="http://help.adobe.com/en_US/flex/using/index.html">Documentation Reference (Old) <i class="icon-share icon-white"></i></a></li>
+
+                    </ul>
+                </li>
+
+                <li><a href="#">About Apache</a>
+                    <ul>
+
+                        <li><a href="http://www.apache.org">The Apache Software Foundation Website <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/contributing.html">Donations <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship <i class="icon-share icon-white"></i></a></li>
+                        <li><a href="http://www.apache.org/foundation/thanks.html">Thanks <i class="icon-share icon-white"></i></a></li>
+                    </ul>
+                </li>
+
+                <li><a href="#" class="download">Download</a>
+                    <ul>
+
+                        <li><a href="/installer.html">Download the SDK Installer (For Application Developers)</a></li>
+                        <li><a href="/download-binaries.html">Download the SDK Binaries (For SDK Developers)</a></li>
+                        <li><a href="/download-source.html">Download the SDK Source Code (For SDK Developers)</a></li>
+                        <li><a href="/download-utilities.html">Download Utilities</a></li>
+                        <li><a href="/download-archive.html">Previous Versions</a></li>
+                    </ul>
+                </li>
+            </ul>
+
+        </div>
+        <div class="nav-shadow"></div>
+        <div class="clear"></div>
+
+    </div>
+    <!-- Navigation / End -->
+
+
+    <!-- Content -->
+
+    
+    <div class="row-fluid">
+
+
+        <!-- Page Title -->
+        <div id="page-title">
+            <h2>Unit 8 - FlexUnit Theories
</h2>
+        </div>
+        <!-- Page Title / End -->
+
+
+    </div>
+    
+
+    <div class="row-fluid">
+
+
+
+<!-- Home Page Exception -->
+
+
+<p><a href="../code/unit4.zip"><img src="../images/DownloadIcon.png" alt="Download" /> Download Unit Project Files</a></p>
+<p>Theories are a tool for testing a class against a potentially infinite set of data points. While theories are a powerful concept, they must work in conjunction with static tests to ensure proper functionality.</p>
+
+<h3>Objectives:</h3>
+
+<p>After completing this lesson, you should be able to:</p>
+
+<ul>
+    <li>Create theories</li>
+    <li>Create theory data points</li>
+    <li>Use assumptions in your theories</li>
+    <li>Use complex objects with theories</li>
+    <li>Use complex objects as data points</li>
+</ul>
+
+<h3>Topics</h3>
+
+<p>In this unit, you will learn about the following topics:</p>
+
+<ul>
+    <li>Understand the use for data points</li>
+    <li>Understanding triangulation of test cases</li>
+    <li>Creating a theory</li>
+    <li>Creating data points</li>
+    <li>Understanding assumptions</li>
+    <li>Understanding the theory success and failure model</li>
+    <li>Using complex objects with theories</li>
+    <li>Using the constructor of the TestCase</li>
+</ul>
+
+<h2>Understanding triangulation of test cases</h2>
+
+<p>When testing formulas, there are a potentially infinite number of values that may be given and return an expected result. It is impossible in these cases to test all possible values that could be passed to a test case.</p>
+
+<p><p>Testing a single case is fairly weak, because any formula could return a hard-coded value. There is very little assurance in a single trial of anything. Likewise, a single test case is just slightly better than not testing at all.</p>
+<p>If a test succeeds in two cases with two different values, already it has exponentially more assurance. If a test succeeds three or more times with three or more values, for each trial added it becomes substantially easier to trust the functionality being tested.</p> 
+<p>A small range of values is acceptable. Granted, it does not cover every case, but it does give you a substantial degree of assurance. A small range of values can also include all the types of values that could be problematic. For instance:</p></p>
+<p><code><pre>public function absoluteValue( value:int ):int {
+    if ( value &#60; 0 ) {
+        return value * -1;
+    } else {
+        return value;
+    }
+}</pre></code></p>
+<p>A simple method like the one presented above should be tested with at least five values: Positive integers, negative integers, 0, NaN, Infinity. That kind of small combination is fairly standard for arithmetic functions, but sometimes it becomes more complicated, particularly when float types are involved in the calculation.</p>
+
+<p><p>While you may not be able to test every case, the more potential values that can be passed through the method to more assurance you have that the method does indeed function directly. We call this concept triangulation.</p></p>
+<h2>Understanding Theories</h2>
+
+<p>A FlexUnit theory is a method marked with the [Theory] metadata. Unlike the test methods you have worked with so far, theory methods can have parameters. Theory methods will be called multiple times with different data points, however, much like a mathematical theory; they are either valid or invalid, there is no sometimes.</p>
+
+<p><p>Any one case that fails disproves the whole theory. Therefore any one time the theory method is called when it fails marks the entire test as a failure.</p>
+<p>A simple theory method:</p></p>
+<p><code><pre>[Theory]
+public function testTheory( value1:Number, value2:Number ):void</pre></code></p>
+<h2>Understanding the use case for data points</h2>
+
+<p>A test like the one in the previous section relies upon good data points to effectively triangulate. The tests you have used so far in this course have been statically coded and passed values to test for functionality. While that works for a small number of tests, it becomes increasingly more difficult to write and maintain as the number of tests and data points grow.</p>
+
+<p>When attempting to triangulate a method, you need to be able to quickly create and add to a vast set of data points which will be provided to the test. In FlexUnit 4.x two special metadata tags named [DataPoint] and [DataPoints] can decorate data to indicate that it should be provided to the available tests as potential data points.</p>
+
+<h2>Creating data points</h2>
+
+<p>A data point is a single variable, or function that returns a value, which will be passed as an argument to a test for testing. A data point:</p>
+
+<ul>
+    <li>Must be defined as static</li>
+    <li>Can be coded statically or be the result of a static method call</li>
+</ul>
+
+<p>For Instance:</p>
+
+<p><code><pre>[DataPoint]
+public static var value1:int = 10;</pre></code></p>
+<p>Data points are an array of variables, or a function that returns an array, used as arguments to a theory. Data points allow you to quickly specify many values that will be passed to a single theory.</p>
+
+<ul>
+    <li>In addition to being decorated with the <code>[DataPoints]</code> metadata, must be decorated with <code>[ArrayElementType("TYPE")]</code> specifying the type of the array elements.</li>
+    <li>Must be static</li>
+    <li>Can be coded statically or be the result of a static method call</li>
+</ul>
+
+<p>For instance:</p>
+
+<p><code><pre>[DataPoints]
+[ArrayElementType("String")]
+public static var stringValues:Array = ["one","two","three" ];</pre></code></p>
+<p>The ArrayElementType metadata describes the type of data in the Array to the theories in this class.</p>
+
+<h2>Creating theories</h2>
+
+<p>Theories are written to test a small function or calculation over a potentially large set of data. Using theories with a range of data, you build assurance that the theory is actually performing the calculation as opposed to just returning the expected result.</p>
+
+<p>Some notes on theories:</p>
+
+<ul>
+    <li>They are decorated with the <code>[Theory]</code> metadata</li>
+    <li>They can take parameters</li>
+    <li>Accepts parameters marked with <code>[DataPoint]</code> and <code>[DataPoints]</code> metadata</li>
+    <li>They run with a special Theory runner</li>
+</ul>
+
+<p><code><pre>[RunWith("org.flexunit.experimental.theories.Theories")]
+public class MyTheoryTest {
+}</pre></code></p>
+<p>Theories run with all matching data points. If any combination of <code>Datapoints</code> fail, the theory fails.</p>
+
+<p><code><pre>[DataPoints]
+[ArrayElementType("Number")]
+public static var radii:Array = [ 1, 2, 3, 4 ];</p>
+<p>[Theory]
+public function testTheory( value1:Number, value2:Number ):void</pre></code></p>
+<p>This theory takes two parameters. All <code>Datapoints</code> referenced with the data type integer will be passed into each of these values for every possible combination.</p>
+
+<p><p>Test process:</p></p>
+<p><code><pre>testTheory( 1, 1 )
+testTheory( 1, 2 )
+testTheory( 1, 3 )
+...
+testTheory( 4, 3 )
+testTheory( 4, 4 )</pre></code></p>
+<h2>Discussion on data typing and conversion</h2>
+
+<p>Marking data points with the <code>[ArrayElementType("Type")]</code> metadata ensures that only the desired input type is contained within the collection. Additionally, it makes sure that these values are passed in wherever a parameter of the specified type is used in a theory.</p>
+
+<p>The following theory takes two number inputs and a string, but there is only a single collection of numbers and a single collection of strings within the class.</p>
+
+<p><code><pre>[DataPoints]
+[ArrayElementType("Number")]
+public static var numbers:Array = [ 1, 2, 3, 4, 5 ];</p>
+<p>[DataPoints]
+[ArrayElementType("String")]
+public static var strings:Array = [ "Mike", "Tom", "Bob", "Cindy" ];</p>
+<p>[Theory]
+public function testNamesAndNumbers( name:String, numberOne:Number, numberTwo:Number ):void {
+    assertTrue( name.length &gt; 0 );
+    assertTrue( numberOne &gt; 0 );
+    assertTrue( numberTwo &gt; 0 );
+    assertTrue( numberOne + numberTwo &gt; 0 );
+    assertTrue( numberOne + numberTwo + name.length &gt; 0 );
+}</pre></code></p>
+<p>Numbers from the number array are used in the numberOne and numberTwo parameters, and the array of strings is used for the name parameter. The theory runs with all possible input combinations.</p>
+
+<p><code><pre>testNamesAndNumbers( "Mike", 1, 1 )
+testNamesAndNumbers( "Mike", 1, 2 ) 
+testNamesAndNumbers( "Mike", 1, 3 ) 
+...
+testNamesAndNumbers( "Cindy", 5, 4 ) 
+testNamesAndNumbers( "Cindy", 5, 5 )</pre></code></p>
+<h2>Walkthrough 1: Creating a Circle Theory</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Create a new theory case for the Circle class.</li>
+    <li>Create a new theory to test Circle radii.</li>
+    <li>Create an array of parameterized data.</li>
+    <li>Add the CircleTheory case to the CircleSuite.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Select the math.testcases package from the previous exercise. Create a new class in the math.testcases package named CircleTheory.as. This class has no superclass or interfaces.</p>
+        <p>Alternatively, if you didn't complete the previous lesson or your code is not functioning properly, you can import the FlexUnit4Training_wt1.fxp project from the Unit 8/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Create the CircleTheory class</h3>
+
+        <p>After the class has been created, the package directory should appear as follows:</p>
+
+        <img alt='PackageDeliveryStructure' id='shift' src='../images/unit8/image1.png' />
+        <p class='caption' id='shift'>Figure 1: Package directory structure</p>
+    </li>
+    <li>
+        <p>Mark the new class with <code>[RunWith("org.flexunit.experimental.theories.Theories")]</code> metadata, which should be placed just above the class definition.</p>
+
+        <code><pre>[RunWith("org.flexunit.experimental.theories.Theories")]
+public class CircleTheory {
+...
+}       </pre></code>
+
+        <h3><br />Creating theories</h3>
+
+    </li>
+    <li>
+        <p>Create a new public function named <code>shouldShowAllRadiiEqual()</code> with a parameter named <code>radius</code> of data type <code>Number</code>. Mark the function with <code>[Theory]</code> metadata:</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllRadiiEqual( radius:Number ):void {
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a variable named <code>circle</code> of type <code>Circle</code> to the <code>shouldShowAllRadiiEqual()</code> method. Instantiate circle with an origin at <code>(0, 0)</code> and the <code>radius</code> parameter passed in as its radius.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllRadiiEqual( radius:Number ):void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), radius );
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the imports for net.digitalprimates.math.Circle and flash.geom.Point at this time.</p> 
+    </li>
+    <li>
+        <p>Add a call to the <code>assertEquals()</code> method. Assert that the <code>circle.radius</code> is equal to the <code>radius</code> parameter.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllRadiiEqual( radius:Number ):void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), radius );
+    assertEquals( radius, circle.radius );
+}       </pre></code>
+
+        <p>If you did not use code-completion, add an import for org.flexunit.asserts.assertEquals at this time.</p>
+    </li>
+    <li>
+        <p>Add a public static array to the class. Fill it with a variety of positive integer values. Here is an example:</p>
+
+        <code><pre>public static var radii:Array = [ 1,2,3,4,5,6,7,8,9,10 ];</pre></code>
+
+    </li>
+    <li>
+        <p>Mark the array with two lines of metadata, <code>[DataPoints]</code> and <code>[ArrayElementType("Number")]</code>.</p>
+
+        <code><pre>[DataPoints]
+[ArrayElementType("Number")]
+public static var radii:Array = [ 1,2,3,4,5,6,7,8,9,10 ];</pre></code>
+
+    </li>
+    <li>
+        <p>Save CircleTheory.as.</p>
+
+        <h3><br />Adding theories to your test suite</h3>
+
+    </li>
+    <li>
+        <p>Open the CircleSuite.as file within the math.testcases package. Add a new public variable named <code>test3</code> with a type of <code>CircleTheory</code>.</p>
+
+        <code><pre>[Suite]
+[RunWith("org.flexunit.runners.Suite")]
+public class CircleSuite {
+    public var test1:BasicCircleTest;
+    public var test2:CircleConstructorTest;
+    public var test3:CircleTheory;
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the import for math.testcases.CircleTheory at this time.</p>
+    </li>
+    <li>
+        <p>Save the CircleSuite.as file.</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='12UnitsPassed' id='shift' src='../images/unit8/image2.png' /> 
+        <p class='caption' id='shift'>Figure 2: FlexUnit tests passed</p>
+    </li>
+</ol>
+
+<h2>Understanding Assumptions</h2>
+
+<p>Assumptions are used in conjunction with theories to limit acceptable data points. Assumptions allow theories to setup basic constraints and limitations for the methods and formulae being tested.</p>
+
+<p><p>Some notes on assumptions:</p>
+<ul>
+    <li>Assumptions use Hamcrest matchers</li>
+    <li>If an assumption fails, the theory will advance to the next set of data points</li>
+    <li>If no <code>Datapoint</code> sets pass the assumptions the test is marked as a failure</li>
+    <li>Assumptions still require an assert or expectation that tests the result</li>
+    <li>For instance</li>
+</ul></p>
+<p><code><pre>assumeThat( value, greaterThan(0) );</pre></code></p>
+<p>If the parameter is greater than 0, the assumption passes and the test moves onto its next line. If the parameter value is not greater than 0 the assumption fails and the runner will move on to the next data point without running any other lines of this test. Even though the assumption fails for values under 0, the test does not fail or throw an error, because those data points have been essentially marked as invalid for the test theory.</p>
+
+<h2>Walkthrough 2: Adding an assumption</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Add invalid data to theory parameters.</li>
+    <li>Create an assumption that handles invalid data.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the CircleTheory.as file from the previous exercise.</p>
+        <p>Alternatively, if you didn't complete the previous lesson or your code is not functioning properly, you can import the FlexUnit4Training_wt2.fxp project from the Unit8/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Adding invalid values to your data points</h3>    
+
+    </li>
+    <li>
+        <p>Add a single negative value to the beginning of the class's radii array. Here is an example:</p>
+
+        <code><pre>public static var radii:Array = [ -5,1,2,3,4,5,6,7,8,9,10 ];</pre></code>
+
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='SingleFailure' id='shift' src='../images/unit8/image3.png' /> 
+        <p class='caption' id='shift'>Figure 1: A single test failure</p>
+
+        <p>The theory failed because -5 is an invalid radius for a Circle object. If one of the theories assertions fails, the entire theory fails.</p> 
+
+        <h3><br />Adding an assumption</h3>
+
+    </li>
+    <li>
+        <p>Add a new line to the <code>shouldShowAllRadiiEqual()</code> method. On the line, add an assumption indicating that this test only works for positive radii. The method should read as follows:</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllRadiiEqual( radius:Number ):void {
+    assumeThat( radius, greaterThan( 0 ) );
+    var circle:Circle = new Circle( new Point( 0, 0 ), radius );
+    assertEquals( radius, circle.radius );
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the import statements for org.flexunit.assumeThat and org.hamcrest.number.greaterThan at this time.</p>
+    </li>
+    <li>
+        <p>Save the CircleTheory.as file.</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='TestsPassed' id='shift' src='../images/unit8/image4.png' />
+        <p class='caption' id='shift'>Figure 2: FlexUnit tests passed</p>
+
+        <p>The <code>assumeThat( radius, greaterThan( 0 ) )</code> statement assures that the theory is only testing radii that are valid, or in this case, positive. The theory ignores the -5 input and all negative inputs thanks to this statement.</p>
+    </li>
+</ol>
+
+<h2>Using complex objects with theories</h2>
+
+<p>FlexUnit 4 theories include support for complex objects as data points. Because ActionScript uses so many complex objects, it's not uncommon to have them passed as arguments in tests and theories. Theories are much more useful given the ability to deal with complex data points.</p>
+
+<p><p>Some notes on complex data points:</p>
+<ul>
+    <li>To use a complex object as data, simply specify it as the <code>ArrayElementType</code> in the <code>DataPoints</code></li>
+    <li>The <code>ArrayElementType</code> requires the full class path for the type, such as <code>flash.geom.Point</code> or <code>mx.collections.ArrayCollection</code>.</li>
+</ul>
+<p>For Instance:</p></p>
+<p><code><pre>[DataPoints]
+[ArrayElementType("flash.geom.Point")]
+Public static var points:Array = [ new Point( 0, 0 ) ];</pre></code></p>
+<h2>Using the constructor of the Theory Case</h2>
+
+<p>Theory case constructors can be used like the constructors of many classes. In test cases and theories, constructors can be passed initial data for use by all or some of the methods within the class. For instance:</p>
+
+<p><code><pre>public class TestCase {</p>
+<div class="codehilite"><pre><span class="k">[DataPoints]</span>
+<span class="k">[ArrayElementType(&quot;flash.geom.Point&quot;)]</span>
+<span class="na">public static var points:Array</span> <span class="o">=</span> <span class="s">[ new Point( 0, 0 ),</span>
+<span class="s">                new Point( 10, 10 ),</span>
+<span class="s">                new Point( -5, 5 ) ];</span>
+
+<span class="k">[DataPoints]</span>
+<span class="k">[ArrayElementType(&quot;Number&quot;)]</span>
+<span class="na">public static var radii:Array</span> <span class="o">=</span> <span class="s">[ 0, 5, 10 ];</span>
+
+<span class="err">public</span> <span class="err">static</span> <span class="err">var</span> <span class="err">circle:Circle</span><span class="c">;</span>
+
+<span class="err">public</span> <span class="err">function</span> <span class="err">TestCase(</span> <span class="err">origin:Point,</span> <span class="err">radius:Number</span> <span class="err">):void</span> <span class="err">{</span>
+    <span class="na">circle</span> <span class="o">=</span> <span class="s">new Circle( origin, radius );</span>
+<span class="err">}</span>
+<span class="err">...</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<p>This method can help to reduce the complexity of the created complex objects, or it can serve to convert existing sets of data points into use within other complex objects.</p>
+
+<p><p>If the complex objects are passed to the class constructor, they no longer need to be passed in as arguments to the theories. The constructor will be run before each test or theory in the case. Each test method can then use the newly instantiated class variables, which will be re-instantiated before each test is run.</p> 
+<p>In this way, the class tends to be more cohesive and about a specific set of data rather than a free for all of unrelated theories working on data points.</p></p>
+<h2>Walkthrough 3: Using Complex Objects as DataPoints</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Create a new theory for testing point distance.</li>
+    <li>Pass Point objects into CircleTheory as DataPoints.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the CircleTheory.as file from the previous exercise.</p> 
+        <p>Alternatively, if you didn't complete the previous lesson or your code is not functioning properly, you can import the FlexUnit4Training_wt3.fxp project from the Unit8/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Create a method for testing points on the circle</h3>
+    </li>
+    <li>
+        <p>Add a private static constant named <code>TOLERANCE</code> of data type <code>Number</code> to the CircleTheory class.</p>
+        <code><pre>private static const TOLERANCE:Number = .0001;</pre></code>
+    </li>
+    <li>
+        <p>Add a new method named <code>shouldShowAllPointsEqual()</code> to the class.</p> 
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual(origin:Point):void {
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Create a new circle with the function's origin argument and a radius of 10.</p> 
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual(origin:Point):void {
+    var circle:Circle = new Circle(origin, 10);
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Call the <code>circle.getPointOnCircle()</code> method with argument <code>Math.PI</code>.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual( origin:Point ):void {
+    var circle:Circle = new Circle( origin, 10 );
+    var pointOnCircle:Point = circle.getPointOnCircle( Math.PI );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Declare a variable named <code>distance</code> of data type <code>Number</code> within the <code>shouldShowAllPointsEqual()</code> method. Instantiate it to <code>Point.distance( origin, pointOnCircle )</code>.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual( origin:Point ):void {
+    var circle:Circle = new Circle( origin, 10 );
+    var pointOnCircle:Point = circle.getPointOnCircle( Math.PI );
+    var distance:Number = Point.distance( origin, pointOnCircle );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a call to the <code>assertThat()</code> method. It should assert that <code>distance</code> variable is <code>closeTo( circle.radius, TOLERANCE )</code>.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual( origin:Point ):void {
+    var circle:Circle = new Circle( origin, 10 );
+    var pointOnCircle:Point = circle.getPointOnCircle( Math.PI );
+    var distance:Number = Point.distance( origin, pointOnCircle );
+
+    assertThat( distance, closeTo( circle.radius, TOLERANCE ) );
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the imports for org.flexunit.assertThat and org.hamcrest.number.closeTo at this time.</p>
+    </li>
+    <li>
+        <p>Add a new public static array named <code>points</code> to the class. Initialize the array with six point values, representing a gamut of potential points.</p> 
+
+        <code><pre>public static var points:Array = [ new Point( 0, 0 ),
+                    new Point( 10, 10 ),
+                    new Point( -5, 5 ),
+                    new Point( 20, -20 ),
+                    new Point( -17, -16 ),
+                    new Point( 5.2, -11.3 ) ];</pre></code>
+
+    </li>
+    <li>
+        <p>Mark the array with <code>[DataPoints]</code> and <code>[ArrayElementType("flash.geom.Point")]</code> metadata. Place these tags on the two lines above the array:</p>
+
+        <code><pre>[DataPoints]
+[ArrayElementType("flash.geom.Point")]
+public static var points:Array = [ new Point( 0, 0 ),
+                    new Point( 10, 10 ),
+                    new Point( -5, 5 ),
+                    new Point( 20, -20 ),
+                    new Point( -17, -16 ),
+                    new Point( 5.2, -11.3 ) ];</pre></code>
+
+    </li>
+    <li>
+        <p>Save CircleTheory.as</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='TestsPassed' id='shift' src='../images/unit8/image5.png' /> 
+        <p class='caption' id='shift'>Figure 1: FlexUnit tests passed</p>
+
+        <h3><br />Adding multiple parameters to a theory</h3>
+
+    </li>
+    <li>
+        <p>Alter the <code>shouldShowAllPointsEqual()</code> method to accept a second parameter named <code>radius</code> of data type <code>Number</code>. The <code>radius</code> parameter will be passed to the circle constructor. You will need to add an <code>assumeThat( radius, greaterThan(0) );</code> statement to the first line of the <code>shouldShowAllPointsEqual()</code> method.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual( origin:Point, radius:Number ):void {
+    assumeThat( radius, greaterThan( 0 ) );
+    var circle:Circle = new Circle( origin, radius );
+    var pointOnCircle:Point = circle.getPointOnCircle( Math.PI );
+
+    var distance:Number = Point.distance( origin, pointOnCircle );
+
+    assertThat( distance, closeTo( circle.radius, TOLERANCE ) );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Save CircleTheory.as</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='TestsPassed' id='shift' src='../images/unit8/image5.png' />
+        <p class='caption' id='shift'>Figure 2: FlexUnit tests passed</p>
+
+        <p>Because the <code>shouldShowAllRadiiEqual()</code> theory passes by constructing valid Circle objects with radius parameters from the radii array, it should be no surprise that the <code>shouldShowAllPointsEqual()</code> method passes using those data points.</p>
+        <p>Valid data points should be consistent for all theories.</p> 
+
+        <h3><br />Add a radians parameter to the test method</h3>
+    </li>
+    <li>
+        <p>Re-Open to the CircleTheory.as file.</p>
+    </li>
+    <li>
+        <p>Add a parameter to the <code>shouldShowAllPointsEqual()</code> method named <code>radians</code> of data type <code>Number</code>. Alter the <code>circle.getPointOnCircle()</code> method so that it takes <code>radians</code> as its arguments.</p>
+
+        <code><pre>[Theory]
+public function shouldShowAllPointsEqual( origin:Point, radius:Number, radians:Number ):void {
+    assumeThat( radius, greaterThan( 0 ) );
+    var circle:Circle = new Circle( origin, radius );
+    var pointOnCircle:Point = circle.getPointOnCircle( radians );
+
+    var distance:Number = Point.distance( origin, pointOnCircle );
+
+    assertThat( distance, closeTo( circle.radius, TOLERANCE ) );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Save CircleTheory.as</p>
+    </li>
+    <li>
+        <p>Run the FlexUnit4Training.mxml file.</p>
+    </li>
+    <li>
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='TestsPassed' id='shift' src='../images/unit8/image5.png' />
+        <p class='caption' id='shift'>Figure 3: FlexUnit tests passed</p>
+
+        <p>The <code>circle.getPointOnCircle()</code> method should return a valid point on the circle regardless of the value of the radians field. Any number within the radii array should be a valid radians argument, and therefore the theory passes with these data points.</p> 
+    </li>
+</ol>
+
+<h2>Summary</h2>
+
+<ul>
+    <li><p>Data points and theories allow many values to be tested without a great deal of complexity.</p></li>
+    <li><p>Metadata:</p></li>
+    <ul>
+        <li><p>Theory classes are marked with <code>[RunWith("org.flexunit.experimental.theories.Theories")]</code> metadata.</p></li>
+        <li><p>Single data points are marked with <code>[DataPoint]</code> metadata.</p></li>
+        <li><p>Arrays of data points are marked with <code>[DataPoints]</code> and <code>[ArrayElementType("TYPE")]</code> metadata.</p></li>
+        <li><p>Theories are marked with <code>[Theory]</code> metadata.</p></li>
+    </ul> 
+    <li><p>Theories can create a test fixture using the class constructor.</p></li>
+    <li><p>Complex objects can be passed as data points.</p></li>
+</ul>
+
+<h2>Navigation</h2>
+
+<ul>
+    <li><a href="Unit-7.html">Unit 7 - Using Suites</a></li>
+    <li><a href="Unit-9.html">Unit 9 - External Data</a></li>
+    <li><a href="../index.html">Table of Contents / Introduction</a></li>
+</ul>
+
+<!-- Home Page Exception -->
+
+
+
+
+</div></div>
+<!-- Wrapper / End -->
+
+
+<!-- Footer -->
+
+<!-- Footer Top -->
+<div id="footer" class="container-fluid paddingbottom" >
+
+
+    <div class="row-fluid">
+
+        <!-- About -->
+        <div class="span3">
+            <div class="footer-headline"><h4>About Us</h4></div>
+            <p>Apache Flex® is a highly productive, open source application framework for building and maintaining expressive web applications that deploy consistently on all major browsers, desktops and devices (including smartphones, tablets and tv). It provides a modern, standards-based language and programming model that supports common design patterns suitable for developers from many backgrounds. Flex applications can be deployed to the ubiquitous Adobe® Flash® Player in the browser, Adobe® AIR™ on desktop and mobile or to native Android™, IOS™, QNX®, Windows® or Mac® applications.</p>
+        </div>
+
+        <!-- Subscribe  -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Subscribe</h4></div>
+            <p>We have two mailing lists, one for SDK developers, and one for SDK users.</p>
+            <p>Developers, send an email to <br>
+                <a href="mailto:dev-subscribe@flex.apache.org">dev-subscribe@flex.apache.org</a>
+            </p>
+            <p>Users, send an email to <br>
+                <a href="mailto:users-subscribe@flex.apache.org">users-subscribe@flex.apache.org</a>
+            </p>
+        </div>
+
+        <!-- Latest Releases -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Latest Releases</h4></div>
+            <p>Apache Flex SDK : <a href="/download-binaries.html">4.12.0 (Mar 2014)</a><br />
+                SDK Installer : <a href="/installer.html">2.7.0 (Oct 2013)</a><br />
+                BlazeDS : <a href="http://sourceforge.net/adobe/blazeds/wiki/Home/">4.6.0 (Nov 2011)</a><br />
+                Flex Mavenizer : <a href="http://svn.apache.org/viewvc/flex/utilities/trunk/mavenizer/"> 4.8.0 (Jan 2013)</a></p>
+        </div>
+
+        <!-- Latest Tweets -->
+        <div class="span3">
+            <div class="footer-headline"><h4>Latest Tweets</h4></div>
+            <a class="twitter-timeline" href="https://twitter.com/ApacheFlex" data-chrome="noheader nofooter noborders noscrollbar" data-widget-id="364567612920852480">Tweets by Apache Flex</a>
+            <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+            <div class="clear"></div>
+        </div>
+
+    </div>
+
+</div>
+<!-- Footer / Bottom -->
+<div id="footer" class="container-fluid" style="background: #111;">
+    <div class="row-fluid">
+        <div class="span12">
+            <div id="footer-bottom">
+                Copyright © 2014 The Apache Software Foundation, Licensed under the Apache License, Version 2.0 <br>
+                Apache Flex, Apache and the Apache feather logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.
+                Read more about our privacy policy on our <a href="about-privacy.html">Privacy Policy</a> page.
+                <div id="scroll-top-top"><a href="#" title="Go to Top"></a></div>
+            </div>
+        </div>
+    </div>
+
+</div>
+
+<!-- Footer / End -->
+
+</body>
+
+</html>
\ No newline at end of file