we decide to ignore that and go off adding attributes to our database model objects
instead.
We might have ideas in our head about the new desired behaviour of our inner layers
like database models, and often these ideas will be pretty good, but they are actually just
speculation about what’s really required, because we haven’t yet built the outer layers
that will use them.
One problem that can result is to build inner components that are more general or more
capable than we actually need, which is a waste of time, and an added source of com‐
plexity for your project. Another common problem is that you create inner components
with an API which is convenient for their own internal design, but which later turns
out to be inappropriate for the calls your outer layers would like to make …worse still,
you might end up with inner components which, you later realise, don’t actually solve
the problem that your outer layers need solved.
In contrast, working outside-in in allows you to use each layer to imagine the most
convenient API you could want from the layer beneath it. Let’s see it in action.
The FT for “My Lists”
As we work through the following functional test, we start with themost outward-facing
(presentation layer), through to the view functions (or “controllers”), and lastly the
innermost layers, which in this case will be model code.
We know our
create_pre_authenticated_session
code works now, so we can just
write our FT to look for a “My Lists” page:
functional_tests/test_my_lists.py.
def
test_logged_in_users_lists_are_saved_as_my_lists
(
self
):
# Edith is a logged-in user
self
.
create_pre_authenticated_session
(
'edith@example.com')
# She goes to the home page and starts a list
self
.
browser
.
get
(
self
.
server_url
)
self
.
get_item_input_box
()
.
send_keys
(
'Reticulate splines
\n
'
)
self
.
get_item_input_box
()
.
send_keys
(
'Immanentize eschaton
\n
'
)
first_list_url
=
self
.
browser
.
current_url
# She notices a "My lists" link, for the first time.
self
.
browser
.
find_element_by_link_text
(
'My lists'
)
.
click
()
# She sees that her list is in there, named according to its
# first list item
self
.
browser
.
find_element_by_link_text
(
'Reticulate splines'
)
.
click
()
self
.
assertEqual
(
self
.
browser
.
current_url
,
first_list_url
)
# She decides to start another list, just to see
self
.
browser
.
get
(
self
.
server_url
)
324
|
Chapter 18: Finishing “My Lists”: Outside-In TDD