Thanks for share your experience!!

2011/6/9 Ed <[email protected]>

> I like to share some testing experience with you, as I am very happy
> about it:
>
> I have a GWT app that contains some complex business rules/logic which
> are  difficult to test as they are embedded in the View.
> This is something that always frustrated me as bugs very difficult to
> track.
>
> Used testing:
> 1) I use the MVP(C) pattern everywhere possible and make presenter
> tests.
> 2) I use a few GWT  tests but they always give me problems as I am
> running in -noserver mode.
> 3) I use Selenium tests for display testing (running all Selenium
> tests take more then 30 hours on one machine).
>
> I tried to extract/put this difficult-to-test embedded business logic
> (BL) in to a presenter, but things got very ugly and difficult to
> maintain. I found out that MVP is great but not always suitable.
>
> ## An example of BL that I couldn't test with one of the above
> methods:
> I have a menu on the left side that show a display on the right side
> with  text box entries that the user can fill in. The user can add and
> remove new entries and erase the content of a line that contains a
> collection of entries.
> The content of the entries are stored and retrieved from a central
> data model. It's retrieved when the display is shown and stored when
> the user selects another menu item such that it navigates away from
> the current display (not earlier as might want to undo his changes if
> they aren't valid for example).
>
> ## I want to test the following scenario:
> Correct storage of the display value in the data model. That sounds
> simple but suppose a member erases some entries and removes some
> entries and creates a few new ones. You have to register the removed
> entries such that they are removed from the data model when the user
> selects another menu item (not earlier).
> Testing this with Selenium was hard as these details aren't easy made
> visible on the screen. Detail: i had to save the data model to the
> backend and restart the application such that the display is filled
> with the earlier stored data.
> However, it's important to test this as bugs are unacceptable in this
> part.
>
> It was bothering me for quite some time now that I couldn't test this
> until GWT came out with the IsWidget interface in version 2.1. This
> interface is implemented by Widget. It's main use is for View's that
> implement IsWidget and can easier be mocked. But it's not really meant
> on detail level were I want to use it for.
> I was asking for a Widget interface for a long time and finally
> IsWidget appeared which was good enough for me...
>
> ## My Solution to test the above:
> The idea:
> Let all widgets implement AsWidget instead of extending of Widget and
> create the Display widget as late as possible.
> With a few exceptions you could say: the actual creation of the
> display widget should only occur when it's attached to some panel.
>
> Changes I made:
> In general I never use the GWT panel's directly, but use them trhough
> own Panel wrappers such that I can add functionality like insert/
> removal animations (I opened a Feature request about this a long time
> ago: 3867) .
> I changes the add/insert/remove methods in the Panel wrapper to accept
> the IsWidget as type and store the IsWidgets widgets in a private
> collection.
> The contained GWT panel is only used when GWT.isClient yields true.
> Side note:  because of this private collection,  the panel wrapper
> returns the IsWidget instance that was added/inserted when requested
> with the method gwtWidget(int) instead as with the GWT panel, that
> always return the Widget instead, even if you inserted the IsWidget
> object that contains the Widget itself. This is confusing (see
>
> http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/e7007d4d4098627b
> for discussion about this).
>
> I changed the involved widgets to implement the IsWidget interface and
> no longer extend from Widget.
> The widget is only created when needed such that the method
> IsWidget.asWidget() is called.
> The idea is that you embed your view in your presenter (Embedded View
> Pattern), see Martin fowler for details about this.
> So basically we split up a widget in a Logical and Display widget.
>
> That's basically it. It's pretty cool to finally be able to unit test
> (and fast) Widgets or a collection of Widgets, like a new world opens
> up :)
> Of course you this isn't some kind of Perfect solution, but perfect
> solutions don't exists in general, but you can test a lot more then
> before.
>
> ## Fine tuning:
> I fine tuned things a bit:
> - A widget will also want to create it self when you set the style,
> debug id, etc... on the widget, so you have to fine tune your code
> such that it occurs only when the widget is created, or cache these
> settings and add them when the widget is created. I choose for the
> latter option through a small parent class called SimpleIsWidget that
> implements IsWidget that overrides methods like setStyleName,
> ensureDebugId, etc.. (add as much as you want). My widgets extends
> from SimpleIsWidget and the parent class will cache/buffer style/debug
> settings till it's created. It will automatically ask the subclass to
> create the display widget when needed or when the method asWidget() is
> called. This works pretty well.
>
> - When listening for an event, the event will contain the display
> widget that triggered the event. However we often want the logical
> widget that created the display widget to perform additional actions
> as the display widget doesn't contain any BL.
> Example: class Entry that extends SimpleIsWidget, creates widget
> EntryDisplay that extends Widget that is contained in the received
> event (like a click event).
> I added the interface HasCreator that the created display widget can
> implement and will return the Logic widget. As such that the Logical
> and Display widgets are associated bidirectional.
>
> I hope this helps you with your testing.
>
> I also hope that the GWT dev team will further extend the usage of the
> IsWidget interface in the GWT framework such that testing becomes
> easier and more testing can be done without the use of the slow
> GWTTestCase method. I opened an issue about this some time ago and
> hope that developers recognize the need for this and vote the issue
> such that the GWT dev team will realize the required changes to gain
> better testing.
> The issue: 6113 (http://code.google.com/p/google-web-toolkit/issues/
> detail?id=6113)
>
> - Ed
>
> --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to