Exploration Through Example

Example-driven development, Agile testing, context-driven testing, Agile programming, Ruby, and other things of interest to Brian Marick
191.8 167.2 186.2 183.6 184.0 183.2 184.6

Sat, 18 Feb 2006

Model-Renderer-Presenter: MVP for web apps?

A client and I were talking over how Model-View-Presenter would work for web applications. The sequence diagram to the right (click on it to get a bigger version in a new window) describes a possible interpretation. Since the part that corresponds to a View just converts values into HTML text, I'm going to call it the Renderer instead. The Renderer can be either a template language (Velocity, Plone's ZPT, Sails's Viento) or—my bias—an XML builder like Ruby's Builder.

I did a little Model-Renderer-Presenter spike this week and feel pretty happy with it. I'm wondering who else uses something like what I explain below and what implications it's had for testing. Mail me if you have pointers.

(Prior work: Mike Mason just wrote about MVP on ASP.NET. I understand from Adam Williams that Rails does something similar, albeit using mixins. So far handling the Rails book hasn't caused me to learn it. I may actually have to work through it.)

Here's the communication pattern from the sequence diagram:

  1. After the Action gets some HTTP and does whatever it does to the Model, it creates the appropriate Presenter (there is one for each page) and asks it for the HTML for the page.

  2. The Presenter asks the Renderer for the HTML for the page. The Renderer is the authority for the structure of the page and for any static content (the title, etc.) The Presenter is the authority for any content that depends on the state of the Model.

  3. When the Renderer needs to "fill in a blank", it asks the Presenter. In this case, suppose it's asking for a quantity (like a billing amount).

  4. The Presenter gets that information from the Model.

  5. The Renderer can also ask the Presenter to make a decision. In this case, suppose it asks the Presenter whether it should display an edit button. I decided that the Presenter should either give it back an empty string or the HTML for the button. That works as follows:

  6. First, the Presenter asks the Model for any data it needs to make the decision. Suppose that it decides the button should be displayed. But it's not an authority over what HTML should look like, so it...

  7. ... asks the Renderer for that button's HTML. As part of rendering that button, the Renderer needs to fill in the name of the Action the button should invoke. It could just fill in a constant value, but I want the program to check—at the time the page is displayed—whether that constant value actually corresponds to a real action. That way, any bad links will be detected whenever the page is rendered, not when the link is followed. Since there are unit tests that render each page, there will be no need for slow browser or HTTP tests to find bad links. Therefore...

  8. ... the Renderer asks the Presenter for the name to fill in.

  9. The Presenter is the dispenser of Action names. Before giving the name to the Renderer the Presenter asks the Action (layer) whether the name is valid. The Action will blow up if not. (It would make as much sense—maybe more—to have the Action be the authority over its name but this happened to be most convenient for the program I started the spike with.)

What good is this? Classical Model-View-Presenter is about making the View a thin holder of whatever controls the windowing system provides. It does little besides route messages from the window system to the Presenter and vice versa. That lets you mock out the View so that Presenter tests don't have to interact with the real controls, which are usually a pain.

There's no call for that in a web app. The Renderer doesn't interact with a windowing framework; it just builds HTML, which is easy to work with. However, the separation does give us four objects (Action, Model, Renderer, and Presenter) that:

  1. can be created through test-driven design,

  2. can be tested independently of each other,

  3. and can be tested in a way that doesn't require many end-to-end tests to give confidence that almost all of the plausible bugs have been avoided.

The second picture gives a hint of the kinds of checks and tests that make sense here. (Click for the larger version. Safari users note that sometimes the JPG renders as garbage for me. A Shift-Reload has always fixed it.)

More later, unless I find that someone else has already described this in detail.

## Posted at 10:31 in category /testing [permalink] [top]

About Brian Marick
I consult mainly on Agile software development, with a special focus on how testing fits in.

Contact me here: marick@exampler.com.

 

Syndication

 

Agile Testing Directions
Introduction
Tests and examples
Technology-facing programmer support
Business-facing team support
Business-facing product critiques
Technology-facing product critiques
Testers on agile projects
Postscript

Permalink to this list

 

Working your way out of the automated GUI testing tarpit
  1. Three ways of writing the same test
  2. A test should deduce its setup path
  3. Convert the suite one failure at a time
  4. You should be able to get to any page in one step
  5. Extract fast tests about single pages
  6. Link checking without clicking on links
  7. Workflow tests remain GUI tests
Permalink to this list

 

Design-Driven Test-Driven Design
Creating a test
Making it (barely) run
Views and presenters appear
Hooking up the real GUI

 

Popular Articles
A roadmap for testing on an agile project: When consulting on testing in Agile projects, I like to call this plan "what I'm biased toward."

Tacit knowledge: Experts often have no theory of their work. They simply perform skillfully.

Process and personality: Every article on methodology implicitly begins "Let's talk about me."

 

Related Weblogs

Wayne Allen
James Bach
Laurent Bossavit
William Caputo
Mike Clark
Rachel Davies
Esther Derby
Michael Feathers
Developer Testing
Chad Fowler
Martin Fowler
Alan Francis
Elisabeth Hendrickson
Grig Gheorghiu
Andy Hunt
Ben Hyde
Ron Jeffries
Jonathan Kohl
Dave Liebreich
Jeff Patton
Bret Pettichord
Hiring Johanna Rothman
Managing Johanna Rothman
Kevin Rutherford
Christian Sepulveda
James Shore
Jeff Sutherland
Pragmatic Dave Thomas
Glenn Vanderburg
Greg Vaughn
Eugene Wallingford
Jim Weirich

 

Where to Find Me


Software Practice Advancement

 

Archives
All of 2006
All of 2005
All of 2004
All of 2003

 

Join!

Agile Alliance Logo