Results 1 to 6 of 6
Thread: Tests questions...
Mar 25, 2007, 06:08 #1
I don't understand which is the purpose of rails tests when you write a test that tests a simple functionality that already works if you use it in a browser. This is the same that happens for example in the book where the author write "silly" test to test a thing that is perfectly checkable in a live browser situation. I mean at least i can firstable test the functionality live in a browser than if something goes wrong i can wrtie a test for it...is that wrong?
Mar 25, 2007, 07:13 #2
No it's not wrong, it's just a difference of approach. Functional/integration testing is just hard proof that your app/site works the way it's supposed to, without having to load up the browser. Yes you still have to do browser-level testing, but if you already know for example that if you click a button a div named "results" will appear on the page, then you only have to concern yourself with how the "results" div looks when it comes time to browser test.
Mar 25, 2007, 07:50 #3
Mar 25, 2007, 19:53 #4
Apr 6, 2007, 17:44 #5
Also, consider this:
Without a test suite, you can easily use your browser to check if things are in order on Day 1 of your project development. Everything is pretty simple then.
Fast forward to day 30 when you've built your app up A LOT. There's more chance at this stage that if some simple component you created on day 1 fails, you might not catch it because of everything else that's going on.
Having a test suite that grows with your project makes sure you don't let this slip by later. It helps make sure everything works all the time--from the simplest equality check to a complex redirect.
Apr 8, 2007, 17:07 #6
- Join Date
- Jul 2004
- Gerodieville Central, UK
- 0 Post(s)
- 0 Thread(s)
Seeing as most people learn by example, here's a good scenario that demonstrates the requirement for testing.
Say you have a site like eBay, where people can "save searches". One of the options when you save a search is to let the system give you notifications when new items meet the search criteria, or items are removed that fit the criteria.
Testing this manually is a PITA at the best of times. When you manually test you need to make sure there is some initial content, create the saved search and then add something that meets the criteria, and then tell the system manually to look for new items for notification, and then check your email to see the item is emailed. This is a time sensitive operation and you may also want to make sure the notification system only runs on a daily basis and no more.
Here, it would be easier to write an automated test. You can use mocks in a similar way to the way you use fixtures (mocks are to behaviour what fixtures are to data)....
a simple test might look like....
class NotificationTest < Test::Unit::Testcase def test_emailer # Assume empty database, we generate our data here (I dislike fixtures personally) Time.is :year => 2005 do product = Product.create :title => "Playstation 2", :description => "This was vaugely successful", :price => 400.USD user = User.create :name => "Jase", :login => "miijase", :password => "<Insert random numbers and rude word here>" Time.is 1.week.since do user.saved_searches.create :min_price => 200.USD, :max_price => 500.USD, :title => "Comp00ters and stuff", :category => "Electronics" # Try and initate a email, because the search is just generated it should not send an email as previously created stuff does fit user.saved_searches.notifiy_changes_by_email assert_equal 0, sent_emails.size product = Product.create :title => "Playstation 3", :description => "This will be a flop, dont buy!", :price => 600.USD end Time.is 2.weeks.since do # No products added that fit criteria, so still no email user.saved_searches.notifiy_changes_by_email assert_equal 0, sent_emails.size end Time.is 3.weeks.since do product = Product.create :title => "Nintendo Wii", :description => "You know you want one, it saves going to the gym!", :price => 300.USD end Time.is 4.weeks.since do user.saved_searches.notifiy_changes_by_email assert_equal 1, sent_emails.size assert sent_emails.last.body =~ /Nintendo/ end end end def sent_emails ActionMailer::Base.deliveries end end
# For tests that require the 'mocking'/faking of the system clock class Time @@list =  cattr_reader :list end class << Time def now return list.last if list.last new end def flush list.clear end def is(time, &code) set time begin code.call if code ensure list.pop end end def resolved(time) return Time.utc(*time.values_at(:year, :month, :day, :hour, :minute, :second)) if time.is_a? Hash time end def set(time) list << resolved(time) end end
As you can see, the test case is not that big considering. Testing manually probably a lot more time when you've had to do do it more than 1 or 2 times.
If you design with testing in mind you will find you will write better code, because the process seems to implicitly make you make code more modular in a way that it's easy to substitute your code and data with fixed / mocked alternatives when testing.
Remember those days of science experiements at school where you are supposed to test one variable at a time and you use a "control" in your experiement to compare against. Well testing is much like this, you are testing a one given aspect of your system at a time (much like science experiments test the change in one given 'variable'), and your control is much like the fixed data and mocks (fixtures etc, which are fixed so you have something to compare against).
Obviously what I have put above is purely a unit test, and isn't a functional test, but it shows how you can avoid the chore of manual faffing in the browser. Proper Functional tests generally extend the idea further to make sure you get the right HTTP headers and content for given controllers. I tend to not rely on such high level test as much as you do need to do manual testing here to test for things like usablity anyway, so you can't totally escape manual testing, but you can certainly minimise it.