Sue needs a system for managing Seminars for knowldge diffusion to students. Sue have identified two main actors: herself as organizer of seminars, and students as attendees. For the moment the system is not required to manage speakers. For the moment, the most important stories are (with their id in parenthesis):
- A student can list the forthcoming seminars (ListSeminars).
- A student can view the summary of a seminar (ViewSeminarSummary).
- A student can register for a seminar (RegisterToSeminar).
- A student can view the participants of a seminar (ViewSeminarParticipants).
from ezweb.stories.model import *
from ezweb.stories.cherrypy import generate
student = Actor(
name='Student',
usecases=[
UseCase('View list of seminars'),
UseCase('View the summary of a seminar'),
UseCase('View the participants of a seminar'),
UseCase('Register for a seminar')
]
)
seminars = Application(
name='Seminars',
actors=[student]
)
generate(seminars)
We start with the ListSeminars story using Instant Feedback. Sue says: "There is no information to provide, and for each seminar we want: the name of the seminar, its date, and the room where it takes place."
Using ezWeb we can translate her specification as:
from ezweb.pages.model import *
from ezweb.pages.cheetah.generate import generate
# we need a list
list_of_seminars = List(
name='list_of_seminars',
details='get_details',
content=[
ListItem('name'),
ListItem('date'),
ListItem('room'),
]
)
# the page contains only the list
view_the_list_of_seminars = Page(
name='view_the_list_of_seminars',
css='/css/style.css',
content=[
Header(title='Seminars'),
sidebar,
Main(name='List of seminars', content=[list_of_seminars]),
Footer(content=[footer])
]
)
seminars = Site(
name='Seminars',
module='seminars',
pages=[
view_the_list_of_seminars,
]
)
generate(seminars)
Note: A page is split in four parts (only the Main is detailed above):
- Header: name of the application,
- Menu: containing links to the various features,
- Footer: containing recurrent information,
- Main: containing the input / output for a feature.

Sue says that it does not looks like a list, couldn't she see an example of seminars?
The following code excerpt is the one generated by default from the description of scenarios.
class ViewListOfSeminars(object):
def __init__(self):
pass
@cherrypy.expose
def index(self):
return bindings.view_the_list_of_seminars()
To provide Sue a more accurate vision, we simply add fake objects in the default code for the feature.
class Seminar(object):
def __init__(self, name, date, room):
self.name = name
self.date = date
self.room = room
class ViewListOfSeminars(object):
def __init__(self, ctrl):
self.ctrl = ctrl
@cherrypy.expose
def index(self):
seminars = [
Seminar('Agility, XP, Scrum', '2007-05-15 14:00:00', 202),
Seminar('Java Generics', '2007-05-29 14:00:00', 202),
Seminar('Python', '2007-05-22 14:00:00', 202),
]
return bindings.view_the_list_of_seminars(seminars)
Then we can show Sue a more realistic list of seminars. This time she just says nice.

On the basis of this small interaction, we now have an acceptance test for the story ListSeminars. On this basis we can write an automated test, and really implement the story: defining the database tables together with the code to extract information from the database (i.e. the true implementation for ViewListOfSeminars.index).
Tools such has ezWeb may be implemented in various languages and environments. The time it took to develop it (about 2 weeks --but only two dozen hours of work-- for a usable version of ezWeb in the context of CherryPy, Cheetah, SQLObject) worth the ROI (return on invest) as we use it in the project for air quality.