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 [4/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-16.html
==============================================================================
--- websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-16.html (added)
+++ websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-16.html Fri Apr  4 01:17:29 2014
@@ -0,0 +1,689 @@
+<!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 16 - Allowing Your Tests to Function with Continuous Integration
</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 16 - Allowing Your Tests to Function with Continuous Integration
</h2>
+        </div>
+        <!-- Page Title / End -->
+
+
+    </div>
+    
+
+    <div class="row-fluid">
+
+
+
+<!-- Home Page Exception -->
+
+
+<p><a href="../code/unit16.zip"><img src="../images/DownloadIcon.png" alt="Download" /> Download Unit Project Files</a></p>
+<p>Continuous integration testing is another necessity of the complex application development environment. Generally, when many people and external forces interact with a deployed or actively developed application, quality control measures must be in place for the application's full functionality. Continuous integration systems should run application tests automatically, and some can be configured to do so.</p>
+
+<h3>Objectives:</h3>
+
+<p>After completing this lesson, you should be able to:</p>
+
+<ul>
+    <li>Setup FlexUnit project builds with Apache Ant</li>
+    <li>Run FlexUnit tests within the Hudson continuous integration environment</li>
+</ul>
+
+<h3>Topics</h3>
+
+<p>In this unit, you will learn about the following topics:</p>
+
+<ul>
+    <li>Understanding continuous integration</li>
+    <li>Examining a build script</li>
+    <li>Hudson</li>
+    <li>Understanding listeners</li>
+    <li>Failure and Success reporting options</li>
+</ul>
+
+<h2>Understanding continuous integration</h2>
+
+<p>Continuous Integration is a software development practice where members of a development team integrate their source code changes frequently; typically each developer integrates their changes at least once per day. This practice leads to multiple integrations throughout the day and with every integration the changes are verified by an automated build (which includes testing) to detect integration errors as quickly as possible.</p>
+
+<p><p>Many tools exist to support a CI environment and make the process automated. Some of the common ones include:</p>
+<ul>
+    <li>Hudson</li>
+    <li>Cruise Control</li>
+    <li>Continuum</li>
+</ul>
+<p>CI systems generally include a source repository, an automated build including build script, self testing code, joint commit by developers, an integration machine and, frequently, automated deployment.</p>
+<p>CI builds commonly use the following process:</p>
+<ul>
+    <li>Developers run local builds and tests on code changes.</li>
+    <li>Developers check in code into the main repository.</li>
+    <li>An automated build server monitors the repository.</li>
+    <li>New code is checked into a project build and continuously integrated and tested.</li>
+    <li>Test results are available to all developers on the project and reported in real time.</li>
+</ul></p>
+<h2>Understanding listeners</h2>
+
+<p>Listeners act as a communication between the test runners and a reporting device. If a runner acts as the worker, the listener acts as the foreman, reporting the results of the workers labors.</p>
+
+<p>All listeners implement the IRunListener interface. FlexUnit 4 may use any number of listeners, each will be called as a test completes. It is also possibly to write custom listeners further extending the framework.</p>
+
+<p>There are several base listeners included in FlexUnit.</p>
+
+<h3>UIListener</h3>
+
+<ul>
+    <li>A separate library which allows visual reporting of results</li>
+    <li>Accepts user interaction</li>
+    <li>Gives detailed information about test run times, passing, failing, ignores and failure messages</li>
+</ul>
+
+<h3>CIListener</h3>
+
+<ul>
+    <li>Separate library listener project</li>
+    <li>Creates a socket connection to communicate results over a connection</li>
+    <li>As part of CI, communicates and reports results to the FlexUnit Ant task</li>
+</ul>
+
+<h3>XMLListener</h3>
+
+<ul> 
+    <li>Creates an XML report for tests</li>
+    <li>Primarily used by the Flashbuilder FlexUnit plugin</li>
+    <li>Can be customized to report XML across different sockets</li>
+</ul>
+
+<h2>Walkthrough 1: Using the CIListener</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Edit the application to use the CIListener</li>
+</ul>
+
+<h3>Adding the CIListener</h3>
+
+<ol>
+    <li>
+        <p>Import the FlexUnit4Training.fxp project from the Unit 16/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+    </li>
+    <li>
+        <p>Open the FlexUnit4Training.mxml file.</p>
+    </li>
+    <li>
+        <p>Find and remove the <code>FlexUnitTestRunnerUI</code> component with id <code>testRunner</code> from the application file.</p>  
+        <p>You are removing this section of code as you will no longer be using the UIRunner.</p>
+
+        <s>&#60;flexui:FlexUnitTestRunnerUI id="testRunner"/&#62;</s>
+
+        <p>Continuous integration servers are autonomous. In addition to creating unnecessary overhead, a UIRunner prevents FlexUnit from running in a headless environment.</p>
+    </li>
+    <li>
+        <p>Within the <code>&#60;fx:Script&#62;</code> block, there is a method named <code>onCreationComplete()</code>. Remove the body of this method, leaving just the empty shell of the method.</p>
+
+<code><pre>private function onCreationComplete():void {
+}</pre></code>
+
+    </li>
+    <li>
+        <p>Within the <code>&#60;fx:Script&#62;</code> block add a new public variable named <code>core</code> of type <code>FlexUnitCore</code>.</p>  
+
+        <code><pre>public var core:FlexUnitCore;</pre></code>
+
+        <p>If you did not use code-completion, add the import statement for and org.flexunit.runner.FlexUnitCore at this time.</p>
+        <p>The <code>core</code> acts as our runner; we will be adding the <code>CIListener</code> to the core listeners.</p>
+    </li>
+    <li>
+        <p>In the <code>onCreationComplete()</code> method instantiate the <code>core</code> variable to a new <code>FlexUnitCore()</code>. Call the <code>core.addListener()</code> method on the next line, passing it an argument of <code>new CIListener()</code>. On the next line call the <code>core.run( currentRunTestSuite() )</code>.</p> 
+
+<code><pre>private function onCreationComplete():void {
+    core = new FlexUnitCore();
+    core.addListener( new CIListener() );
+}</pre></code>
+
+    </li>
+    <li>
+        <p>On the following line, call <code>core.run()</code> passing <code>currentRunTestSuite()</code> as its argument.</p> 
+
+<code><pre>private function onCreationComplete():void {
+    core = new FlexUnitCore();
+    core.addListener( new CIListener() );
+    core.run( currentRunTestSuite() );
+}</pre></code>
+
+        <p>If you did not use code-completion, add the import statement for org.flexunit.listeners.CIListener at this time.</p>
+    </li>
+    <li>
+        <p>Save this mxml file. Do not run it at this time.</p>
+    </li>
+</ol>
+
+<h2>Examining an Ant build script</h2>
+
+<p>A build script is an XML configuration file to run compiling and, in some cases, testing of the app. The build file acts as an instruction manual to the CI server on what files to include and what tests to run. It may also contain additional behaviors.</p>
+
+<p>Scripts are made up of a project, optional properties, optional task definitions and a series of 'targets' which must include at least one default target.</p>
+
+<h3>Project tag</h3>
+
+<ul>
+    <li>Acts as the build header</li>
+    <li>name - name of the project</li>
+    <li>default - the default target, or command, to run when the build is run</li>
+    <li>basedir - Base directory for all work. If none is specified, Ant uses the build file directory as base directory</li>
+    <li>Project tag structure</li>
+</ul>
+
+<p><code><pre>&#60;project name=<i>"project_name"</i> basedir=<i>"project_base"</i> default=<i>"default_target"</i> &#62;</pre></code></p>
+<h3>Property tag</h3>
+
+<ul>
+    <li>Frequently used to create shorthand variables for directory locations</li>
+    <li>Also used to specify directories of task targets</li>
+    <li>Property tag structure</li>
+</ul>
+
+<p><code><pre>&#60;property name=<i>"property_name"</i> location=<i>"property_location"</i> /&#62;</pre></code></p>
+<h3>Taskdef tag</h3>
+
+<ul>
+    <li>Tasks define the custom behavior to be used with the build</li>
+    <li>Frequently built into a jar file</li>
+    <li>The taskdef tag defines the location of a task within the jar</li>
+    <li>Task definition tag structure</li>
+</ul>
+
+<p><code><pre>&#60;taskdef resource=<i>"task_location_within_jar"</i> classpath=<i>"task_jar_location"</i> /&#62;</pre></code></p>
+<h3>Target tag</h3>
+
+<ul>
+    <li>Creates possible start points for where the build should begin</li>
+    <li>Targets may depend on other targets</li>
+    <li>The compile target, common in most Flex builds, will depend on directory construction</li>
+    <li>In the case of testing, the test target will depend on the application being compiled</li>
+    <li>If a target has dependencies, the dependencies will be run when the target is run</li>
+    <li>Target tag structure</li>
+</ul>
+
+<p><code><pre>&#60;target name=<i>"target_name"</i> depends=<i>"target_dependencies"</i>&#62;</pre></code></p>
+<h3>Task</h3>
+
+<ul>
+    <li>Each task is a job or file to be run as part of the build</li>
+    <li>A task is a custom piece of code to be executed during the build</li>
+    <li>There are many common tasks included with Ant</li>
+    <li>We are also concerned with the compile task, FlexUnit task and delete task</li>
+    <li>Each task may have its own unique properties</li>
+    <li>Common task tag structure</li>
+</ul>
+
+<p><code><pre>&#60;taskname id=<i>"task_id"</i> attribute1=<i>"..."</i> attribute2=<i>"..."</i> ... /&#62;</pre></code> </p>
+<ul>
+    <li>For building projects with Hudson we will be using 6 tasks, Flex Ant task, FlexUnit task, JUnit report task, copy task, zip task and delete task</li>
+    <li>The flex ant task consists of the following tasks</li>
+    <ul>
+        <li>mxmlc - Application compiler for SWFs</li>
+        <li>compc - Component compiler for SWFs and RSLs</li>
+        <li>html-wrapper - Generates wrapper and supporting files</li>
+        <li>asdoc - Generates ASDoc output</li>
+    </ul>
+    <li>The flexunit task which consists solely of the flexunit task</li>
+    <li>The junitreport task, which allows viewing of JUnit style reports</li>
+    <li>The delete task, which will be used as a clean target</li>
+    <li>Copy task, for copying files</li>
+    <li>Zip task, for zipping files</li>
+</ul>
+
+<h2>Hudson</h2>
+
+<p>A popular, open-source, continuous integration server, Hudson is simple to set up, configure and use. It can monitor multiple jobs, and through use of the FlexUnitAntTask, can make automating testing virtually a painless process.</p>
+
+<p>In order to use Hudson, it requires that Ant and/or Maven be installed on the CI system. It may be deployed through the .war file to an Apache, Tomcat, Glassfish or other HTTP server project. Hudson may also be used by way of the Windows service on a Windows machine, or integrated directly with many Linux distributions.</p>
+
+<p>For more information about Hudson and its capabilities, visit:</p>
+
+<p><a class='contentlink' href='http://hudson-ci.org' target='blank'>http://hudson-ci.org</a></p>
+<h2>Failure and Success reporting options</h2>
+
+<p>The FlexUnit Ant Task allows several options for test reporting</p>
+
+<ul>
+    <li><p>haltonfailure=true|false</p></li>
+    <ul>
+        <li><p>If true, when a failure or error is encountered will complete all currently executing tests then cancel the run</p></li>
+    </ul>
+    <li><p>verbose=true|false</p></li>
+    <ul>
+        <li><p>If true, reports the complete failure message for each failed test</p></li>
+        <li><p>If false, reports number of tests passed and failed only</p></li>
+    </ul>
+    <li><p>port=&#60;port results will be reported on, default is CIListener port&#62;</p></li>
+    <li><p>timeout=&#60;length of time to wait for runner to send results before considering test a failure&#62;</p></li>
+    <li><p>failureproperty=&#60;property name to set to <code>true</code> if any tests fail&#62;</p></li>
+</ul>
+
+<h2>Walkthrough 2: Running your tests from Hudson test launch</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Prepare a debug projector</li>
+    <li>Prepare an Ant build file</li>
+    <li>Install Ant and Hudson</li>
+    <li>Setup your environment to run tests from Hudson</li>
+</ul>
+
+<h3>Import the CI Project</h3>
+
+<ol>
+    <li>
+        <p>Import the FlexUnitTraining_wt2.fxp contained in Unit 16/Start folder.</p>
+        <p>Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3><br />Preparing the debug projector</h3>
+
+    </li>
+    <li>
+        <p>Navigate to Unit 16/FlexUnitCI and find the file flashplayer_sa_win.exe (Windows users) or flashplayer_10_sa_debug.app.zip (Mac users). This is the debug version of the standalone FlashPlayer. Copy it to your local file system somewhere you will remember.</p>  
+        <p>In this walkthrough, you will associate swf files with the standalone, debug player. Failure to associate SWF files with a standalone FP will cause Ant builds to fail. This requires administrator privileges.</p>
+    </li>
+    <li>
+        <p>Windows Users: Return to the FlexUnitCI folder. Right-click on the TestSwf.swf and select <b>Open with...</b>. If an expanding menu appears, instead click <b>choose program</b>. This should open the following screen:</p>
+
+        <img alt='WindowsOpenWith' id='shift' src='../images/unit16/image1.jpeg' />
+
+        <p>Depending on your version, the dialog may appear slightly different.  Click on <b>Browse...</b> and select the standalone player you saved earlier.  Click OK.  The file will attempt to open and throw a SecurityError. This is normal. Click Dismiss and close the player.</p>
+        <p>Mac Users: Return to the FlexUnitCI folder. Right-click, or if using a single mouse button control-click, on the file <b>TestSwf.swf</b> and select <b>Get Info</b>. In this dialogue you will see a section titled <b>Open With</b>.</p>
+
+        <img alt='MacOpenWith' id='shift' src='../images/unit16/image2.png' /> 
+        <p>Select the drop down menu and click <b>Other...</b> When the browser box opens, navigate to the location you saved the debug player and select that file.</p>
+
+        <h3><br />Prepare the Ant build file</h3>
+
+        <p>Continuous integration projects require a build file.  Since you will be using Ant along with Hudson, you need a build.xml file.</p>
+    </li>
+    <li>
+        <p>Open the build.xml.</p>  
+        <p>You will need to make some modifications to this file for it to work with your project build. You will see a heading that reads: <b>Setup paths for build</b>.</p>  
+        <p>If you changed the organization of your project, make sure these paths reflect those changes.</p>
+
+        <img alt='BuildPath' id='shift' src='../images/unit16/image3.png' />
+
+        <p>You will also see a heading <code>&#60;!--Setup Flex and FlexUnit ant tasks --&#62;</code>.  Here you will need to modify the path locations of your tasks as well as set the <code>FLEX_HOME</code>.</p>
+    </li>
+    <li>
+        <p>First, navigate to your Flex SDK. In most cases, your Flex SDK should be located at root/Program Files/Adobe/Adobe Flash Builder 4/sdks.</p> 
+
+        <code><pre>&#60;property name="FLEX_HOME" 
+ location="rootpath:/Program Files/Adobe/Adobe Flash Builder 4/sdks/4.1.0/" /&#62;</pre></code>
+
+        <p>It is highly recommended you use Flex 4.1 SDK. Keep every directory in this walkthrough relative to the FLEX_HOME directory, this way the build file is guaranteed to reference these correctly.</p>
+
+        <h3><br />Install Ant and Hudson</h3>
+
+    </li>
+    <li>
+        <p>Navigate to Unit 16/FlexUnitCI.  Copy this entire directory to the root drive.</p>  
+        <p>You may copy it to another location; however this guide assumes you have copied it to this location. If you do not, be sure to adjust all directory references to your installed location.</p>
+    </li>
+    <li>
+        <p>Navigate to the URL:  <a class='contentlink' href='https://hudson.dev.java.net/hudson.jnlp' target='_blank'>https://hudson.dev.java.net/hudson.jnlp</a></p>
+    </li>
+    <li>
+        <p>Choose to download and run the hudson.jnlp file.</p>
+        <p>After the Java Web Start has completed you should see a startup dialog:</p>
+
+        <img alt='HudsonConsole' id='shift' src='../images/unit16/image4.jpeg' />
+
+        <p>This is the Hudson test drive. For our purposes this is sufficient. However, if you are running Hudson through your CI machine you will want to install the windows service or console app depending on your OS.</p>
+    </li>
+    <li>
+        <p>Open your browser and navigate to the <a class='contentlink' href='http://localhost:8080/' target='_blank'>http://localhost:8080/</a></p>
+        <p>You should see the Hudson start page.</p>        
+    </li>
+    <li>
+        <p>On the left is a menu of options. Click on <b>Manage Hudson</b> and navigate to <b>Configure System</b>. Here, you will need to specify the Ant location.</p>
+    </li>
+    <li>
+        <p>Go to the sub heading <b>Ant</b> and click the <b>Add Ant</b> button.  For the name, specify 'FlexUnit Intro Ant'. Uncheck <b>Install automatically.</b></p>
+    </li>
+    <li>
+        <p>In the <b>ANT_HOME</b> field, specify the install directory of your Ant installation. If you used the walkthroughs location, specify 'root/FlexUnitCI/Ant'.</p>
+
+        <img alt='' id='shift' src='../images/unit16/image5.jpeg' />
+    </li>
+    <li>
+        <p>Navigate to the bottom of the page and click <b>Save</b>.</p>
+    </li>
+    <li>
+        <p>On the left hand menu, click <b>New Job</b>.</p>
+    </li>
+    <li>
+        <p>Give the job a name of FlexUnitCI Intro. Select <b>Build a free-style software project</b>. This version will allow you to build directly from an Ant script.</p>
+
+        <img alt='NewProjectPage' id='shift' src='../images/unit16/image6.jpeg' />
+
+        <p>You will now see the new project page. You may at this time assign a description to the project. Take note of the Source Code Management settings.  The SCM is what will turn our build into a continually integrating project.  Normally we would specify our SCM and pass the location of the SCM. Hudson would then be pushed any changes to the repository and immediately execute a build. However, since we do not have any SCM for this project we will be executing manual builds.</p>
+    </li>
+    <li>
+        <p>Leave this option as <b>None</b>.</p>
+
+        <img alt='None' id='shift' src='../images/unit16/image7.png' />
+    </li>
+    <li>
+        <p>Under the heading <b>Build</b>, add a new build step. Click on the drop down and select <b>Invoke Ant</b>. For the <b>Ant Version</b> select the <b>FlexUnit Intro Ant</b>.  Under <b>Targets</b> enter 'test'. This will cause Hudson to run the test target every time a build is run.</p>
+    </li>
+    <li>
+        <p>Click <b>Save</b>.</p>
+    </li>
+    <li>
+        <p>You should now be taken to the project homepage. Right now this project will do nothing. You need to specify a workspace.  To do so, select <b>Workspace</b> from the main screen. This can also be accessed from the menu on the left.</p>
+
+        <img alt='Workspace' id='shift' src='../images/unit16/image8.png' /> 
+
+        <p>You will receive an error:</p>
+
+        <img alt='Error' id='shift' src='../images/unit16/image9.jpeg' />
+
+        <p>This is completely expected. Hudson needs to execute a new build to configure the workspace.</p>
+    </li>
+    <li>
+        <p>Select <b>Run a build</b>.</p>  
+        <p>You should see new Build History menu on the left, it will update with the new build.  At completion, this build should fail (red dot indicates failure). The build will fail because the current target does not exist. However, the workspace setup is now complete.</p>
+    </li>
+    <li>
+        <p>Click on the workspace link in the left-hand menu again.</p>
+        <p>You should now see:</p>
+
+        <img alt='NoFiles' id='shift' src='../images/unit16/image10.jpeg' /> 
+        <p>Hudson is expecting the base directory of your project which should also contain the build.xml. Unfortunately, since we are not using a SCM, this directory will not populate correctly. We need to add the files directly to the workspace.</p>
+    </li>
+    <li>
+        <p><i>Windows</i>: Navigate to: C:/Documents and Settings/&#60;username&#62;/.hudson/jobs/FlexUnitCI Intro/workspace</p>  
+        <p><i>Mac</i>: Navigate to: Users/&#60;username&#62;/.hudson/jobs/FlexUnitCI Intro/workspace</p>
+    </li>
+    <li>
+        <p>This is the default location of the test launch workspace. Copy <b>all</b> files contained within the FlexUnit4Training project directory into this directory.</p>
+    </li>
+    <li>
+        <p>Refresh the Hudson page in your browser.</p>
+    </li>
+    <li>
+        <p>Hudson should now show the current contents of your project.</p>
+
+        <img alt='CurrentContents' id='shift' src='../images/unit16/image11.jpeg' /> 
+
+        <p>The project is now ready to be built. Since we are running this from the Test Launch and do not have a SCM specified, we will need to run manual builds.</p>
+    </li>
+    <li>
+        <p>Select <b>Build Now</b> from the menu on the left.</p>  
+        <p>Build now will force an immediate build on any files currently in the workspace.  This should return a success (blue dot on the left under build history.)</p> 
+
+        <img alt='BuildHistory' id='shift' src='../images/unit16/image12.jpeg' />
+
+        <p>During test execution, you will see the standalone player load with a blank screen. This is normal and will close automatically. Do not close this manually or your build may fail.</p>
+    </li>
+    <li>
+        <p>Click on <b>build #2</b>.</p> 
+        <p>This is the details view of the build. Since we have verbose set to true in the build file, we can view the details of each run.</p>
+    </li>
+    <li>
+        <p>Click on <b>Console Output</b>. Here will print detail of each test. Failures will also appear here.</p>
+        <p>Since JUnit reports were created for the test run, you may also view these.</p>
+    </li>
+    <li>
+        <p>Click on <b>Back to Project</b> in the left hand menu. Then click on <b>Workspace</b>. This will open the current workspace setup. Click on target then report then html. Select index.html to see the detailed JUnit report.</p>
+    </li>
+    <li>
+        <p>Congratulations, you have now completed your first Hudson test run.</p>
+        <p>Hudson will not auto build when new changes are made to the main project.  Because we had to copy the build files manually any new changes will also need to be manually copied. This is not necessary in a server version where a SCM tool has been specified for the project. Hudson will pull any new changes and create a new build automatically.</p>
+    </li>
+</ol>
+
+<h2>Navigation</h2>
+
+<ul>
+    <li><a href="Unit-15.html">Unit 15 - Creating Testable Code</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-4.html
==============================================================================
--- websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-4.html (added)
+++ websites/staging/flex/trunk/content/flexunit/tutorial/flexunit/Unit-4.html Fri Apr  4 01:17:29 2014
@@ -0,0 +1,983 @@
+<!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 4 - FlexUnit Basics
</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 4 - FlexUnit Basics
</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>FlexUnit 4.x tests are simply methods that are decorated with special metadata. They setup conditions, execute code and make assertions about expected results.</p>
+
+<p><p>These methods are grouped together by common themes and executed often to ensure consistent, functional code.</p></p>
+<h3>Objectives:</h3>
+
+<p>After completing this lesson, you should be able to:</p>
+
+<ul>
+    <li>Explain the basics of unit tests and test metadata</li>
+    <li>Perform basic assertions in multiple unit tests</li>
+</ul>
+
+<h3>Topics</h3>
+
+<p>In this unit, you will learn about the following topics:</p>
+
+<ul>
+    <li>Testing a unit</li>
+    <li>Examining a test</li>
+    <li>Creating tests</li>
+</ul>
+
+<h2>Testing a Unit</h2>
+
+<h3>Understanding a Unit</h3>
+
+<p>A unit is the smallest block of code that can be isolated and tested independently.</p>
+
+<p><p>Suppose you had a table lamp that was not working properly. You might first try changing the light bulb to see if that fixes the issue. Perhaps you would try that light bulb in another fixture or move the lamp to another room to try another outlet. These are all steps to isolate a problem and realizations of the idea behind testing units.</p>
+<p>When the lamp is fully assembled with light bulb in place and plugged into the wall it is not possible to definitively see where an issue might exist. There could be an issue with the outlet, cord, switch, wiring or bulb. You can only begin to determine the problem by isolating one system at a time and testing it. If you could not change the light bulb, move the lamp, or disassemble it, your ability to test would only be at the whole system level. This likely means you throw away your lamp each time the bulb burns out.</p>
+<p>While a lamp is a relatively simple example, the average class in your application is likely not. To be able to test a class properly, you need to ensure it is capable of being isolated and then test each piece in an isolated fashion.</p>
+<p>To successfully unit test a class, you will:</p>
+<ul>
+    <li>Generally write at least one test for each method of a class.</li>
+    <li>Write one test for every possible outcome of a method with conditional logic.</li>
+    <li>Test both valid/expected and invalid/unexpected input to your methods.</li>
+</ul>
+<p>This is only possible if you can test one isolated object at a time.</p></p>
+<h3>The Need for Seams</h3>
+
+<p>We call the point where objects can be separated from each other seams. Continuing with the lamp example, the light bulb socket and wall plug are both seams. Seams allow us to isolate an object and ensure that we are only testing one object at a time.</p>
+
+<p>Let's examine the following piece of code:</p>
+
+<p><code><pre>public class TestSeams {
+    private var someMathObj:SomeMathClass = new SomeMathClass();</p>
+<div class="codehilite"><pre><span class="n">public</span> <span class="k">function</span> <span class="n">findDistance</span><span class="p">(</span> <span class="n">a</span><span class="p">:</span><span class="n">Number</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span><span class="n">Number</span> <span class="p">):</span><span class="n">Number</span> <span class="p">{</span>
+    <span class="n">var</span> <span class="n">difference</span><span class="p">:</span><span class="n">Number</span> <span class="p">=</span> <span class="p">(</span> <span class="n">b</span> <span class="o">-</span> <span class="n">a</span> <span class="p">);</span>
+    <span class="n">var</span> <span class="n">distance</span><span class="p">:</span><span class="n">Number</span> <span class="p">=</span> <span class="n">someMathObj</span><span class="p">.</span><span class="nb">abs</span><span class="p">(</span> <span class="n">difference</span> <span class="p">);</span>
+    <span class="k">return</span> <span class="n">distance</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<p>Unfortunately, you cannot test the <code>findDistance()</code> method alone. That method depends upon <code>SomeMathClass</code> and its <code>abs()</code> function. Therefore, it cannot be isolated. Any attempt to test this method results in testing the code in the TestSeams class, an unknown amount in the SomeMathClass, and the integration between the classes.</p>
+
+<p>When creating new code you must keep the need for seams in mind. Not only does it facilitate testable code, it also has the side effect of creating loosely coupled code with a minimum of interwoven dependencies.</p>
+
+<h3>Examining the Circle Class and the Circle Layout</h3>
+
+<p>Let's take a look at the Circle class and the <code>getPointOnCircle()</code> method.</p>
+
+<p><code><pre>public function getPointOnCircle( t:Number ):Point {
+    var x:Number = origin.x + ( radius * Math.cos( t ) );
+    var y:Number = origin.y + ( radius * Math.sin( t ) );</p>
+<div class="codehilite"><pre><span class="k">return</span> <span class="n">new</span> <span class="n">Point</span><span class="p">(</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="p">);</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<p>In this unit of code:</p>
+
+<ul>
+    <li>The method takes a single argument, <code>t</code>.</li>
+    <li>The method calculates the point on a circle using the <code>origin</code> and <code>radius</code> properties.</li>
+    <li>The <code>origin</code> and <code>radius</code> properties are set in the Circle class constructor.</li>
+    <li>The method depends upon the static Math class, which is unfortunate. It could use better seams but is typical of methods you might encounter in real world classes.</li>
+</ul>
+
+<p>A unit test for <code>getPointOnCircle()</code> would need to test:</p>
+
+<ul>
+    <li>For a given t, origin, and radius, does the returned point match what is expected?</li>
+    <li>What happens when invalid values of t, origin, and radius are provided to this method?</li>
+</ul>
+
+<p>As you can see, most units will need more than one test to fully validate the unit's function.</p>
+
+<p>Here is a unit from the CircleLayout class:</p>
+
+<p><code><pre>public function getLayoutRadius( contentWidth:Number, contentHeight:Number ):Number {
+    var maxX:Number = (contentWidth/2)<em>.8;
+    var maxY:Number = (contentHeight/2)</em>.8;
+    var radius:Number = Math.min( maxX, maxY );</p>
+<div class="codehilite"><pre><span class="k">return</span> <span class="n">Math</span><span class="p">.</span><span class="n">max</span><span class="p">(</span> <span class="n">radius</span><span class="p">,</span> 1 <span class="p">);</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<p>While not perfect, this unit has a couple testing advantages over the previous method:</p>
+
+<ul>
+    <li>All the required values for the computation are passed as arguments.</li>
+    <li>Save for the Math class, this method has no external dependencies.</li>
+</ul>
+
+<p>A unit test for this method would need to test:</p>
+
+<ul>
+    <li>For a given set of <code>contentWidth</code> and a <code>contentHeight</code>, is the proper value returned?</li>
+    <li>If an invalid <code>contentWidth</code> or <code>contentHeight</code>, does the expected behavior occur?</li>
+</ul>
+
+<h3>Examining a Test Case</h3>
+
+<p>As you learned in the previous unit, a test case is merely a collection of individual test methods that test related behaviors. Each of the methods of a test case is decorated with [Test] metadata to signal to the FlexUnit framework that a method is a test. The [Test] metadata tag can also accept user defined attributes for descriptive and organizational purposes</p>
+
+<p><code><pre>[Test(description="Test is supposed to fail",issueID="0012443")]</p>
+<p>public function thisTestFails():void {}</pre></code></p>
+<p>or system-defined attributes that provide further instructions to FlexUnit when it runs the test.</p>
+
+<p>A test fixture comprises all of the state required to evaluate your test methods. For example, in the following test:</p>
+
+<p><code><pre>[Test]
+public function shouldComputeCorrectDiameter():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+    assertEquals( 10, circle.diameter );
+}</pre></code></p>
+<p>The existence of the Circle is necessary for the assertion and can therefore be considered part of your test fixture.</p>
+
+<h2>Walkthrough 1: Adding Tests to a Case</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Add tests to the BasicCircleTest case.</li>
+    <li>Run the case with the new tests.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the BasicCircleTest.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_wt1.fxp project from the Unit 4/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+    </li>
+    <li>
+        <p>Add seven new public functions to the class right under the <code>shouldReturnProvidedRadius()</code> function. They should be named <code>shouldComputeCorrectDiameter()</code>, <code>shouldReturnProvidedOrigin()</code>, <code>shouldReturnTrueForEqualCircle()</code>, <code>shouldReturnFalseForUnequalOrigin()</code>, <code>shouldReturnFalseForUnequalRadius()</code>, <code>shouldGetPointsOnCircle()</code>, and <code>shouldThrowRangeError()</code>.</p>
+        <p>Mark each function with <code>[Test]</code> metadata.</p>
+
+        <code><pre>[Test]
+public function shouldComputeCorrectDiameter():void {
+}
+
+[Test]
+public function shouldReturnProvidedOrigin():void {
+}
+
+[Test]
+public function shouldReturnTrueForEqualCircle():void { 
+}
+
+[Test]
+public function shouldReturnFalseForUnequalOrigin():void {
+}
+
+[Test]
+public function shouldReturnFalseForUnequalRadius():void {
+}
+
+[Test]
+public function shouldGetPointsOnCircle():void {    
+}
+
+[Test]
+public function shouldThrowRangeError():void {  
+}       </pre></code>
+    </li>
+    <li>
+        <p>Although you have written out seven methods, only the first five are going to be used in this walkthrough. Within <code>shouldComputeCorrectDiameter()</code>, <code>shouldReturnProvidedOrigin()</code>, <code>shouldReturnTrueForEqualCircle()</code>, <code>shouldReturnFalseForUnequalOrigin()</code>, and <code>shouldReturnFalseForUnequalRadius()</code> declare a local variable named <code>circle</code> of type <code>Circle</code>. Instantiate <code>circle</code> with an origin Point at <code>(0, 0)</code> and a radius of <code>5</code>.</p>
+
+        <code><pre>[Test]
+public function shouldComputeCorrectDiameter():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+}
+
+[Test]
+public function shouldReturnProvidedOrigin():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+}
+
+[Test]
+public function shouldReturnTrueForEqualCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+}
+
+[Test]
+public function shouldReturnFalseForUnequalOrigin():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+}
+
+[Test]
+public function shouldReturnFalseForUnequalRadius():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Just below the circle instantiation in the <code>shouldComputeCorrectDiameter()</code> method, add a line that calls to the <code>assertEquals()</code> method with arguments <code>10</code> and <code>circle.diameter</code>.</p> 
+
+        <code><pre>[Test]
+public function shouldComputeCorrectDiameter ():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+    assertEquals( 10, circle.diameter );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Just below the circle instantiation in the <code>shouldReturnProvidedOrigin()</code> method, add two lines that each call the <code>assertEquals()</code> method. This test requires two assertion statements because it will check the x and y coordinates' equality to 0, each on a different line.</p>
+
+        <code><pre>[Test]
+public function shouldReturnProvidedOrigin():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 ); 
+    assertEquals( 0, circle.origin.x );
+    assertEquals( 0, circle.origin.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a new local variable named <code>circle2</code> of type <code>Circle</code> to the <code>shouldReturnTrueForEqualCircle()</code> method. Instantiate <code>circle2</code> with an origin of <code>(0, 0)</code> and radius of <code>5</code>.</p>
+
+        <code><pre>[Test]
+public function shouldReturnTrueForEqualCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 0 ), 5 );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a new line to the <code>shouldReturnTrueForEqualCircle()</code> function that calls to the <code>assertTrue()</code> method with the argument <code>circle.equals( circle2 )</code>.</p>
+
+        <code><pre>[Test]
+public function shouldReturnTrueForEqualCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 0 ), 5 );
+
+    assertTrue( circle.equals( circle2 ) ); 
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the import for org.flexunit.asserts.assertTrue at this time.</p> 
+    </li>
+    <li>
+        <p>Add a variable named <code>circle2</code> of type <code>Circle</code> to the <code>shouldReturnFalseForUnequalOrigin()</code> method. Instantiate <code>circle2</code> with an origin of <code>(0, 5)</code> and a radius of <code>5</code>.</p>
+
+        <code><pre>[Test]
+public function shouldReturnFalseForUnequalOrigin():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 5 ), 5 );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a call to the <code>assertFalse()</code> method. The statement <code>circle.equals( circle2 )</code> should be passed in as its argument.</p>
+
+        <code><pre>[Test]
+public function shouldReturnFalseForUnequalOrigin():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 5 ), 5);
+
+    assertFalse( circle.equals( circle2 ) );
+}       </pre></code>
+
+        <p>If you did not use code-completion, add the import for org.flexunit.asserts.assertFalse at this point.</p>
+    </li>
+    <li>
+        <p>Add a variable named <code>circle2</code> of type <code>Circle</code> to the <code>shouldReturnFalseForUnequalRadius()</code> method. Instantiate <code>circle2</code> with an origin of <code>(0, 0)</code> and a radius of <code>7</code>.</p>
+
+        <code><pre>[Test]
+public function shouldReturnFalseForUnequalRadius():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 0 ), 7);
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add a call to the <code>assertFalse()</code> method. The expression <code>circle.equals( circle2 )</code> should be passed in as its argument.</p>
+
+        <code><pre>[Test]
+public function shouldReturnFalseForUnequalRadius():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var circle2:Circle = new Circle( new Point( 0, 0 ), 7);
+
+    assertFalse( circle.equals( circle2 ) );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Save the BasicCircleTest.as file.</p>
+    </li>
+    <li>
+        <p>Re-Open the FlexUnit4Training.mxml file. Click the run button in the upper toolbar.</p> 
+        <p>If FlexUnit4Training.mxml ran successfully you should see the following output in your browser window:</p>
+
+        <img alt='UnitsPassed' id='shift' src='../images/unit4/image1.png' />
+
+        <p class='caption' id='shift'>Figure 1: FlexUnit tests passed.</p>
+    </li>
+</ol>
+
+<h2>Creating tests</h2>
+
+<h3>Examining a passing test</h3>
+
+<p>In the section above you used assertions to establish several passing tests. Many took the same form as this simple math example:</p>
+
+<p><code><pre>[Test]
+public function testAddition():void {
+    var num1:Number = 5;
+    var num2:Number = 3;
+    var total:Number = 8;</p>
+<div class="codehilite"><pre><span class="n">assertEquals</span><span class="p">(</span> <span class="n">total</span><span class="p">,</span> <span class="n">num1</span> <span class="o">+</span> <span class="n">num2</span> <span class="p">);</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<ul>
+    <li>5 and 3 are expected to add up to 8.</li>
+    <li>The tests <b>assert</b> this expectation using the <code>assertEquals()</code> method</li>
+    <li>Since 5 + 3 == 8, this test will pass.</li>
+</ul>
+
+<h3>Performing basic assertions</h3>
+
+<p>Assertions allow us to specify expected conditions that help determine whether a test passes or fails. They are statements that evaluate to true or false. If you make an assertion that is false under the conditions you have set up, the test fails. If all of the assertions in the test are true, the test passes.</p>
+
+<p>FlexUnit provides many assertion methods to use in your test methods. You might use an assertion to state that you expect a value to be true or false, null or not null, equal to another variable, or simply not in a list of acceptable values.</p>
+
+<p>The three most common assertions in FlexUnit 4 are:</p>
+
+<ul>
+    <li><code>assertTrue( condition:Boolean )</code> - Asserts that a condition is true. This passes if the condition is true.</li>
+    <li><code>assertFalse( condition:Boolean )</code> - Asserts that a condition is false. This passes if the condition is false.</li>
+    <li><code>assertEquals( value1:Obj, value2:Obj )</code> - Asserts that two objects are equal. This passes if value1 == value2.</li>
+</ul>
+
+<p>If all of the assertion in a test evaluate correctly, that test is added to the list of passed tests. If any assertion fails, it throws an <code>AssertionError</code>. FlexUnit handles the error and adds the test to a list of failed tests.</p>
+
+<h3>Examining a failed test</h3>
+
+<p>Consider this slightly modified <code>testAddition()</code> method:</p>
+
+<p><code><pre>[Test]
+public function testAddition():void {
+    var num1:Number = 5;
+    var num2:Number = 3;
+    var total:Number = 1000;</p>
+<div class="codehilite"><pre><span class="n">assertEquals</span><span class="p">(</span> <span class="n">total</span><span class="p">,</span> <span class="n">num1</span> <span class="o">+</span> <span class="n">num2</span> <span class="p">);</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<ul>
+    <li>The test asserts that 5 + 3 == 1000.</li>
+    <li>This test will fail as your assertion is false.</li>
+</ul>
+
+<p>FlexUnit 4.x catches the <code>AssertionError</code> that is thrown when this test fails, and the following result is displayed within the FlexUnit Results window in Flash Builder:</p>
+
+<p><code><pre>
+"expected: &#60;1000&#62; but was: &#60;8&#62;"
+</pre></code></p>
+<p>A test will be registered as a failure after the <i>first</i> instance of a failed assertion.  FlexUnit will not continue to evaluate the other assertions in the method. This means that if multiple assertions are written in a single test you will only receive notification of the first failure and the others will be in an unknown state.</p>
+
+<p><code><pre>[Test]
+public function testAddition():void {
+        var num1:Number = 5;
+        var num2:Number = 3;
+        var total:Number = 1000;</p>
+<div class="codehilite"><pre>    <span class="n">assertEquals</span><span class="p">(</span> <span class="n">total</span><span class="p">,</span> <span class="n">num1</span> <span class="o">+</span> <span class="n">num2</span> <span class="p">);</span>
+    <span class="n">assertEquals</span><span class="p">(</span> <span class="n">num1</span> <span class="o">+</span> <span class="n">num2</span><span class="p">,</span> <span class="n">total</span> <span class="p">);</span>
+</pre></div>
+
+
+<p>}</pre></code></p>
+<p>For example, both of these assertions would fail given the opportunity.  However, as soon as FlexUnit catches the first failed assertion it stops the test.  The second assert will never be called.  The error message would read:</p>
+
+<p><code><pre>
+"expected: &#60;1000&#62; but was: &#60;8&#62;"
+</pre></code></p>
+<p>With multiple assertions in a test, a test can fail for one of several reasons. In diagnosis, it is not immediately clear what caused the test to fail.</p>
+
+<h2>Walkthrough 2: Failing and Passing Assertions</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Add multiple assertions to a test method.</li>
+    <li>Run the test case.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the BasicCircleTest.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 Unit 4/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3>Write multiple assertions for a test method</h3>
+
+    </li>
+    <li>
+        <p>In the <code>shouldGetPointsOnCircle()</code> method, create a local variable named <code>circle</code> of type <code>Circle</code>. This Circle should be instantiated with an origin of <code>(0, 0)</code> and a radius of <code>5</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetPointsOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Declare a variable named <code>point</code> of type <code>Point</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetPointsOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Set the point variable equal to the return value of <code>circle.getPointOnCircle( 0 )</code>. Above that line, it is useful to add a comment line specifying that this is the top-most point of circle.</p>
+
+        <code><pre>[Test]
+public function shouldGetPointsOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+
+    //top-most point of circle
+    point = circle.getPointOnCircle( 0 );
+}       </pre></code>
+
+        <p>The <code>getPointOnCircle( t:Number )</code> returns a Circle object's point that corresponds to the radians passed in as the <code>t</code> parameter.</p>
+    </li>
+    <li>
+        <p>Add two new lines, each with a call to the <code>assertEquals()</code> method. The first takes the arguments <code>5</code> and <code>point.x</code>. The second takes the arguments <code>0</code> and <code>point.y</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetPointsOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+
+    //top-most point of circle
+    point = circle.getPointOnCircle( 0 );
+    assertEquals( 5, point.x );
+    assertEquals( 0, point.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Copy these four new lines of code and paste them into the bottom of the function.</p> 
+        <p>Alter the comment in this section to read <code>//bottom-most point on circle</code>.</p>
+    </li>
+    <li>
+        <p>Replace the <code>0</code> in <code>circle.getPointOnCircle( 0 )</code> with <code>Math.PI</code>.</p>
+    </li>
+    <li>
+        <p>Update the <code>assertEquals()</code> statements to <code>assertEquals( -5, point.x )</code> and <code>assertEquals( 0, point.y )</code>.</p>
+        <p>This should create a duplicate set of assertions for the bottom-most point on the circle.</p>
+
+        <code><pre>[Test]
+public function shouldGetPointsOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+
+    //top-most point of circle
+    point = circle.getPointOnCircle( 0 );
+    assertEquals( 5, point.x );
+    assertEquals( 0, point.y );
+
+    //bottom-most point of circle
+    point = circle.getPointOnCircle( Math.PI );
+    assertEquals( -5, point.x );
+    assertEquals( 0, point.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Save BasicCircleTest.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='SingleTestFailure' id='shift' src='../images/unit4/image2.png' />
+        <p class='caption' id='shift'>Figure 1: A single test failure</p>
+
+        <p>One of the tests in the case has failed. Further evaluation within the FlexUnit results tab will show that the newly populated <code>shouldGetPointsOnCircle()</code> method failed.</p>
+        <p>While you know that this test failed, you do not know the failure. Fewer assertions in a method provide you better context to understand the root cause quickly.</p>
+        <p>If you examine the failure in Flash Builder, you will see that the root cause actually has to do with the imprecision of floating point calculations. You will learn to adapt your code to these issues in future lessons.</p>
+
+        <img alt='FailureStackTrace' id='shift' src='../images/unit4/image3.png' />
+        <p class='caption' id='shift'>Figure 2: The failure stack trace </p>
+    </li>
+</ol>
+
+<h2>Understanding multiple assertions</h2>
+
+<p>As you have previously learned, FlexUnit 4.x marks a test as a failure after the first failed assertion. Therefore a test with many assertions provides a limited amount of useful information as to the root cause of the failure.</p>
+
+<p>The <code>shouldGetPointsOnCircle()</code> method already has too many assertions to be useful. Furthermore, to test it effectively you still need additional data points along the circle.</p>
+
+<p>The way to resolve this issue is to refactor these test cases into multiple small cases which provide useful context during a failure. Each test will make a single assertion. Subsequently, if a single test fails, a single assertion has failed.</p>
+
+<h2>Walkthrough 3: Factoring into Multiple Test Methods</h2>
+
+<p>In this walkthrough you will perform the following tasks:</p>
+
+<ul>
+    <li>Refactor a test method with multiple assertions.</li>
+</ul>
+
+<h3>Steps</h3>
+
+<ol>
+    <li>
+        <p>Open the BasicCircleTest.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 Unit5/Start folder. Please refer to Unit 2: Walkthrough 1 for instructions on importing a Flash Builder project.</p>
+
+        <h3>Refactor point tests</h3>
+
+    </li>
+    <li>
+        <p>Replace the <code>shouldGetPointsOnCircle()</code> function with two new public functions in the <code>BasicCircleTest</code> class. These functions will be named so that each clearly represents the point on the circle being tested.</p>
+
+        <code><pre>[Test]
+public function shouldGetTopPointOnCircle():void {
+}
+
+[Test]
+public function shouldGetBottomPointOnCircle():void {
+}       </pre></code>
+
+        <p>Although the original <code>shouldGetPointsOnCircle()</code> method contained tests for only the top and bottom points of the Circle, in this Walkthrough you will add tests for the left and right points as well.</p>
+    </li>
+    <li>
+        <p>Add two new methods named <code>shouldGetRightPointOnCircle()</code> and <code>shouldGetLeftPointOnCircle()</code>.</p>
+    </li>
+    <li>
+        <p>Copy the instantiation of the circle, and declaration of the point from the <code>shouldgetPointsOnCircle()</code> method into each of the four new methods.</p>
+
+        <code><pre>[Test]
+public function shouldGetTopPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+}
+
+[Test]
+public function shouldGetBottomPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+}
+
+[Test]
+public function shouldGetRightPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+}
+
+[Test]
+public function shouldGetLeftPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Copy the block of code following <code>//top-most point of circle</code> comment into the <code>shouldGetTopPointOnCircle()</code> method.  Copy the block following the <code>//bottom-most point of circle</code> comment into the <code>shouldGetBottomPointOnCircle()</code> method.</p>
+
+        <code><pre>[Test]
+public function shouldGetTopPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+
+    //top-most point of circle 
+    point = circle.getPointOnCircle( 0 );
+    assertEquals( 5, point.x );
+    assertEquals( 0, point.y );
+}
+
+[Test]
+public function shouldGetBottomPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point;
+
+    //bottom-most point of circle
+    point = circle.getPointOnCircle( Math.PI );
+    assertEquals( -5, point.x );
+    assertEquals( 0, point.y );
+}       </pre></code>
+
+        <p>Because the methods each test specific points, the name is clear enough to distinguish one test from another. Remove the comment fields in each of the tests accordingly.</p>
+    </li>
+    <li>
+        <p>Modify the <code>shouldGetTopPointOnCircle()</code> and <code>shouldGetBottomPointOnCircle()</code> methods to save space by instantiating the point variable as it is declared in each function, much like the circle variable. The comments can be removed as well.</p>
+
+        <code><pre>[Test]
+public function shouldGetTopPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( 0 );
+
+    assertEquals( 5, point.x );
+    assertEquals( 0, point.y );
+}
+
+[Test]
+public function shouldGetBottomPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( Math.PI );
+
+    assertEquals( -5, point.x );
+    assertEquals( 0, point.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>In the <code>shouldGetRightPointOnCircle()</code> method, set the <code>point</code> variable to <code>circle.getPointOnCircle( Math.PI/2 )</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetRightPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( Math.PI/2 );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>In the <code>shouldGetLeftPointOnCircle()</code> method, set the <code>point</code> variable to <code>circle.getPointOnCircle( (3*Math.PI)/2 )</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetLeftPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( (3*Math.PI)/2 );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add two calls to the <code>assertEquals()</code> method to <code>shouldGetRightPointOnCircle()</code>. One should assert that <code>point.x</code> is equal to <code>5</code>, and <code>point.y</code> is equal to <code>0</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetRightPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( Math.PI/2 );
+
+    assertEquals( 0, point.x );
+    assertEquals( 5, point.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Add two calls to the <code>assertEquals()</code> method to <code>shouldGetLeftPointOnCircle()</code>. One should assert that <code>point.x</code> is equal to <code>0</code>, and <code>point.y</code> is equal to <code>-5</code>.</p>
+
+        <code><pre>[Test]
+public function shouldGetLeftPointOnCircle():void {
+    var circle:Circle = new Circle( new Point( 0, 0 ), 5 );
+    var point:Point = circle.getPointOnCircle( (3*Math.PI)/2 );
+
+    assertEquals( 0, point.x );
+    assertEquals( -5, point.y );
+}       </pre></code>
+
+    </li>
+    <li>
+        <p>Delete the previously used <code>shouldGetPointsOnCircle()</code> method, because its tests have been replicated.</p>
+    </li>
+    <li>
+        <p>Save the BasicCircleTest.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='ThreeTestsFailed' id='shift' src='../images/unit4/image4.png' />
+        <p class='caption' id='shift'>Figure 1: Three tests failed.</p>
+
+        <p>Previously, when all the point assertions were bundled into a single method, it was impossible to determine which assertions caused the failure. Refactoring these assertions into four different test methods makes it clear that three of the four conditions are failures.</p> 
+        <p>Further inspection will reveal that the <code>shouldGetTopPointOnCircle()</code> is the only of the four tests that is passing. It is also the only test with an integer value of 0 passed in for its radians argument. The root cause of the situation is the way in which Flash Player handles fractions and the precision of those comparisons. This will be explored further and a solution demonstrated later in this text.</p>
+    </li>
+</ol>
+
+<h2>Summary</h2>
+
+<ul>
+    <li>A unit is the smallest piece of code that can be isolated and tested independently</li>
+    <li>Code with seams is testable. Code without seams is impossible to truly unit test.</li>
+    <li>You can create seams in your code by:</li>
+    <ul>
+        <li>Passing dependencies as arguments</li>
+        <li>Limiting the use of static classes or global state</li>
+    </ul>
+    <li>Test cases are collections of test methods</li> 
+    <li>A test without a failing assertion is a passing test</li>
+    <ul>
+        <li>This means an empty tests is a passing test</li>
+    </ul>
+    <li>Common assertions in FlexUnit include:</li>
+    <ul>
+        <li><code>assertEquals()</code></li>
+        <li><code>assertTrue()</code></li>
+        <li><code>assertFalse()</code></li>
+    </ul>
+    <li>Any failing assertion within a test causes the test to cease execution and fail</li>
+    <li>When a test with multiple assertions fails, it is difficult to narrow down which assertion failed.</li>
+</ul>
+
+<h2>Navigation</h2>
+
+<ul>
+    <li><a href="Unit-3.html">Unit 3 - FlexUnit Capabilities</a></li>
+    <li><a href="Unit-5.html">Unit 5 - Developing Static Tests</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