Upload
yehuda-katz
View
2.978
Download
0
Tags:
Embed Size (px)
Citation preview
Testing Merb
The Right Way
Why Test?
TDD
TDD and Regressions
TDD and Regressions
I am not saying TDD is bad, but this talk doesn’t focus on mock-driven TDD.
Resiliant Against Refactoring
class Awesome def hello puts "~ Hello ~" endend
describe Awesome do it "prints hello" do awesome = Awesome.new awesome.should_receive(:puts) awesome.hello endend
class Awesome def hello awesome_print "~ Hello ~" end def awesome_print(str) print "#{str}\n" endend
describe Awesome do it "prints hello" do awesome = Awesome.new awesome.should_receive(:puts) awesome.hello endend
class Awesome def hello awesome_print "~ Hello ~" end def awesome_print(str) print "#{str}\n" endend
describe Awesome do it "prints hello" do awesome = Awesome.new awesome.should_receive(:puts) awesome.hello endend
FAIL
class Awesome def hello awesome_print "~ Hello ~" end def awesome_print(str) print "#{str}\n" endend
describe Awesome do it "prints hello" do capture { Awesome.new.hello }. should =~ /Hello/ endend
How to Test Three Rules
Broken Interface means failing tests
Working Interface means passing tests
Write tests about what you care about
http://example.com/foo
Controller
Filters
Views
Helpers
What Happens in Your App
Your App
http://example.com/foo
What You Care About
http://example.com/foo
Controller
4 Filters
Views
Helpers
H Partials
Refactoring
Iteration 1
class Foo < Application def awesome awesome_string end def awesome_string "Awesome" endend
Merb::Router.prepare do match("/foo/awesome"). to(:controller => Foo, :action => :awesome). name(:awesome)end
dispatch_to(Foo, :awesome) do |cont| cont.should_receive(:awesome_string)end
dispatch_to(Foo, :awesome) do |cont| cont.should_receive(:awesome_string)end
Iteration 2
class Bar < Application def coolness render end end
Merb::Router.prepare do match("/foo/awesome"). to(:controller => Bar, :action => :coolness). name(:awesome)end
dispatch_to(Foo, :awesome) do |cont| cont.should_receive(:awesome_string)end
dispatch_to(Foo, :awesome) do |cont| cont.should_receive(:awesome_string)end FAIL
request("/foo/awesome").body. should =~ /Awesome/
request(url(:awesome)).body. should =~ /Awesome/
Broken Interface means failing tests
Working Interface means passing tests
Write tests about what you care about
“It’s Too Hard”
Let’s Make it Easy
request(url(:speakers))
request(resource(@speaker))
request("/foo/speakers")
request(url(:speakers))
request(resource(@speaker))
request("/foo/speakers")
one method
Sessions are automatically sticky in a spec
it "should let you in" do request("/login", :method => :post, :params => {:username => "user", :password => "pass"}) request("/home").should be_successfulend
it "should let you in" do request("/login", :method => :post, :params => {:username => "user", :password => "pass"}) request("/home").should be_successfulend
login
it "should let you in" do request("/login", :method => :post, :params => {:username => "user", :password => "pass"}) request("/home").should be_successfulend
you’re logged in
describe "/login", :given => "successful login" do it "should let you in" do request("/home").should be_successful endend
simpler
describe "/login", :given => "successful login" do it "should let you in" do request("/home").should be_successful endend
simpler
Request
Rack
body headersstatus
request() helper
Rack
body headersstatus
request("/foo").body.should == "hello"
request("/foo").should have_xpath("//h1")
request("/foo").should( have_selector("h1:contains(text)"))
request("/foo").body.should == "hello"
request("/foo").should have_xpath("//h1")
request("/foo").should( have_selector("h1:contains(text)"))
1.0 final
request("/foo").should be_client_error
request("/foo").should( have_content_type(:json))
Thank you.