Datasheet

Chapter 1: Building Resources
23
In this book, I m going to try where possible to present working tests for the code samples as they are
presented. The idea is to give you a sense of strategies for testing various parts of a Rails application, and
to reinforce the idea that writing tests for all your Rails code is an achievable and desirable goal.
I d like to start by reinforcing the previously created tests for the Recipe new form and the create
method. For
new , I d like to confirm that the expected elements in the form actually exist, and for
create , I d like to confirm that when those elements are passed to the server, the expected recipe object
is created. For both, I d like to test the ingredient functionality.
Asserting HTML
To test the form, you ll use an extremely powerful feature of the Rails test environment called assert_
select
, which allows you to test the structure of the HTML sent to the browser. Your first usage of
assert_select just scratches the surface of what it can do. The following test is in tests/
functional/recipe_controller_test.rb
:
def test_should_get_new
get :new
assert_response :success
assert_select(“form[action=?]”, recipes_path) do
assert_select “input[name *= title]”
assert_select “input[name *= servings]”
assert_select “textarea[name *= ingredient_string]”
assert_select “textarea[name *= description]”
assert_select “textarea[name *= directions]”
end
end
The strategy in testing these forms is to verify the structure of the form. Writing tests for the visual
aspects of the form is likely to be very brittle, especially this early in development, and would add a lot
of cost in maintaining the test. However, no matter how it s displayed, the recipe form is likely to have
some method for entering a title. You could test based on the CSS class of each form, if your design
process was such that those names are likely to be stable. Then you could experiment with the visual
display via the CSS file.
Each
assert_select test contains a selector, and the job of the test is to validate whether the HTML
output of the test has some text that matches the selector. This is roughly equivalent to a regular
expression; however, the selectors are specifically structured for validating HTML output. Each selector
can contain one or more wildcards denoted with a question mark, and the next argument to the method
is a list of the values that would fill in those wildcard spots similar to the way the
find method works
with SQL statements. The wildcard entries can either be strings or, if you are determined to make it
work, regular expressions.
The first part of a selector element is the type of HTML tag that you are searching for. In the case of your
first test, that s a
form tag. Without any further adornment, that selector will match against all form tags
in your returned HTML. You can then pass a second argument if it s a number or a range, and then the
selector tests to see if the number of tags matches. The following tests would pass:
assert_select “form”, 1
assert_select “form”, 0..5
c01.indd 23c01.indd 23 1/30/08 4:02:27 PM1/30/08 4:02:27 PM