[Rails] Re: second assert_tag failling in rails integration test
Eric Hodel
drbrain at segment7.net
Tue May 23 07:07:32 GMT 2006
On May 22, 2006, at 4:09 PM, Taryn East wrote:
> On Mon, 2006-05-22 at 11:47 -0700, Eric Hodel wrote:
>> On May 21, 2006, at 6:46 PM, Taryn East wrote:
>
>>> Does they work for you? They seem to for the people that use them.
>>>
>>> Do you not do what we are doing?
>>
>> They probably don't, integration testing isn't about testing HTML.
I'm going to take the liberty of rearranging this paragraph.
> we're testing the flow of screens... which I assumed is what
> integration tests are for.
Correct.
> We're not actually testing the html itself, [...] It's just that to
> test that we're arriving at the right screen with the right data on
> it we use assert_tag.
If you're using assert_tag you're testing the HTML.
assert_tag tests at the wrong level. Test assigns instead.
Your functional tests should ensure that data on the controller side
correctly shows up in the right place on the HTML. If you're using
assert_tag you're testing in two places.
> We also use assert_response and assert_template (which seem to be
> the main thing used in integration tests I've found) but you have
> to test not only that *an* edit screen popped up, but that the
> right one popped up and the way to test that is to check that it
> was populated by the data that you actually asked for.
This is the responsibility of functional tests. When your functional
tests ensure that data is in the right spot then you can test based
purely on assigns in your integration tests and cut out a ton of
(duplicated) code.
> We don't test that every bit of data is there (that's what I
> believe belongs in the realm of functional testing - though maybe I
> have that wrong too) but we need to check that something is right
> so for example we check for the existence of one key field, or that
> one input has been pre-populated with previously-chosen data. We
> check that, for example, this occurs whether or not the user is
> still using the same session, or if they login with a different
> session and come to the same page.
And that data gets there via assigns, so exploit that fact and make
your tests simpler. The bigger the test the more likely it is wrong.
> If we are doing this in the wrong way then I would be very
> appreciative of any assistance in directing us towards the correct
> way to test this sort of thing.
I actually think that even functional tests are too high level, so I
wrote Test::Rails to break functional tests down into controller
tests and view tests. I found my functional tests repeating
themselves too much so I needed to get closer to what the real
responsibilities of controllers and views are.
Controller tests ensure that URL params map to the correct assigns
and view tests ensure that assigns map to the correct HTML. Once I
know these tests all pass then integration tests can rely strictly on
assigns and I avoid tons of code.
>>> Are we using the wrong kind of test here?
>>
>> You should be writing functional tests when using assert_tag.
>
> Ok, so then what are integration tests for? It's quite possible
> that we have misunderstood what level of testing we need... but the
> article I read on it here:
> http://jamis.jamisbuck.org/articles/2006/03/09/integration-testing-
> in-rails-1-1
>
> seemed to indicate that integration tests were used for screen
> flow... which is what (afaics) we are doing.
Testing is broken into multiple layers. What you test on one layer
shouldn't be tested on another. What is tested on one layer you can
rely on in a higher layer.
Here's an untested example:
class EntryControllerTest < Test::Rails::ControllerTestCase
fixtures :entries
def test_view
get :view, :id => entries(:frogs).id
assert_response :success
assert_template 'entry/view'
assert_assigned :entry, entries(:frogs)
end
def test_edit
get :edit, :id => entries(:frogs).id
assert_response :success
assert_template 'entry/edit'
assert_assigned :entry, entries(:frogs)
end
def test_update
post :update, :id => entries(:frogs).id, :body => 'Frogs rock!'
assert_redirected_to "/entry/view/#{entries(:frogs).id}"
entries(:frogs).reload
assert_equal entries(:frogs).body, 'Frogs rock!'
end
end
class EntryViewTest < Test::Rails::ViewTestCase
fixtures :entries
def test_view
assigns[:entry] = entries(:frogs)
render
assert_tag :tag => 'p', :content => entries(:frogs).body
end
def test_edit
assigns[:entry] = entries(:frogs)
render
form_url = "/entries/update/#{entries(:frogs).id}"
assert_post_form form_url
assert_tag_in_form form_url, :tag => 'textarea',
:content => entries(:frogs).body
end
end
Now I know that all the URLs and data will show up correctly I can do
an integration test.
class EntryIntegrationTest < ActionController::IntegrationTest
fixtures :entries
def test_editing
entry = entries(:frogs)
get "/entry/edit/#{entry.id}"
assert_response :success
assert_template 'entry/edit'
post "/entry/update/#{entry.id}" :body => 'Frogs rock!'
assert_response :redirect
follow_redirect!
assert_success
assert_template 'entry/view'
end
end
I already know all the URLs in the HTML will be correct for that
template so I don't need to re-test that.
> In any case even if we are using integration tests completely
> incorrectly.... there is still a bug in the framework if assert_tag
> is failing.
I know exactly what the problem is, and it isn't a problem if you
write your integration tests correctly.
--
Eric Hodel - drbrain at segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant
http://trackmap.robotcoop.com
More information about the Rails
mailing list