21 Replies Latest reply: Mar 9, 2011 1:32 AM by nikos101 RSS

    How to use SequenceRunner with FlexUnit 4

    Carsten Schlipf

      Hi,

       

      I just read the Wiki page about Fluint Sequences at http://docs.flexunit.org/index.php?title=Sequences#Sequences_from_Fluint. 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\dmoore\Documents\_Product ion\Flex Unit 4\GIT\FlexUnit4\src\org\flexunit\async\AsyncLocator.as:82]
          at org.fluint.sequence::SequenceWaiter/setupListeners()[C:\Users\dmoore\Documents\_Productio n\Flex Unit 4\GIT\FlexUnit4\src\org\fluint\sequence\SequenceWaiter.as:100]
          at org.fluint.sequence::SequenceRunner/continueSequence()[C:\Users\dmoore\Documents\_Product ion\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::RelativeDateInputFluintSequence/testForm()[/home /cschlipf/data/dev/svn/opr/components/common/flex/lib/opr-fx-common/src/test/flex/com/hp/o pr/flex/filter/eventFilter/view/RelativeDateInputFluintSequence.as:56]
          at net.digitalprimates.fluint.tests::TestCase/protect()[C:\Users\mlabriola\Documents\workspa ces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\flex\net\digitalprimate s\fluint\tests\TestCase.as:315]
          at Function/http://adobe.com/AS3/2006/builtin::apply()
          at net.digitalprimates.fluint.tests::TestCase/executeMethodWhileProtected()[C:\Users\mlabrio la\Documents\workspaces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\fle x\net\digitalprimates\fluint\tests\TestCase.as:370]
          at net.digitalprimates.fluint.tests::TestCase/runTestMethod()[C:\Users\mlabriola\Documents\w orkspaces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\flex\net\digitalp rimates\fluint\tests\TestCase.as:160]
          at net.digitalprimates.fluint.ui::TestRunner/runTestMethod()[C:\Users\mlabriola\Documents\wo rkspaces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\flex\net\digitalpr imates\fluint\ui\TestRunner.as:361]
          at net.digitalprimates.fluint.ui::TestRunner/handleTestProcess()[C:\Users\mlabriola\Document s\workspaces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\flex\net\digit alprimates\fluint\ui\TestRunner.as:393]
          at flash.events::EventDispatcher/dispatchEventFunction()
          at flash.events::EventDispatcher/dispatchEvent()
          at net.digitalprimates.fluint.tests::TestCase/handleAsyncEventFired()[C:\Users\mlabriola\Doc uments\workspaces\net\digitalprimates\opensource\flexunit\fluint\fluint\src\main\flex\net\ digitalprimates\fluint\tests\TestCase.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\flexunit\fluint\fluint\src\main\flex\net\digita lprimates\fluint\async\AsyncHandler.as:166]
          at flash.events::EventDispatcher/dispatchEventFunction()
          at flash.events::EventDispatcher/dispatchEvent()
          at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.5.0\frameworks\projects\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\frameworks\projects\framew ork\src\mx\core\UIComponent.as:8744]
          at mx.core::UIComponent/callLaterDispatcher()[C:\autobuild\3.5.0\frameworks\projects\framewo rk\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

        • 1. Re: How to use SequenceRunner with FlexUnit 4
          rquantin Community Member

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

           

          Romu

          • 2. Re: How to use SequenceRunner with FlexUnit 4
            rquantin Community Member

            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)));
                    }
                   
                }
            }

            • 3. Re: How to use SequenceRunner with FlexUnit 4
              Michael Labriola Community Member

              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

              • 4. Re: How to use SequenceRunner with FlexUnit 4
                Michael Labriola Community Member

                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

                • 5. Re: How to use SequenceRunner with FlexUnit 4
                  rquantin Community Member

                  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

                  • 6. Re: How to use SequenceRunner with FlexUnit 4
                    Michael Labriola Community Member

                    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

                    • 7. Re: How to use SequenceRunner with FlexUnit 4
                      Carsten Schlipf Community Member

                      Hi Michael,

                       

                      some comments and question on that page.

                       

                      First it is states 'Create a new ActionScript class named TestSequences.as with a superclass of net.digitalprimates.fluint.tests.TestCase.'. I assume that this is wrong as it contradicts with what you are writing.

                       

                      Then in the setUp method you write

                       

                      form.addEventListener( FlexEvent.CREATION_COMPLETE,

                                                                    asyncHandler( pendUntilComplete, 100),

                                             false,            0, true );

                       

                      However where does this asyncHandler come from if not from the superclass? I guess it would be better to add a SequenceWaiter at the beginning of the test, which waits for the CREATION_COMPLETE - is that the way to go?

                       

                      Best regards,

                      Carsten

                      • 8. Re: How to use SequenceRunner with FlexUnit 4
                        Michael Labriola Community Member

                        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

                        • 9. Re: How to use SequenceRunner with FlexUnit 4
                          Carsten Schlipf Community Member

                          Hi Mike,

                           

                          thank you very much for you fast reply. I believe I got it working.

                           

                          Too bad that SequenceRunner is so underrepresentated. It's so elegant and powerful for testing UI components that I wonder why it's not more prominently announced.

                           

                          Again, thank you very much for your help.

                           

                          Best regards,

                          Carsten

                          • 10. Re: How to use SequenceRunner with FlexUnit 4
                            Michael Labriola Community Member

                            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

                            • 11. Re: How to use SequenceRunner with FlexUnit 4
                              Carsten Schlipf Community Member

                              Oh - just noticed another error in the doc.

                               

                              The test function must be marked as async test, so add [Test(async)] and not just [Test] before the method.

                              • 13. Re: How to use SequenceRunner with FlexUnit 4
                                nikos101 Community Member

                                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

                                • 14. Re: How to use SequenceRunner with FlexUnit 4
                                  Carsten Schlipf Community Member

                                  Nikos,

                                   

                                  do not derive your test class from TestCase. Simply create a plain FlexUnit 4 testcase with metadata annotations.

                                  • 15. Re: How to use SequenceRunner with FlexUnit 4
                                    nikos101 Community Member

                                    Thx mate,

                                     

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

                                     

                                     

                                    sequence:SequenceRunner = new SequenceRunner( this     );

                                    • 16. Re: How to use SequenceRunner with FlexUnit 4
                                      Carsten Schlipf Community Member

                                      Simply specify 'this' as argument.

                                       

                                      var sequence:SequenceRunner = new SequenceRunner(this);

                                       

                                      Note that there are two SequenceRunners. Make sure to import the correct one:

                                       

                                      import org.fluint.sequence.SequenceRunner;

                                      • 17. Re: How to use SequenceRunner with FlexUnit 4
                                        nikos101 Community Member

                                        opps, I imported

                                         


                                            import net.digitalprimates.fluint.sequence.SequenceRunner;

                                         

                                         

                                        • 18. Re: How to use SequenceRunner with FlexUnit 4
                                          Carsten Schlipf Community Member

                                          Can't count how often I fell into the same trap

                                          • 19. Re: How to use SequenceRunner with FlexUnit 4
                                            nikos101 Community Member

                                            so why 2 of them?


                                            • 20. Re: How to use SequenceRunner with FlexUnit 4
                                              Michael Labriola Community Member

                                              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

                                              • 21. Re: How to use SequenceRunner with FlexUnit 4
                                                nikos101 Community Member

                                                Ah thanks michael