Upload
jason-noble
View
2.796
Download
4
Embed Size (px)
DESCRIPTION
Citation preview
Validation and Unit Testing
Validations
• Title should not be empty• Description should not be empty• Price should be valid
• Models hook the code up to what’s in the db• Everything that is put into / read from the db
goes through the model
Verify text fields have content
• app/models/product.rb• validates :title, :description, :image_url, :prese
nse => true
• rails c– p = Product.new– p.valid? #=> false– p.errors
Validate price > $0.00
• app/models/product.rb• validates :price, :numericality =>
{:greater_than_or_equal_to => 0.01}
• p = Product.new({:title => "blah", :description => "blah", :image_url => "blah"})
• p.valid?• p.errors
Validate uniqueness of title
• app/model/product.rb• validates :title, :uniqueness => true
• p = = Product.new({:title => "blah", :description => "blah", :image_url => "blah", :price => "33"})
• p.save• q = Product.new({:title => "blah", :description =>
"blah", :image_url => "blah", :price => "33"})• q.valid # => false• q.errors
Validates :image_url
• validates :image_url, :format => { :with => %r{\.(gif|jpg|png)$}i, :message => ‘must be a URL for GIF, JPG or PNG image’}
• q = Product.new({:title => "blah", :description => "blah", :image_url => "blah", :price => "33"})
• q.valid?• q.errors
What we’ve accomplished
• Product model verifies:– field’s title, description and image URL are not
empty– Price is a valid number > $0.01– Title is unique– Image URL looks reasonable
• http://localhost:3000/products
rake test
• 7 tests, 9 assertions, 2 failures, 0 errors, 0 skips
• Why are our tests failing?
• We added requirements for “valid” products
Update functional tests
• test/functional/products_controller_test.rb
@update = { :title => 'Lorem Ipsum', :description => 'Wibbles are fun', :image_url => 'lorem.jpg', :price => 19.95 }
Model Unit Tests
• test/unit/product_test.rb
test "product attributes must not be empty" do product = Product.new assert product.invalid? assert product.errors[:title].any? assert product.errors[:description].any? assert product.errors[:price].any? assert product.errors[:image_url].any? end
rake test:units
• Runs only unit tests (not the full test suite)
• All unit tests pass!
Test more validations test "product price must be positive" do product = Product.new(:title => "My Book", :description => 'yyy', :image_url => 'zzz.jpg') product.price = -1 assert product.invalid? assert_equal "must be greater than or equal to 0.01", product.errors[:price].join(': ') product.price = 0 assert product.invalid? assert_equal "must be greater than or equal to 0.01", product.errors[:price].join(': ')
product.price = 1 assert product.valid? end
Test your assumptions
• These tests pass now
• Do your tests fail if you remove the validation(s)?
Good/Bad Image_url’s test "image url" do ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg http://a.b.c/x/y/z/fred.gif } bad = %w{ fred.doc fred.gif/more fred.gif.more } ok.each do |name| assert new_product(name).valid?, "#{name} shouldn't be invalid" end
bad.each do |name| assert new_product(name).invalid?, "#{name} shouldn't be valid" end end
Test Fixtures
• Fills our test database with known sample data
• Usually stored in CSV or YAML format (YAML is more common)
• Fixture name must match the table you’re testing
• YAML requires spaces not tabs, tabs produce a syntax error
Products Fixture
• test/fixtures/products.yml
ruby: title: Programming Ruby 1.9 description: Book on programming Ruby. Commonly called the
"pick-axe" book. price: 49.50 image_url: ruby.png
Using Fixture Data• test/unit/product_test.rb
test "product is not valid without a unique title" do product = Product.new(:title => products(:ruby).title, :description => "yyy", :price => 1, :image_url => "fred.gif") assert !product.save assert_equal "has already been taken", product.errors[:title].join(';
') end
Commit your work
• git status• git commit –a –m ‘Validation!’
Homework
• Add a validation that verifies the title is at least 10 characters long– Checkout the :length argument to validate
• Add a validation that verifies the description is no more than 50 characters long
• Change the error message on one or more of your validations
• Pretend we operate a dollar store. Write a validation that makes sure the price is between $0.01 and $1.00.
Upgrade to Rails 3.0.3
• vi Gemfile• bundle install• rake test