Copy link to clipboard
Copied
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()
at org.fluint.sequence::SequenceWaiter/setupListeners()
at org.fluint.sequence::SequenceRunner/continueSequence()
at org.fluint.sequence::SequenceRunner/run()
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/opr/flex/filter/eventFilter/view/RelativeDateInputFluintSequence.as:56]
at net.digitalprimates.fluint.tests::TestCase/protect()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at net.digitalprimates.fluint.tests::TestCase/executeMethodWhileProtected()
at net.digitalprimates.fluint.tests::TestCase/runTestMethod()
at net.digitalprimates.fluint.ui::TestRunner/runTestMethod()
at net.digitalprimates.fluint.ui::TestRunner/handleTestProcess()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at net.digitalprimates.fluint.tests::TestCase/handleAsyncEventFired()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at net.digitalprimates.fluint.async::AsyncHandler/handleEvent()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.core::UIComponent/set initialized()
at mx.managers::LayoutManager/doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()
at mx.core::UIComponent/callLaterDispatcher()
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
Copy link to clipboard
Copied
I tr y to find a solution with the sequencer runner as well, did you find one?
Romu
Copy link to clipboard
Copied
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)));
}
}
}
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Thanks.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Nikos,
do not derive your test class from TestCase. Simply create a plain FlexUnit 4 testcase with metadata annotations.
Copy link to clipboard
Copied
Thx mate,
So how can I use the SequenceRunner if SequenceRunner expects a TestCase
sequence:SequenceRunner = new SequenceRunner( this );
Copy link to clipboard
Copied
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;
Copy link to clipboard
Copied
opps, I imported
import net.digitalprimates.fluint.sequence.SequenceRunner;
Copy link to clipboard
Copied
Can't count how often I fell into the same trap
Copy link to clipboard
Copied
so why 2 of them?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Ah thanks michael