Update: The new release of assert_select includes support for CSS pseudo classes (nth-child, first-child, empty). More details here. It also supports nested assertions for dealing with lists, tables and forms. Some examples here. I updated this post to use nested asserts.
Update 2:A new release adds support for RJS.
Update 3: assert_select is now part of Rails core. Also, cheat sheet available here.
assert_select helps you write functional tests using CSS selectors.
If you’re using HTML and CSS, you’re already familiar with CSS selectors. CSS selectors have a simple syntax that lets you pick parts of the page and apply styling. assert_select uses the same simple syntax, for testing the content of the page.
You can test that selected element(s) exist, has specific text content, test number and order of elements, and a few more tricks.
Here’s a simple example that asserts the page has the right title:
det test_page_has_right_title get :index assert_select "title", "Welcome" end
And a more complex one that tests a login form:
def test_login_form_has_all_fields get :login assert_select "form[action=http://myapp/login] input" do |inputs| assert_equal 3, inputs.size assert_select "input[type=name][name=username]" assert_select "input[type=password][name=password]" assert_select "input[type=submit][value=Login]" end end
You can also use css_select to pick specific elements and work with them. This example asserts that the page header has all the right links:
HEADER_LINKS = [ ["Main", "http://myapp/"], ["About", "http://myapp/about"], ["Login", "http://myapp/login"] ] def test_page_header_links assert_select "#header>ul>li>a" do HEADER_LINKS.each do |text, href| assert_select "a[href=?]", href, text end end end
Here’s a few more examples:
# Form includes four input fields assert_select "form input", 4 # Page does not have any forms in it. assert_select "form", false, "Page must contain no forms" # Page has one link back to user's page. assert_select "a[href=?]", url_for(:controller=>"user", :id=>user_id), :count=>1, :text=>"Back to page"
The last example uses substituation. The question mark gets replaced with an argument, in this case the result of url_for. You can use strings and regular expressions.
To install assert_select:
./script/plugin install http://labnotes.org/svn/public/ruby/rails_plugins/assert_select
As always, code is under MIT and/or Creative Commons license. Enjoy!