Relational Databases and Web Integration Dr. Carl Pulley
[email protected] Monday, 17 August 2009
Test Driven Development Test first, code later no application code should be written unless a test exists to show a deficiency wrt our requirements specification So, we start developing our application with a blank or empty Rails project!
Monday, 17 August 2009
Revision: test test rake
test:units
test/* test/unit/*_test.rb
test:functional
test/functional/*_controller_test.rb
Test fixtures
test/fixtures/*.yml
Monday, 17 August 2009
Example Tag
Blog
title 1 * * value created_at entry blogs_tags
Feedback
blog_id
created_at * comment 1
author_id
1
Author name email
Monday, 17 August 2009
author_id
Place tests in:
Model Existence
test/unit/tag_test.rb
test "Tag model exists" do assert_nothing_thrown do begin Tag rescue throw :fail end end assert_equal(Tag.superclass, ActiveRecord::Base) end
test “Tag model has expected attributes” do columns = Tag.columns.map { |t| [t.name, t.type.to_s] } [[‘id’, ‘integer’], [‘value’, ‘string’]].each do |nm, tg| assert(columns.member?([nm, tg])) end end Monday, 17 August 2009
Tag Model Code
script/generate model tag value:string .. class Tag < ActiveRecord::Base end
Monday, 17 August 2009
Place tests in:
Model Existence
test/unit/blog_test.rb
test "Blog model exists" do assert_nothing_thrown do begin Blog rescue throw :fail end end assert_equal(Blog.superclass, ActiveRecord::Base) end
test “Blog model has expected attributes” do columns = Blog.columns.map { |b| [b.name, b.type.to_s] } [[‘id’, ‘integer’], [‘title’, ‘string’], [‘created_at’, ‘datetime’], [‘entry’, ‘text’], [‘author_id’, ‘integer’]].each do |nm, bl| assert(columns.member?([nm, bl])) end end Monday, 17 August 2009
..and so on for all our other models.
Model Relationships test "blogs attribute" do assert(Tag.count > 0) Tag.find(:all).each do |tag| assert_respond_to(tag, 'blogs') assert_equal(tag.blogs.class, Array) end end Place test in: test/unit/tag_test.rb
class Tag < ActiveRecord::Base has_and_belongs_to_many :blogs end
Monday, 17 August 2009
Relationship Arities Tackle these issues by trying to save model object instances that break the arity in question for example, if at least 2 tags should be associated with each blog try and create blogs with no tags or 1 tag
Monday, 17 August 2009
Tag Validations test "empty/blank Tag validation" do [nil, '', ' ', ' ', "\t", "\t \t\t"].each do |val| tag = Tag.new(:value => val) assert(!tag.valid?) assert(tag.errors.invalid?(:value)) end end test "ensure Tag uniqueness" do Tag.find(:all).each do |tg| tag = Tag.new(:value => tg) assert(!tag.valid?) assert(tag.errors.invalid?(:value)) end end Place tests in: test/unit/tag_test.rb Monday, 17 August 2009
Beware, this last test could pass if the Tag table were empty!! Maybe we should also assert(Tag.count > 0)?
Tag Validations test "valid Tag validation" do # NOTE: following are NOT present in our Tag fixtures # - hence why they're valid! Poor test? ['sql', 'a', 'devilish'].each do |tg| tag = Tag.new(:value => tg) assert(tag.valid?, tag.errors.ful_messages) assert_equal(tag.value, tg) end end test "invalid Tag validation" do ['Rails', 'SQL', '0', '999', 'l3v3l', 'leve1', '1evel', 'level!', '!level', 'le vel'].each do |val| tag = Tag.new(:value => val) assert(!tag.valid?) assert(tag.errors.invalid?(:value)) end Place tests in: test/unit/tag_test.rb end Monday, 17 August 2009
This is potentially a poor test since alterations to our Tag fixtures could make the test invalid. A better test might be to generate random tag values and then test that they’re not in our tags fixture data structure.
Tag Model Code class Tag < ActiveRecord::Base has_and_belongs_to_many :blogs validates_presence_of :value validates_uniqueness_of :value validates_format_of :value, :with => /^[a-z]+$/ end
Monday, 17 August 2009
Foreign Keys Such tests can be written, but tend to be highly database oriented not good if database may change! If model uses validations, can catch null constraints on attributes If table uses foreign-key constraints and you need to test, you’ll be mucking around with SQL statements! Place tests in: test/unit/blog_test.rb Monday, 17 August 2009