Testing named_scope
Posted by Tammer Saleh
Jul 29
We’re huge fans of NamedScope here at Thoughtbot. It does wonders for finder reuse and clarity. Unfortunately, it also creates a large number of finders that all must be tested, where the old method may have only created one.
To help out with the testing of simple named_scope definitions, we added a helper to Shoulda, should_have_named_scope:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class User < ActiveRecord::Base named_scope :old, :conditions => "age > 50" named_scope :eighteen, :conditions => { :age => 18 } named_scope :recent, lambda {|count| { :limit => count } } end class UserTest < Test::Unit::TestCase should_have_named_scope :old, :conditions => "age > 50" should_have_named_scope :eighteen, :conditions => { :age => 18 } should_have_named_scope 'recent(5)', :limit => 5 should_have_named_scope 'recent(1)', :limit => 1 end |
Now for complex methods, where the options returned by the has_finder are hairier than a simple limit or a single column condition, we would also write black box tests. But this helper is great for those simpler calls.
Comments on this post
Jul 29
theJareCare said,
i’d use this helper if it were actually testing my code ;). all this is doing is duplicating the implementation, basically testing that i typed in the correct characters. there’s no testing of the actual functionality.
i prefer traditional state-based testing i.e. setting up local fixtures, exercising the code and then running assertions on the results. yes, its more code but its a full test; these helpers are like partial tests only testing the fact that im using #named_scope (im assuming they’re using Scope#proxy_options which would fail if i wasn’t)
- jc
Jul 30
Carlos Brando said,
Bundle updated! http://github.com/carlosbrando/ruby-shoulda-tmbundle/tree/master
Jul 30
John said,
Hi, I’ve been trying to get my head around Rails testing, and I have to agree with the first poster (theJaleCare). What is the example actually testing? It looks like it’s just testing the framework code. And if that hasn’t been tested, there’s a much bigger problem! Most tests I’ve seen, and testing tutorials pretty much do the same thing – test_added_to_database. It’ll add a record to the DB and then check to see if it’s there. Again, if that functionality didn’t work, there’s a huge problem!
Can someone point me to some examples of testing that actually test something besides the framework? I’ve looked at many various Rails apps and have yet to find tests that are beyond the simple “add an item to the db, is there now one item in the table?” type.
Thanks!
Jul 30
Tammer Saleh said,
John & theJareCare: Here’s an example of where you would be testing the finder logic, and not the SQL that it produces.
Using blackbox testing for this method would definitely result in greater test coverage. It would also mean that you’d have to create a large number of records, each with different names, scores, and popularity rankings, and assert that they’re returned in the right order. The tests would also have to ensure that the object returned can be chained with other finders.
Compare that to:
And to be clear: the only thing we aren’t testing here is that an SQL call with order set to “first_name DESC” returns the records ordered by first_name. That is a definite gap in the test coverage. In return for that gap, you get test suite maintainability.
Jul 30
theJareCare said,
you admit there’s a gap in the test coverage and in return that gives you ‘test suite maintainability’? so you prefer less code and shotty tests over a few more lines of test code and tests that actually test the functionality of your app?
lines of code is a poor metric for determining that an app is not maintainable, only the quality of those tests should be used in determining maintainability. lines of code can only give you a rough indicator of whether an app is tested at all, in no way can it tell you what is and what isn’t tested or how effective those tests are.
Jul 30
Eric Anderson said,
I agree with the first poster. This is not meant to criticize the test helper you have developed but just something I have been thinking about in general. I feel like a lot of tests are:
1. Add a Record 2. Make sure that record exists
Obviously if you are developing an ORM then you need test like the above. But on the other hand if you are just using a ORM then you should rely on that library’s testing (and if it is insufficient then test there). Another example. If I have the following:
In my mind there is nothing here that needs to be tested. We are purely just using the library and all testing would do is make sure we typed the characters right (and if we doubt that what makes us think we can type the test characters right).
The only time you need to test is in YOUR projects code. For example if I add a complex :conditions parameter I might test it (but simple :conditions I probably won’t because again we are just using the library). Or if I add a before_filter I might test that. In general my rules are:
If the answer to either of these questions is YES then I often don’t see a need for testing. You are just increasing the size of your code base without really doing anything.
Aug 01
Morgan Roderick said,
We have been using shoulda since it’s early public releases, and welcome these updates, as they will be valuable in sketching out the scopes that other functionality in the system will rely on.
The complaints about lacking test coverage is a bit strange to me. Shoulda now provides an easier way to quickly sketch out requirements for a named scope, which is part of the public interface of a model. If you want to ensure quality test coverage, you should use your brain and not rely entirely on tests written using a dsl … but a few tests written using a dsl will get you off the ground quickly.
How much complexity would it add to Shoulda, to have exhaustive end-to-end tests for named scopes? How often would you use these? Would the value of such tests outweigh the costs?
@Eric: Is testing the public interface of a class of less value to YOU than testing if a record has been written to a database, or some condition is set to a specific value?
I find that in colloboration with other developers, having tests for the public interfaces is of great value, as you might think twice about modifying the public interface when you start breaking tests :-)
Sorry, comments are closed for this article.
© 2000 - 2009 by thoughtbot, inc.
written by a bushel of tiny robots
Come “ride the toad” on Hoptoad, the app error app.
Thunder Thimble: Brand monitoring for social media.
Widgetfinger: Simple content management for simple websites.
Tee-Bot, funny shirts your friends won't understand!
Umbrella Today: “It’s like totally the simplest weather report ever, Julie.”
Thoughtbot
thoughtbot is a technology consulting firm that provides web application development and design services. We focus on building modern systems, embracing good ideas and delivering elegant solutions.
Interested in learning Rails?
Sign up for our beginning or advanced training.
Archives