rspec: what, how and why

46
RSpec The What, How and Why?

Upload: ratan-sebastian

Post on 15-Jan-2015

2.939 views

Category:

Technology


1 download

DESCRIPTION

BDD with RSpec.

TRANSCRIPT

Page 1: RSpec: What, How and Why

RSpec

The What, How and Why?

Page 2: RSpec: What, How and Why

WHAT?

Page 3: RSpec: What, How and Why

What is Rspec?

A BDD Framework for Ruby

Page 4: RSpec: What, How and Why

What is Rspec?

A BDD Framework for RubyA testing framework that supports BDD

Page 5: RSpec: What, How and Why

/[T|B]DD/: Just Tests ... Right?

What is BDD

Page 6: RSpec: What, How and Why

/[T|B]DD/: Just Tests ... Right?

Page 7: RSpec: What, How and Why

100% Code Coverage is Good.Good Code + 100% Coverage is Better.

Feel Free make whatever you want out of the above picture

Page 8: RSpec: What, How and Why

Enter BDD

Dan North(ThoughtWorks)

Teaching TDD was hard

TDD needed Direction

Page 9: RSpec: What, How and Why

The Tools of BDD

Change Of Focus

Interaction-Based Testing

A Ubiquitous Language

Page 10: RSpec: What, How and Why

Change of Focus

Tests have a tendency of loosing focus of what we’re meant to be building. Too low level.

test_cases.each {|case| case.should add_business_value}

tests which describe domain specific functions => specs

Keeps focus. Gives direction.

Page 11: RSpec: What, How and Why

Interaction-Based Testing

As opposed to state-based testing

OOP design principles:Object exposes methods which are the only thing

that touch its internal state.

Any change in state requires a method call. SO:Just test that the call is made. Mock out all

neighboring objects.

A true UNIT test.

Page 12: RSpec: What, How and Why

Is that a Bad thing?<wait for the onslaught>

HOLD ON!

Doesn’t that mean that my tests are tightly coupled with my implementation?

Page 13: RSpec: What, How and Why

HOW?

Page 14: RSpec: What, How and Why

How Do I use Rspec (with rails)?

Page 15: RSpec: What, How and Why

How Do I use Rspec (with rails)?

gem install rspec rspec-rails

Page 16: RSpec: What, How and Why

How Do I use Rspec (with rails)?

gem install rspec rspec-rails

./script/generate rspec

Page 17: RSpec: What, How and Why

The Rspec FilesRAILS_ROOT

./specmodels

user_spec.rb

views

controllers

[spec|rcov].opts

helpers

spec_helper.rb

factories

./scriptautospec

spec

Page 18: RSpec: What, How and Why

A Word about Factories

A easy-to-maintain replacement for fixtures(Finally some code!)

More about creating your own strategies at theend of this presentation

Page 19: RSpec: What, How and Why

spec_helper.rb

Loaded at the beginning of ever spec file

Put methods that can be used by all specs here.

Page 20: RSpec: What, How and Why

Examples

The equivalent of a unit test in RSpec

Page 21: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 22: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

EXAMPLE

Page 23: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 24: RSpec: What, How and Why

The Syntax

context “Unit#something” dobefore(:each) do

@unit= Unit.new(params)endspecify “should return something” do

@unit.something.should == ‘something’

endend

Page 25: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 26: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 27: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 28: RSpec: What, How and Why

The Syntax

describe “Unit#something” dobefore(:each) do@unit= Unit.new(params)endit “should return something” [email protected] ==

‘something’end

end

Page 29: RSpec: What, How and Why

The mocking/stubbing framework object.stub!(:foo => ‘bar’, :one => 1) object.stub!(:foo).and_return(‘bar’) mock_object= mock/mock_model(Klass,

espectations= {:foo => ‘bar’}) mock_object.foo #=> ‘bar’

Tool for Interaction Testing: mock_object.should_receive(:message).exactly(n

).times.with(params).and_return(val) Each of the methods in that chain take many

different options. Ref: Links Raises error if the message isn’t received

& with the parameters specified & with the correct freq.

Page 30: RSpec: What, How and Why

Mocks Aren’t StubsStubs provide canned answers to calls made during

the test, usually not responding at all to anything outside what's programmed in for the test. Stubs

may also record information about calls, such as an email gateway stub that remembers the messages

it 'sent', or maybe only how many messages it 'sent'.

Mocks are […] objects pre-programmed with expectations which form a specification of the calls

they are expected to receive.

-Martin Fowler

Page 31: RSpec: What, How and Why

Functional Tests(Controller Examples)

Isolate controllers from the models(mocks)

Big difference from Rails Functional Testing:

Also isolate it from the views.

Integration is possible with integrate_views

Page 32: RSpec: What, How and Why

Controller specific Expectations

Response Expectations should be_success should render_template

should be_redirect should redirect_to

response.[assigns|flash|sessions]

Routing Expectations route_for(:controller => …, :action => …).should == /…/…/

params_from(:get,"/hello/world").should ==

{:controller=>"hello” ,:action => "world"}

Page 33: RSpec: What, How and Why

View Examples

Again<Yawn> Isolation is key.

# examplearticle = mock_model(Article) article.should_receive(:author).and_return("J”)article.should_receive(:text).and_return("this is the text of the article")

assigns[:article] = article assigns[:articles] = [article]# flash and params are also available

# template <% for article in @articles -%> <!-- etc -->

Page 34: RSpec: What, How and Why

View Specific Expectations

response.should have_tag#examplesresponse.should have_tag('div#interesting_div‘, contents)

# Contents can be Regexp or String

response.should have_tag("input[type=?][checked=?]", 'checkbox', 'checked')

response.should have_tag('ul') do with_tag('li', 'list item 1') with_tag('li', 'list item 2') with_tag('li', 'list item 3')

end

Page 35: RSpec: What, How and Why

Exercise

Page 36: RSpec: What, How and Why

My Spec

Page 37: RSpec: What, How and Why

WHY?

Page 38: RSpec: What, How and Why

The RSpec Philosophy

Clarity over Cleverness

Completely isolate the unit under test

i.e. Mock Everything

Page 39: RSpec: What, How and Why

Pros and Cons

Easily understandable tests

True unit tests Interoperability with

other testing frameworks

More descriptive code == more lines of code

Not very DRY Tight coupling of test

and implementation.

Page 40: RSpec: What, How and Why

Interaction Testing is a Guideline

Not a rule

Depends on what you are testing.

Remember: Usually leads to better OO Design not always

better tests.

Page 41: RSpec: What, How and Why

Good News

Rspec doesn’t force IBT on you

Write tests that work best for you.

Page 42: RSpec: What, How and Why

If we’re doing SBT with Rspec.Why not stick to Test::Unit?

OPTIONS

RSpec is versatile. Can do everything that Test::Unit does and then some.

Undoubtedly better for adding new functionality

Page 43: RSpec: What, How and Why

Why RSpec?

RSpec is not just about RSpec. It's about BDD. It's about encouraging conversation about testing and looking at it in different ways. It's about illuminating the design, specification, collaboration and documentation aspects of tests, and thinking of them as executable examples of behaviour. You can do this all without RSpec, but RSpec aims to help with innovations like:

strings as example names pending examples nested groups for flexible organization should[_not] + matchers (inspired by hamcrest - a java library) one matcher supports both positive and negative expectations improved failure messages flexible/readable/customizable output formats built-in mocking framework plain text scenarios (now in Cucumber)

- David Chelimsky(RSpec lead developer)

Page 44: RSpec: What, How and Why

More Quotes

The problem I have with TDD is that its mindset takes us in a different direction... a wrong direction. – Dave Astels(RSpec Creator)

Page 45: RSpec: What, How and Why

Thank You!

Questions.

Pleeeeease!!