Skip navigation
Carsten Schlipf
Currently Being Moderated

How to use SequenceRunner with FlexUnit 4

Aug 9, 2010 8:24 AM

Hi,

 

I just read the Wiki page about Fluint Sequences at http://docs.flexunit.org/index.php?title=Sequences#Sequences_from_Flui nt. I really would like to use sequences as it seems a great way to test flows in UI components.

 

So I created a first test based on the examples in the wiki. Unfortunately it does not work as I hoped.

 

The testcase:

 

package flex.filter.eventFilter.view
{

      import flash.events.Event;

     import mx.events.FlexEvent;

  import net.digitalprimates.fluint.tests.TestCase;

  import org.fluint.sequence.SequenceRunner;
  import org.fluint.sequence.SequenceSetter;
  import org.fluint.sequence.SequenceWaiter;


  public class RelativeDateInputFluintSequence extends TestCase
  {

    private var form:RelativeDateInput;

    [Before(async)]
    override protected function setUp():void
    {
      form = new RelativeDateInput();
      form.addEventListener(FlexEvent.CREATION_COMPLETE, asyncHandler (pendUntilComplete, 100), false, 0, true);
      addChild(form);
    }


    [After(async)]
    override protected function tearDown():void
    {
      removeChild(form);
      form = null;
    }

    [Test(async)]
    public function testForm():void
    {
      var passThroughData:Object = new Object();
      passThroughData.value = 5;
      passThroughData.selectedUnit = "hours";

      var sequence:SequenceRunner = new SequenceRunner(this);

      // Set time in stepper
      sequence.addStep (new SequenceSetter(form.timeStepper, {value:passThroughData.value}));
      sequence.addStep(new SequenceWaiter(form.timeStepper, FlexEvent.VALUE_COMMIT, 100));

      // Set units
      sequence.addStep (new SequenceSetter(form.unitCombo, {selectedItem:passThroughData.selectedUnit}));
      sequence.addStep(new SequenceWaiter(form.timeStepper, FlexEvent.VALUE_COMMIT, 100));

      sequence.addAssertHandler(handleFiveHoursSet, passThroughData);

      sequence.run();
    }


    private function handleFiveHoursSet(event:Event, passThroughData:Object):void
    {
      assertEquals(passThroughData.value * 60 * 60000, form.milliseconds);
    }
  }
}

 

Note that I did not add the test annotations at first as they were ommitted in the Wiki. I added these later after I got the error below.

 

When sequence.run() is executed I get this error:

Cannot add asynchronous functionality to methods defined by Test,Before or After that are not marked async
Error: Cannot add asynchronous functionality to methods defined by Test,Before or After that are not marked async
    at org.flexunit.async::AsyncLocator$/getCallableForTest()[C:\Users\dmoor e\Documents\_Production\Flex Unit 4\GIT\FlexUnit4\src\org\flexunit\async\AsyncLocator.as:82]
    at org.fluint.sequence::SequenceWaiter/setupListeners()[C:\Users\dmoore\ Documents\_Production\Flex Unit 4\GIT\FlexUnit4\src\org\fluint\sequence\SequenceWaiter.as:100]
    at org.fluint.sequence::SequenceRunner/continueSequence()[C:\Users\dmoor e\Documents\_Production\Flex Unit 4\GIT\FlexUnit4\src\org\fluint\sequence\SequenceRunner.as:177]
    at org.fluint.sequence::SequenceRunner/run()[C:\Users\dmoore\Documents\_ Production\Flex Unit 4\GIT\FlexUnit4\src\org\fluint\sequence\SequenceRunner.as:124]
    at com.hp.opr.flex.filter.eventFilter.view::RelativeDateInputFluintSeque nce/testForm()[/home/cschlipf/data/dev/svn/opr/components/common/flex/ lib/opr-fx-common/src/test/flex/com/hp/opr/flex/filter/eventFilter/vie w/RelativeDateInputFluintSequence.as:56]
    at net.digitalprimates.fluint.tests::TestCase/protect()[C:\Users\mlabrio la\Documents\workspaces\net\digitalprimates\opensource\flexunit\fluint \fluint\src\main\flex\net\digitalprimates\fluint\tests\TestCase.as:315 ]
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at net.digitalprimates.fluint.tests::TestCase/executeMethodWhileProtecte d()[C:\Users\mlabriola\Documents\workspaces\net\digitalprimates\openso urce\flexunit\fluint\fluint\src\main\flex\net\digitalprimates\fluint\t ests\TestCase.as:370]
    at net.digitalprimates.fluint.tests::TestCase/runTestMethod()[C:\Users\m labriola\Documents\workspaces\net\digitalprimates\opensource\flexunit\ fluint\fluint\src\main\flex\net\digitalprimates\fluint\tests\TestCase. as:160]
    at net.digitalprimates.fluint.ui::TestRunner/runTestMethod()[C:\Users\ml abriola\Documents\workspaces\net\digitalprimates\opensource\flexunit\f luint\fluint\src\main\flex\net\digitalprimates\fluint\ui\TestRunner.as :361]
    at net.digitalprimates.fluint.ui::TestRunner/handleTestProcess()[C:\User s\mlabriola\Documents\workspaces\net\digitalprimates\opensource\flexun it\fluint\fluint\src\main\flex\net\digitalprimates\fluint\ui\TestRunne r.as:393]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at net.digitalprimates.fluint.tests::TestCase/handleAsyncEventFired()[C: \Users\mlabriola\Documents\workspaces\net\digitalprimates\opensource\f lexunit\fluint\fluint\src\main\flex\net\digitalprimates\fluint\tests\T estCase.as:267]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at net.digitalprimates.fluint.async::AsyncHandler/handleEvent()[C:\Users \mlabriola\Documents\workspaces\net\digitalprimates\opensource\flexuni t\fluint\fluint\src\main\flex\net\digitalprimates\fluint\async\AsyncHa ndler.as:166]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.5.0\frameworks\pr ojects\framework\src\mx\core\UIComponent.as:9440]
    at mx.core::UIComponent/set initialized()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx \core\UIComponent.as:1168]
    at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.5.0 \frameworks\projects\framework\src\mx\managers\LayoutManager.as:718]
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at mx.core::UIComponent/callLaterDispatcher2()[C:\autobuild\3.5.0\framew orks\projects\framework\src\mx\core\UIComponent.as:8744]
    at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.5.0\framewo rks\projects\framework\src\mx\core\UIComponent.as:8684]

 

So my guess is that the SequenceRunner is not fully compatible with FlexUnit 4 as asyncronous calls that are internal to the SequenceRunner are not marked as async.

 

Best regards,

Carsten

 
Replies
  • Currently Being Moderated
    Oct 9, 2010 7:50 PM   in reply to Carsten Schlipf

    I tr y to find a solution with the sequencer runner as well, did you find one?

     

    Romu

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 10, 2010 5:45 AM   in reply to rquantin

    If you are interested, I solved it with the TestCase class in the flexunit.framework package:

     

    package com.soma.core.tests.suites.commands {
        import flexunit.framework.TestCase;
        import flash.events.Event;
        import com.soma.core.tests.suites.support.TestSequenceCommand;
        import mx.core.FlexGlobals;
        import flash.display.Stage;
        import com.soma.core.tests.suites.support.TestAsyncCommand;
        import com.soma.core.tests.suites.support.TestEvent;
        import com.soma.core.Soma;
       
        /**
         * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
         * <b>Class version:</b> 1.0<br />
         * <b>Actionscript version:</b> 3.0<br />
         * <b>Date:</b> Oct 10, 2010<br />
         * @example
         * <listing version="3.0"></listing>
         */
       
        public class SequenceTestCaseSuccess extends TestCase {

     

            //------------------------------------
            // private, protected properties
            //------------------------------------
           
            private var _soma:Soma;
            private var _count:int;
           
            private static var _stage:Stage;

     

            //------------------------------------
            // public properties
            //------------------------------------
           
           
           
            //------------------------------------
            // constructor
            //------------------------------------
           
            public function SequenceTestCaseSuccess() {
               
            }
           
            //
            // PRIVATE, PROTECTED
            //___________________________________________________________________ _____________________________
           
            override public function setUp():void {
                _stage = FlexGlobals.topLevelApplication.stage;
                _count = 0;
                _soma = new Soma(_stage);
                _soma.addCommand(TestEvent.TEST, TestAsyncCommand);
                _soma.addCommand(TestEvent.TEST_SEQUENCE, TestSequenceCommand);
            }
           
            override public function tearDown():void {
                var command:TestAsyncCommand = _soma.getCommand(TestEvent.TEST) as TestAsyncCommand;
                if (command) command.dispose();
                _soma.removeEventListener(TestEvent.TEST_ASYNC_COMPLETE, testSequenceHandler);
                _soma.dispose();
                _soma = null;
            }
           
            //
            // PUBLIC
            // _____________________________________________________________________ ___________________________
           
            public function testSequence():void {
                _soma.addEventListener(TestEvent.TEST_ASYNC_COMPLETE, addAsync(testSequenceHandler, 500));
                _soma.dispatchEvent(new TestEvent(TestEvent.TEST_SEQUENCE));
            }

     

            private function testSequenceHandler(event:TestEvent):void {
                _soma.removeEventListener(TestEvent.TEST_ASYNC_COMPLETE, testSequenceHandler);
                if (++_count < 5) {
                    _soma.addEventListener(TestEvent.TEST_ASYNC_COMPLETE, addAsync(testSequenceHandler, 500));
                }
                else {
                    _soma.addEventListener(TestEvent.TEST_SEQUENCE_COMPLETE, addAsync(testSequenceCompleteHandler, 100));
                }
                trace("TestSequenceCommand: step", _count + "/5");
            }

     

            private function testSequenceCompleteHandler(event:TestEvent):void {
                assertNull(_soma.getLastSequencer());
                assertEquals(_soma.getRunningSequencers().length, 0);
                assertNull(_soma.getSequencer(Event(event.data)));
            }
           
        }
    }

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 10, 2010 8:14 AM   in reply to rquantin

    Hi All:

     

    Sorry I missed this post before. I did not even see it until a reply was posted.

     

    The problem in these examples is that concepts are being mixed and matched.

     

    In FlexUnit 4, you will never extend from a TestCase class.If you are extending from TestCase, you are no longer running in FlexUnit 4. You are now running inside of Fluint (or FlexUnit .9) depending on which TestCase class you extend from. FlexUnit 4 allow you to still write cases this way for backwards compatibility but it literally delegates the running of this test to the old framework.

     

    Concepts like Before and After were not present in those original frameworks. They are FlexUnit 4 concepts. Therefore, when you extend from TestCase but then use a Before or After... all of the Before/After and other code is completely and totally ignored.

     

    The SequenceRunner stuff is 100% compatible with FlexUnit 4 and works properly. We actually use it to test parts of FlexUnit 4.

     

     

    So, going back to the very first post in this thread. If you removed the words "extends TestCase" It probably would have worked fine.

     

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 10, 2010 8:37 AM   in reply to rquantin

    Also, I update some of the code on this page:

     

    http://docs.flexunit.org/index.php?title=Fluint_Sequences

     

    To show the example and deprecated the older one. I apologize for the confusion. Because there is a lot of information on the original fluint project and a growing amount of information on FlexUnit 4, this can get very confusing.

     

    I hope we will continue to find volunteers to ensure the documentation is better updated.

     

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 10, 2010 5:14 PM   in reply to Michael Labriola

    Indeed the SequenceRunner works great when I don't extend anything. I'm not a unit test specialist but it looks nice, I could tests my stuff in a pretty way.

     

    I've also tried the change you've made in the wiki but when I try to extend this TestCase class (net.digitalprimates.fluint.tests.TestCase), I still get:

     

    Cannot add asynchronous functionality to methods defined by Test,Before or After that are not marked async

     

    I tried with a [Test], a [Test(async)] and without.

     

    Maybe the problem is because I add the TestCase to a Flex Unit 4 Suite?

     

    No clue, but first solution works perfectly.

     

    Thanks for the help.

     

    Romu

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 10, 2010 5:19 PM   in reply to rquantin

    Hi Romu,

     

    Don't extend that TestCase class. We could make it work doing so, but the Before and After methods won't work. The whole way that TestCase extended code worked was very different than the new code.

     

    I will make sure the wiki is updated to properly reflect this, but you will get the best speed and features by using the newer style and NOT extending TestCase.

     

    I am glad to help,

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 13, 2010 9:08 AM   in reply to Carsten Schlipf

    Carsten:

     

    Yes, I am continuing to try to straighten out the wiki, however, to answer your specific questions:

     

    Do not extend the TestCase

    There is a static class called Async, so :

     

         Async.asyncHandler();

     

    Finally, yes, a waiter at the beginning of the test would be cleaner.

     

    Sorry the docs are in such bad shape on this.

     

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 13, 2010 9:19 AM   in reply to Carsten Schlipf

    Carsten,

     

    It was a big part of fluint and still a part of FlexUnit 4. However, we have a small team and out first goals were integration and compatibility so we are lagging behind where we wanted to be.

     

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 13, 2010 9:21 AM   in reply to Carsten Schlipf

    Thanks.

     
    |
    Mark as:
  • Currently Being Moderated
    Dec 23, 2010 3:04 AM   in reply to Michael Labriola

    I  can't even get the SequenceRunner thing to compile, just following the docs

     

    http://docs.flexunit.org/index.php?title=Fluint_Sequences

     

    1067   var sequence:SequenceRunner = new SequenceRunner( this     );
                sequence.addStep( new SequenceSetter( view.username, {text:passThroughData.username} ) );          
                sequence.addStep( new SequenceWaiter(view.username, FlexEvent.VALUE_COMMIT, 100 ) );

     

    Multiple markers at this line:
    -1067: Implicit coercion of a value of type tests.view:TestLoginForm to an unrelated type
    net.digitalprimates.fluint.tests:TestCase.
    -1067: Implicit coercion of a value of type tests.view:TestLoginForm to an unrelated type
    net.digitalprimates.fluint.tests:TestCase.
    -SequenceRunner
    -SequenceRunner
    -1 changed line

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 8, 2011 9:15 AM   in reply to Carsten Schlipf

    Thx mate,

     

    So how can I use the  SequenceRunner   if SequenceRunner  expects a TestCase

     

     

    sequence:SequenceRunner = new SequenceRunner( this     );

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 8, 2011 9:24 AM   in reply to Carsten Schlipf

    opps, I imported

     


        import net.digitalprimates.fluint.sequence.SequenceRunner;

     

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 8, 2011 9:31 AM   in reply to Carsten Schlipf

    so why 2 of them?


     
    |
    Mark as:
  • Currently Being Moderated
    Mar 8, 2011 9:36 AM   in reply to nikos101

    One is actually coming from the old fluint library and one is in FlexUnit 4. There are 2 because our first goal for FlexUnit 4.0 was to make it 100% compatible with people writing FlexUnit .9 or Fluint 1.x tests.

     

    For the 4.1 release we are going to change that. You will manually have to add the Fluint swc if you want it, which means you will generally only see 1 and this should get a bit easier.

     

    Sorry it is confusing. Something we are just trying to deal with is the balance of bakwards compatibility and still making this easy to use. Don't know that we have been 100% sucessful.

     

    Mike

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 9, 2011 1:32 AM   in reply to Michael Labriola

    Ah thanks michael

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points