web tech: lecture 5

26
SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY Lecture 5 RSpec testing,

Upload: ardak-shalkarbayuli

Post on 15-Jul-2015

45 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Lecture 5RSpec testing,

Page 2: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Automated testing

Testing is a checking if your code is right

Every developer actually checks his project for

outputting correct values for different values.

Since testing is done many times and many

operations are repeated over a time, it is needed to

be automated

Page 3: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

TDD - Test Driven

Development

Development where you first write tests and then

write code for them.

It is good for following cases:

Developers better understand what to do

It can be used as documentation

Page 4: Web tech: lecture 5

RSpec on Rails(Engineering Software as a Service §8.2)

Armando Fox

© 2012 Armando Fox & David Patterson

Licensed under Creative Commons Attribution-

NonCommercial-ShareAlike 3.0 Unported

License

Page 5: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

RSpec

RSpec is a library to do automatic testing

Page 6: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

RSpec usage

It’s tests are inside spec folder

To use in project: write in Gemfilegem 'rspec-rails'

rails generate rspec:install

run rake db:migrate

then run rake db:test:prepare

Last command prepares test database for testing

then run rspec

Page 7: Web tech: lecture 5

RSpec, a Domain-Specific

Language for testing

• RSpec tests (specs) inhabit spec directory

rails generate rspec:install creates

structure

• Unit tests (model, helpers)

• Functional tests (controllers)

• Integration tests (views)?

app/models/*.rb spec/models/*_spec.rb

app/controllers/

*_controller.rb

spec/controllers/

*_controller_spec.rb

app/views/*/*.html.haml (use Cucumber!)

Page 8: Web tech: lecture 5

The TDD Cycle:

Red–Green–Refactor(Engineering Software as a Service §8.3)

Armando Fox

© 2013 Armando Fox & David Patterson, all rights reserved

Page 9: Web tech: lecture 5

Test-First development

• Think about one thing the code should do

• Capture that thought in a test, which fails

• Write the simplest possible code that lets the

test pass

• Refactor: DRY out commonality w/other tests

• Continue with next thing code should do

Red – Green – Refactor

Aim for “always have working code”

Page 10: Web tech: lecture 5

How to test something “in

isolation” if it has dependencies

that would affect test?

Page 11: Web tech: lecture 5

The Code You Wish You Had

What should the controller method do that

receives the search form?

1.it should call a method that will search

TMDb for specified movie

2.if match found: it should select (new)

“Search Results” view to display match

3.If no match found: it should redirect to RP

home page with message

Page 12: Web tech: lecture 5

TDD for the Controller action:

Setup

• Add a route to config/routes.rb# Route that posts 'Search TMDb' form

post '/movies/search_tmdb'

– Convention over configuration will map this to MoviesController#search_tmdb

• Create an empty view:touch app/views/movies/search_tmdb.html.haml

• Replace fake “hardwired” method in movies_controller.rb with empty method:def search_tmdb

end

Page 13: Web tech: lecture 5

What model method?

• Calling TMDb is responsibility of the model... but

no model method exists to do this yet!

• No problem...we’ll use a seam to test the code we

wish we had (“CWWWH”), Movie.find_in_tmdb

• Game plan:

– Simulate POSTing search form to controller action.

– Check that controller action tries to call Movie.find_in_tmdb

with data from submitted form.

– The test will fail (red), because the (empty) controller

method doesn’t call find_in_tmdb.

– Fix controller action to make green.

http://pastebin.com/zKnw

phQZ

Page 14: Web tech: lecture 5

Optional!

Test techniques we know

obj.should_receive(a).with(b)

Page 15: Web tech: lecture 5

Should & Should-not

• Matcher applies test to receiver of should

count.should == 5` Syntactic sugar for

count.should.==(5)

5.should(be.<(7)) be creates a lambda that tests the

predicate expression

5.should be < 7 Syntactic sugar allowed

5.should be_odd Use method_missing to call odd?

on 5

result.should include(elt) calls #include?, which usually gets

handled by Enumerable

republican.should

cooperate_with(democrat)

calls programmer’s custom

matcher #cooperate_with (and

probably fails)

result.should render_template('search_tmdb')

Page 16: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

spec/model/person_spec.rb

This file tests model Person, the line starting with it

is one test, text next to it is name of test, inside

functionrequire ‘spec_helper’

describe Person do

it ‘is invalid without name’ do

Person.create.should_not be_valid

end

end

Page 17: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

should

should or should_not are next to object you want to

test

after should or should_not you can write:

== equals

be_valid if model is valid

have_text

redirect_tohttp://rspec.rubyforge.org/rspec-rails/1.1.12/classes/Spec/Rails/Matchers.html

Page 18: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Associationsbasic

Page 19: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Problem

We have two tables: Students and Group

Each group contains many students, so in students

table it has foreign key to group table.

So table students: name, surname, group_id

and table group: title

Page 20: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Dumb way #1:

Creating model and migrating

rails generate model Group title:string

rails generate model Student name:string

surname:string group_id:integer

rake db:migrate

Page 21: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Dumb way #1:

show all students of group #1

gr = Group.find(1)

studs = Student.all.where(group_id: gr.id)

This code is not beautiful, because it would be

better to find all students of group from object

Page 22: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

has_many and belongs

add line has_many :students to Group model

and line belongs_to :group to Student model

Note: has_many is in plural form and belongs_to in

singular form

Now you can use:

gr = Group.find(1)

gr.students

Which will show all students of group with id 1

Page 23: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

How it works

When you add belongs_to field to Student model, it

understands that foreign_key should be called

group_id, and works with it

Page 24: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Simplifying

Instead of rails generate model Student name:string group_id:integer

it’s better to userails generate model Student name:string group:references

Two commands create same database tables, but

second command automatically adds belongs_to

to Student table

Page 25: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

Working through associations

grr = Group.find(1)

grr.students.create(:name=>”John”)

grr.students<<Student.create(:name=>”John”)

grr.students[2].name

Page 26: Web tech: lecture 5

SULEYMAN DEMIREL UNIVERSITY : ENGINEERING FACULTY : © ARDAK SHALKARBAYULY

has_one with different name

has_one :capital, :class_name=>”City”, foreign_key=>”capital_id”