Statement Decorators that are used in Sequences.

Decoration

Sequencers are used for every operation that might be asynchronous. Sequencers are one of two concepts used to run methods. The second concept is that of Decoration.

Decorations are used to 'wrap' the invocation of a method with code that should be executed before or after the method, synchronously.

Wrapping

Here is an example of the wrapping that goes on for each test method:

var statement:IAsyncStatement = methodInvoker( method, test );
statement = withPotentialAsync( method, test, statement );
statement = withPotentialTimeout( method, test, statement );
statement = possiblyExpectingExceptions( method, test, statement );
statement = withStackManagement( method, test, statement );

So with the example above, here is how the statement is wrapped.

:Stack Management
::Expecting Exception
:::Potential Timeout
::::Potential Async
:::::Method Invoker
::::Potential Async
:::Potential Timeout
::Expecting Exception
:Stack Management

As the statement is run, it will run Stack Management, then move to Expecting Exception, and on down until getting to the Method Invoker which runs the actual test. At each step, the Token is passed down to it's child. Once Method Invoker is run, then the token is passed back up from the child to it's parent telling the parent "I'm done!" with some information attached. The parent can then use that to complete it's job and pass the token up to it's parent. This goes on until the top level parent is reached and it does it's job to complete the whole wrapped Statement.

'''In a more visual way, the wrapping looks like this:'''

Why?

Wrapping actually enhances the performance and extensibility of FlexUnit4. Each layer of wrapping independently checks the test to see if it is needed. If the layer is not needed, then it acts as a '''noop''' (No Operation). If the layer is needed, for example, we specify async, then the logic for that layer is instantiated and enabled to ensure that the test is handled properly.

Green Threading

Green Threading in this instance, is the term for simulating multithreading in a single threaded environment (Flash Player).

Stack (and Frame) Management

The stack and frame management decorator implements green threading to deal with Flash frames. Since Flash player runs code using frames, it has a finite amount of time (usually 1/24th of a second) to execute code. Given the single threaded nature of Flash player, it does not ever interrupt code execution that is in progress. If the frame time is gone over, then the Flash player will experience a freeze on the screen until that frame can end, and if the code goes on long enough, the Flash player 15 second timeout will be reached. If that timeout is reached, then Flash player will throw up a dialog allowing the user to kill the script that is running. This is obviously something that we do not want.

So to prevent this from happening, and to help make testing quick and responsive, FlexUnit4 keeps track of the amount of time that each method takes to run. As methods are run, FlexUnit4 tracks the time for the methods, and as the time for those methods approaches the duration of a frame (about 80% currently) any further methods are deferred until the next frame. This ensures that there is never a script timeout or locking of the player during testing.

Expecting Exception

The Expecting Exception decorator implements logic to catch exceptions thrown during the test. If the user indicates that an exception should be thrown by the test, then this code will compare any exception against the specified one. If the exceptions match, then all is good and the test will pass. If they do not match, or if the test doesn't throw an exception, then the Expecting Exception decorator ends up marking the test as a failure.

Potential Timeout

The Potential Timeout decorator implements a timer to time the test. The test will be marked as a failure if the test exceeds the number of milliseconds that is specified in the timeout.

Potential Async

The Potential Async decorator creates the infrastructure to monitor an async test. Since not all tests are async, using a decorator like this allows us to not instantiate the overhead needed to keep track of such a test. The overhead for async testing is only created when the user requests it.

Method Invoker

This decorator, the Method Invoker, is what actually executes the test method and captures any errors that happen during the method invocation.


Back | Next

  • No labels