Hey guys!
We used to write our UnitTests with FlexUnit and we were just testing our model. Now we want to test the view too. Before i run my tests i create an instance of my view and my model to test the stuff. When i try to access the view i get a null pointer exception. If i add the view to the displaylist it somehow works - even if i remove it from the list right after adding.
it looks something like this:
var myView: MyView = new myView();
//myView.initialize(); will throw error
Application.application.addChild(view);
Application.application.removeChild(view);
myView.initialize(); // will work
Hope you can give me a hint.
Sims
Flex UIComponents do not walk through the component lifecycle until after they are added to a container. As such, variables may not be initialized and children may not be created if you never add it to a container.
More info on the Flex Component LifeCycle. You'll notice there are 11 steps after the component is added to the container.
I suspect that adding it, then removing it, could cause other issues but it depends what you're trying to test.
To know your exact error, we'd have to see what code is in the initialize method on the view. Most likely it accesses a child that was not created yet.
MXML components will often masks the lifecycle steps, but a component will still go through them.
I hope this helps; but since you didn't ask a question I'm not sure if that was the information you were after.
In addition to what (www.Flextras.com) wrote, which I was just about to post as well, you might consider a different approach to testing your views.
First, consider a separation pattern like Presentation Model, MVP or MVC. They allow you to separate your view from your view behavior and test the behavior separate from the view. An approach like this, when done correctly, will take you a long way because you minimize or eliminate the AS3 code in your view.
If you really want to test your views, I would suggest that you use a functional testing tool for this. Unit test frameworks are good for testing classes in isolation. Once you start talking about views, which have complicated lifecycles, a functional testing framework starts to make sense.
Look at FlexMonkey as an example of a functional UI testing framework for Flex.
I recommend you to use User Interface Facade described here or here. This functionality is designed specially for UI componets testing.
Related
Actually I am trying to structure my project in a clean MVVMV way. Unfortunately to this restriction I need to find a way to set pins to the map without the power DataBinding. One workaround could be to have the View in my ViewModel and set it directly.
Right now I don't have any chance to get the registered view. Does it make sense to extend the XLabs.Forms.Mvvm.ViewFactory?
Before adding a new issue on GitHub, my hope is that there is a better solution to handle such restrictions. I always used MVVM in my (small) WPF projects.
No that doesn't make sense. Your best approach would be to extend the Maps class to make Pins an ObserverableCollection that is bindable.
The new documentation format on the Xamarin site is rather difficult to read and does not provide the information you require at hand like it used to but I believe the Pins object is not bindable.
Take a look at the Xamarin Forms Labs Github project to get an idea of how this can be done. The approach is defined particularly well in the ExtendedPicker classes (here the items are bound to an ObservableCollection).
I'm developing an infrastructure for a major project currently based on caliburn 1.
It works fine but it seems like the future is in caliburn micro, am I right?
If I do, how do I implement filters? How do I specify view to a view viewnodel (non conventional)?
And whats the best place to put my splash logic (not root model)
I recommend moving to Caliburn.Micro as it's simpler and easier to extend. It is where any future innovations will be made and it has a larger more active community. As far as filters go, you can actually build them and plug them in. See here Marco's post You can add non-conventional view specification as well. You just plug into the view locator and teach it how to find views. For example, if you want to use an attribute, you can just have the locator look for that attribute first, use it if found, otherwise fall back to the default behavior. Regarding splash logic, you can do that by customizing the Bootstrapper.
Just wanted to ask about what to do when using as includes (ie <fx:Script source="includes/my_as3_file.as" />.
The problem is that in all of my files I'm using class-only modifiers, such as private, public protected, and FB sometimes protests regarding these. A friend told me that what he does is changing the file extension to .ias, but in this way, he loses code highlighting, content-assist and enabling breakpoints.
Thanks.
I like to use something called a ViewHelper (posted a link)
http://www.kensodev.com/2010/08/19/keep-your-mxml-files-neat-with-view-helpers/
This way, the MXML file is pure MXML at all times, and the view helper is coupled and has a reference to the view meaning you can do something like this in your view helper
myView.dataGrid.visible = false;
And of course many more things.
Even when I use RobotLegs's mediators, I still use the view helper for all actions that concern the view such as animations, hiding and shoeing things, state changing and more. I use the mediators only to mediate with the RobotLegs framework (re-dispatch events) and listen to the eventDispatcher.
Personally, I'm not a fan of using includes. As you've mentioned, it tends to obfuscate what's actually going on within a view, and makes it difficult to quickly scan a file and grok it's behaviour.
One of the best practices I've always followed is to reduce the amount of code within an <fx: Script /> block to almost none.
If you are using an include file, this suggests that your views are very script-heavy, which can lead to poor code reuse, and difficulty in writing testable code.
Instead, consider using the Presentation Model pattern where the logic is moved out to a separate class. Alternatively, there's also the Mediator pattern, however personally I've found this leads to more heavily coupled code - though that's likely down to my crappy execution, than a failing of the pattern.
Use code behind!
or
[mxml_file]AS.as for Actionscript file name.
ex MXML: MyView.mxml and the as file MyViewAS.as
then it will look like <fx:Script source="MyViewAS.as" />
Renaming the .as file to .ias, in my opinion, is one of the worst solutions one can come up with ( it's just horrible ). I also kinda disagree with Marty, because in Flex 4, the architecture is different from Flex 3 ( although Spark is built on top of MX - if we were talking about Flex 3, then I'd agree with what Marty said ). In Flex 4, the Skin is now considered to be the "View" and class making use of the view is the "Controller"... meaning that things are now much better separated than they were in Flex 3, where a components kinda played the role of both the View and Controller ( http://www.slideshare.net/saurabhnarula/flex-4-skinning-2634949 ).
Coming back to the original problem: It's true that Flash Builder is not perfect, but if you know that you don't have any errors in your code and it keeps on throwing some weird stuff at you, then simply try closing it and starting it again ( Clean your project afterward ). Whenever I set an .as file as the source for my MXML component, I like to have the file next to the MXML class ( ex: MyMXMLComponent.mxml and MyMXMLComponentAS.as, both being at the same level - source="MyMXMLComponentAS.AS" ). This 99% of the time works fine, but really rarely, I might have also received some weird errors from Flash Builder ( which usually got solved by closing it and cleaning the project afterward - on a couple of occasions, there was actually an error in my code which seemed to totally confuse/crash the compiler and make it throw some really senseless error messages, so definitely try to make sure that your code is correct ).
Personally, I'd suggest that instead of using .as files, you try to use the "code behind" approach ( search on Google / Adobe for more info on this - I wanted to post a link, but since I'm a new user, I'm limited to 1 link / post... hah ). Using code behind, you will surely never run into the problems you might run into with .as file and you will surely never have problems with code hinting. In case you have never used code behind before, then it might feel "strange" at the beginning, but you'll get used to it and you'll surely not want to write code "the old way" ever again.
Has anyone had any luck testing a Flex app without static Automation IDs attached to components? All of the elements in the apps are generated .....
We've investigated FlexMonkey but it appears to be incompatible with any app that utilizes the ExternalInterface. RIATest's scripting language leaves much to be desired...
Thanks-
Jonathan
Unfortunately I don't know much about this kind of stuff, but I went to a talk that presented these tools for TDD:
- Hudson
- Flex Unit 4
I guess there are tutorials online, don't know if it helps with ExternalInterface testing.
Is there anything that prevents you from generating appropriate automationNames for your generated components? This way you should be able to refer to them properly in automation tools.
Are there any other non-changing properties that your generated components have, like maybe 'id'? If so you can use these properties to address the components. This is definitely possible in RIATest.
FunFX is a Flex automation tool that allows you to access components via ID, "automation name", "automation value" or index. While using something like the component index might be less than ideal for robust tests, if that's all that's stable, it might be worth a try. And it's written in Ruby, so that should satisfy any "real programming language" related requirements. :)
We added an "automationPrefix" property to many of our custom controls (particularly those that are reused many times on a single screen), and wrote code to append the beginning of the automationName property on any child controls. Setting the automationName was the most important parting of enabling automation testing on our Flex apps. There are several ways you could modify the automationName to be unique without making it completely static at the level that most test automation packages need it. We are currently using QTP as the test automation tool of choice.
I am a AS3 novice learning PureMVC and want to write code following best practices so that any other AS3 developer can pick up my code and easily understand what I did, I am tempted to do stuff as I would in JavaScript or Asp.Net/C#, but I have a feeling that might not be the best approach.
Thoughts? Links?
Using reverse domain folder structure is common from the Flex code I have seen. ie:
com/mydomain/myproject/view ... model, business, controller (this would make it easy for me to understand your code)
More: http://blog.tsclausing.com/post/11
ASDoc is a tool that creates very pretty HTML documentation from code comments automatically:
http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=asdoc_127_1.html
You may be beyond this point but I have used Cairngorm (MVC) and it was well documented:
http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm
Code Example
This is the Cairngorm store which is the standard Cairngorm example:
http://cairngormdocs.org/blog/?p=17
I found that reading through the docs helped me get a clear definition of each of the parts to PureMVC. On top of that I downloaded the source for the demos and added them in Flex Builder so I could look through them easily and see how they were constructed to get an idea of how I should construct my project.
One thing you have to remember is that you can do things any way you want, but to make using the framework worthwhile you should stick to the structure and way of doing things that it suggests. For example you could give your view a reference to the facade and have it get information from Proxies etc. But you should keep the view decoupled from the framework and just have it dispatch events and have a Mediator deal with the facade.