Philip Gatt
2005-Aug-16 00:55 UTC
Duplication between unit and functional tests in Agile Web Development with Rails
According to the new Agile Web Development with Rails book, if Dave Thomas wanted to change the "to address" for emails, he''d have to update unit and functional tests. Is this an oversight or done this way on purpose? class OrderMailerTest < Test::Unit::TestCase def setup @order = Order.new(:name =>"Dave Thomas", :email => "dave@pragprog.com") end def test_confirm response = OrderMailer.create_confirm(@order) assert_equal("Pragmatic Store Order Confirmation", response.subject) assert_equal("dave-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org", response.to[0]) assert_match(/Dear Dave Thomas/, response.body) end end class OrderControllerTest < Test::Unit::TestCase fixtures :orders def setup @controller = OrderController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @emails = ActionMailer::Base.deliveries @emails.clear end def test_confirm get(:confirm, :id => @daves_order.id) assert_redirected_to(:action => :index) assert_equal(1, @emails.size) email = @emails.first assert_equal("Pragmatic Store Order Confirmation", email.subject) assert_equal("dave-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org", email.to[0]) assert_match(/Dear Dave Thomas/, email.body) end end
Jarkko Laine
2005-Aug-16 06:32 UTC
Re: Duplication between unit and functional tests in Agile Web Development with Rails
Philip, On 16.8.2005, at 03:55, Philip Gatt wrote:> According to the new Agile Web Development with Rails book, if Dave > Thomas wanted to change the "to address" for emails, he''d have to > update unit and functional tests. Is this an oversight or done this > way on purpose?These are just tests. It doesn''t really matter what addresses you use in them. In the unit tests, an order is created in the setup phase with an address and later it is tested that the address is exactly the same in the mail object. In the functional tests the situation is similar, just the original address is probably fetched from a fixture file. //jarkko> class OrderMailerTest < Test::Unit::TestCase > def setup > @order = Order.new(:name =>"Dave Thomas", :email => > "dave-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org") > end > def test_confirm > response = OrderMailer.create_confirm(@order) > assert_equal("Pragmatic Store Order Confirmation", > response.subject) > assert_equal("dave-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org", response.to[0]) > assert_match(/Dear Dave Thomas/, response.body) > end > end > > class OrderControllerTest < Test::Unit::TestCase > fixtures :orders > def setup > @controller = OrderController.new > @request = ActionController::TestRequest.new > @response = ActionController::TestResponse.new > @emails = ActionMailer::Base.deliveries > @emails.clear > end > def test_confirm > get(:confirm, :id => @daves_order.id) > assert_redirected_to(:action => :index) > assert_equal(1, @emails.size) > email = @emails.first > assert_equal("Pragmatic Store Order Confirmation", email.subject) > assert_equal("dave-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org", email.to[0]) > assert_match(/Dear Dave Thomas/, email.body) > end > end > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Jarkko Laine http://jlaine.net http://odesign.fi _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Alex Verhovsky
2005-Aug-16 08:01 UTC
Re: Duplication between unit and functional tests in Agile Web Development with Rails
Jarkko Laine wrote:> On 16.8.2005, at 03:55, Philip Gatt wrote: > >> According to the new Agile Web Development with Rails book, if Dave >> Thomas wanted to change the "to address" for emails, he''d have to >> update unit and functional tests. Is this an oversight or done this >> way on purpose? > > These are just tests. It doesn''t really matter what addresses you use > in them. In the unit tests, an order is created in the setup phase > with an address and later it is tested that the address is exactly the > same in the mail object. In the functional tests the situation is > similar, just the original address is probably fetched from a fixture > file.I''m not Dave Thomas, but ... here is my humble opinion, anyway - it has some controversial points that are perhaps worth discussing :) There seem to be two issues here: duplication of code between unit and functional tests and the use of hard-coded expected values. Re duplication, it is not actually all that evil in tests. If you write a Rails app using the test-driven method, you often end up testing for the same thing at both levels. I prefer to keep both, and here is why. On one hand if you have some breakage you want the simplest possible test to tell you about it (much easier to understand the problem when it''s isolated to a single three-liner method, as opposed to a dozen classes and half the framework code in between). On the other hand, you do also need to test at the integration (controller) level, obviously. Besides, this has some documentation value. Test methods should be organised in such a way that they say to a reader "1. Here is how this method should work under normal circumstances. 2. And here is what should happen when we change the circumstances this way. 3. And here is another iteresting variant, etc". Most of the duplication between unit and integration tests seems to happen in the success scenarios. Re the hard-coded values vs named constants (or references to fixture values, or some other form of indirection that makes them easy to change). Having tried it both ways, I now prefer to use named constants in production code, but hard-coded values in tests . Especially for strings. It is much easier to read, and also when the test breaks, having a hard-coded expected value right in front of your eyes eliminates many possible causes. So, unless an expected value is difficult to explain or needs some calculation, I write it down explicitly. Expected values rarely change, hence YAGNI [http://c2.com/cgi/wiki?YouArentGonnaNeedIt] Dragging myself away from the soapbox, Alexey Verkhovsky
Philip Gatt
2005-Aug-16 19:17 UTC
Re: Duplication between unit and functional tests in Agile Web Development with Rails
> I''m not Dave Thomas, but ... here is my humble opinion, anyway - it has > some controversial points that are perhaps worth discussing :) > There seem to be two issues here: duplication of code between unit and > functional tests and the use of hard-coded expected values.The duplication is what got me. I was working on a mailer, and changed the subject line slightly. I then realized I broke 2 tests - unit and functional. That seemed like some sort of code smell. So, I turned to the wonderful Rails book, and noticed they had the same "problem." So far, the consensus seems to be that we should just accept it and not worry about DRY in tests so much. I''d love to hear different opinions on this. - Philip