Card plugins are looking to be a powerful extension point for Shuffl, allowing as they do for arbitrary additional logic to be associated with a card. This extra logic may encompass data handling, user interactions and external system interactions.
This presents a challenge for testing, especially as it has proven tricky to simulate user interaction with other jQuery plugins, such as editable text values, without resorting to external testing tools like Selenium. (I have used Selenium in the past, and it has been very useful, but it does involve working with a whole new framework, and in my experience it can be unreliable when testing event-intensive browser code. I prefer to stick with the simple jQuery testing framework for unit testing, though I do expect to eventually adopt a UI testing framework as well.)
The approach I'm taking is based on what we did with the FlyWeb project: there, we adopted a pattern for widgets based on the Model-View-Controller (MVC) pattern. Essentially, all updates to the browser display and user interactions were decoupled from the main system logic through a generic "Model" facility with which code interacts using a publish/subscribe (or "Observer") pattern.
I've looked at replicating this for Shuffl, and was able to create a simple jQuery plug-in that provides a model and model-listener capability for any jQuery object, all in little more than 20 lines of code! It turns out that jQuery already has most of the logic required, between its data() method, and its event bind, unbind and trigger capabilities. I've simplified the pattern from FlyWeb by also using the model interface to also serve as a controller interface for a Shuffl card - that is, external interactions with a card are by setting, getting and listening for changes to model values.
With this in place, I have refactored the existing Shuffl card plugin code to use browser DOM accessing methods only for rendering the display, and otherwise top use the model as the primary interface for a card. The biggest changes have been that user input is recorded by updating the model, with listeners reflecting those changes to the browser DOM, and card serialization is now performed entirely from the model, where previously it involved reading values from the DOM.
This allows test code to be written that updates the model and looks for appropriate changes in other model values and/or in the browser DOM. Code that is not covered by this testing regime is reduced to those areas that respond to user inputs and generate appropriate callbacks, and generation of graphical displays; so far, such untested logic is almost entirely within off-the-shelf jQuery plugins.
Making these changes, and in particular adding new test cases for card interactions, has allowed me to discover and correct a number of bugs in the existing code. I count this a win, even though I spent 2.3 days on an activity budgeted for just half a day. The overrun is mostly caused by retrofitting the new MVC-derived pattern to existing widgets, and creating additional test cases for these.
The jQuery model plugin is at http://code.google.com/p/shuffl/source/browse/trunk/src/jquery.model.js.
No comments:
Post a Comment