Sorry if this comes across as a bunch of disjointed thoughts…I’m just
trying to put my thoughts down and I’d like to know what other people’s
opinions on the subject are.
I’ve been working with Rails for 3 or 4 months now and I’m constantly
to look at ways of improving my testing techniques, especially when it
to TDD. I have a few concerns about the way Rails approaches tests with
regards to controllers/models.
Rails has always seemed to apply that you unit test your models and
functional test your controllers. For me however, this distinction
down in practice and leads to what are in my opinion very smelly tests.
Firstly, I don’t like the way that by default Rails assumes you want to
an entire controller in a testcase. I’ve found that this leads to tests
are far to big. I believe better breakdown would be to have a test case
each action, or even a testcase for each action in different contexts.
as an example, say you had an ArticleController with view, post and
actions. The post action simply displays the form which submits to the
Now, instead of having one large ArticleControllerTest, it would make
more sense to break it down into ArticleViewTest, ArticlePostTest,
FailedArticleCreate test and SuccessfulArticleCreate, because each of
represent different contexts, or fixtures.
I’m quite keen on Ben G.’ testing approach outlined
have also been looking into Dave A.’
RSpec http://rspec.rubyforge.org/ and have to agree with the idea of
testcases being bound by fixtures. If you have test methods that require
common setups, the code should be extracted to the setup method. If you
different groups of methods using two different types of setups, this is
indication that you should be creating a new testcase for the new
Overall, I’ve found that trying to test a whole controller leads to
fixtures in one testcase and multiple violations of DRY.
This also leads me on to my other concern, and that is the practice of
testing for the presence of markup in a view using assert_tag. I can’t
really see the value in this, and again it seems to violate DRY to me.
would you want to assert that a tag exists in most cases? For example,
the ArticlePostTest example above, which wouldn’t really do much in the
controller, and simply pass to the view for the rendering of the form.
would I want to test for the structure of the form? Ultimately my form
be laid out using CSS but there are still several ways I could markup my
form, with all variations being “correct”. By testing for one particular
implementation in my test, I’m duplicating the markup in my test and my
view, and binding the test to my implementation of the form. Testing
particular HTML element is present in my view does nothing to tell me
my view is “correct”, therefore I think this makes the test worthless.
Which leads me on to saying that views such as forms are the realm for
proper functional testing using something like Watir or Selenium, not
TestUnit and tag assertions. You want to check that you can fill in the
and submit it, not that the page contains a tag.
So what would I really like to see? No separation of unit and functional
testing in terms of model and controller code. They should all be
unit tests. Functional testing should be the realm of something like
or Selenium, unless somebody can put together a good library that lets
do this kind of functional testing (i.e., filling in forms, interacting
your web application as if it were in a browser) from within your
tests. I’d like to see less emphasis on the idea of testing your
as a whole and testing your different actions as smaller, focussed unit
tests. I think this would also aid with TDD.
Dave A.’ has some good reading material here:
What do you think?