1. Ruby On Rails par Rspec
Ruby On Rails par Rspec
Cyril Mougel
30 D´cembre 2008
e
2. Ruby On Rails par Rspec
Rspec, BDD ?
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
3. Ruby On Rails par Rspec
Rspec, BDD ?
Behaviour Driven Development
M´thode Agile
e
Extreme programming
TDD (Test Driven Development)
l’empire du ’should’
4. Ruby On Rails par Rspec
Rails est agile avant tout
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
5. Ruby On Rails par Rspec
Rails est agile avant tout
Test : :Unit de base dans Rails
Dossier test cr´´ ` chaque cr´ation de projet Rails
ee a e
Stats de nombre du LOC et LOC de test
Possibilit´ de tester chaque couche de Rails
e
6. Ruby On Rails par Rspec
Rails est agile avant tout
Mais pourquoi Rspec alors ?
Rspec == BDD Framework
Documentation g´n´r´e plus claire que les Test : :Unit
e ee
R´utilisation plus simple du comportement
e
Ajout des Stories (Cucumber)
7. Ruby On Rails par Rspec
Rails est agile avant tout
Et ca s’installe comment ?
gem install rspec && gem install rspec-rails
gem install rspec &&
./script/install git ://github.com/dchelimsky/rspec-rails.git
gem install rspec &&
git-submodule add vendor/plugins/rspec-rails
git ://github.com/dchelimsky/rspec-rails.git
8. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
9. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Des classes de Mapping ` la Base de donn´e
a e
1 c l a s s U s e r < A c t i v e R e c o r d : : Base
2 has many : p r o d u c t s
3
4 v a l i d a t e s p r e s e n c e o f : name
5 v a l i d a t e s u n i q u e n e s s o f : name
6 v a l i d a t e s f o r m a t o f : email ,
: w i t h => / A ( [ ˆ @ s ]+)@( ( ? : [ − a−z0 −9]+.)+[ a−z ] { 2 , } ) Z/ i ,
7
8 : on => : c r e a t e
9 end
10
11 c l a s s P r o d u c t < A c t i v e R e c o r d : : Base
12 belongs to : user
13 end
10. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Doit cr´er les accesseurs sur les colonnes
e
1 d e s c r i b e U s e r do
2
3 b e f o r e ( : e a c h ) do
4 @user = User . f i r s t
5 end
6
7 it ’ s h o u l d a c c e s s t o name ’ do
8 @ u s e r . name . s h o u l d n o t b e n i l
9 end
10
11 end
11. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Doit valider le model
1 d e s c r i b e U s e r do
2 d e s c r i b e ’ c r e a t e ’ do
3 def u s e r v a l i d ( options )
U s e r . new ( { : name = ’ C y r i l Mougel ’ ,
4 >
: e m a i l = ’ c y r i l . m o u g e l @ g m a i l . com ’ } . merge ( o p t i o n s ) )
5 >
6 end
7
8 it ’ s h o u l d u s e r v a l i d ’ do
9 u s e r v a l i d . should be valid
10 end
11
12 it ’ s h o u l d p r e s e n c e o f name ’ do
13 u s e r v a l i d ( : name = n i l ) . s h o u l d n o t b e v a l i d
>
14 end
15
16 it ’ s h o u l d u n i q name ’ do
17 u s e r v a l i d . save
18 user valid . should not be valid
19 end
20
21 i t ’ s h o u l d n o t v a l i d w i t h bad e m a i l ’ do
22 u s e r v a l i d ( : email = ’ cool ’ ) . should not be valid
>
23 end
24 end
25 end
12. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Doit chercher des donn´es
e
1 d e s c r i b e U s e r do
2
3 i t ’ s h o u l d f i n d by name ’ do
4 U s e r . f i n d b y n a m e ( ’ C y r i l Mougel ’ ) . s h o u l d == u s e r s ( : s h i n g a r a )
5 end
6
7 i t ’ s h o u l d f i n d by e m a i l ’ do
8 U s e r . f i n d b y e m a i l ( ’ c y r i l . m o u g e l @ g m a i l . com ’ ) . s h o u l d == u s e r s ( : s h i n g a r a )
9 end
10
11 it ’ s h o u l d f i n d by name and e m a i l ’ do
12 U s e r . f i n d b y n a m e a n d e m a i l ( ’ C y r i l Mougel ’ ,
13 ’ c y r i l . m o u g e l @ g m a i l . com ’ ) . s h o u l d == u s e r s ( : s h i n g a r a )
14 end
15
16 it ’ s h o u l d f i n d a l l ’ do
17 U s e r . a l l . s h o u l d == [ u s e r s ( : s h i n g a r a ) , u s e r s ( : u n d e r f l o w ) ]
18 end
19 end
13. Ruby On Rails par Rspec
La couche mod`le de Rails
e
Doit avoir des associations
1 d e s c r i b e U s e r do
2 b e f o r e : e a c h do
3 @user = u s e r s ( : s h i n g a r a )
4 end
5
6 it ’ s h o u l d h a v e 2 p r o d u c t s ’ do
7 @user . s h o u l d have ( 2 ) . p r o d u c t s
8 # @ u s e r . p r o d u c t s . s i z e == 2
9 end
10
11 it’ s h o u l d h a v e book p r o d u c t s ’ do
12 @ u s e r . p r o d u c t s [ 0 ] . s h o u l d == p r o d u c t s [ : book ]
13 end
14 end
15
16 d e s c r i b e P r o d u c t do
17 b e f o r e : e a c h do
18 @ p r o d u c t = p r o d u c t s ( : book )
19 end
20
21 i t ’ s h o u l d h a v e u s e r s h i n g a r a ’ do
22 @ p r o d u c t . u s e r . s h o u l d == u s e r s ( : s h i n g a r a )
23 end
24 end
14. Ruby On Rails par Rspec
La couche controller de Rails
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
15. Ruby On Rails par Rspec
La couche controller de Rails
Un controlleur Rails
1 class UsersController < ApplicationController
2
3 def index
4 @users = User . f i n d ( : a l l )
r e s p o n d t o do | f o r m a t |
5
6 format . html # i n d e x . html . erb
f o r m a t . xml { r e n d e r : xml = @ u s e r s }
7 >
8 end
9 end
10
11 d e f show
12 @ u s e r = U s e r . f i n d ( params [ : i d ] )
r e s p o n d t o do | f o r m a t |
13
14 f o r m a t . h t m l # show . h t m l . e r b
f o r m a t . xml { r e n d e r : xml = @ u s e r }
15 >
16 end
17 end
18
19 def c r e a t e
20 @ u s e r = U s e r . new ( params [ : u s e r ] )
r e s p o n d t o do | f o r m a t |
21
22 i f @user . save
23 f l a s h [ : n o t i c e ] = ’ U s e r was s u c c e s s f u l l y c r e a t e d . ’
format . html { r e d i r e c t t o ( @user ) }
24
25 else
f o r m a t . h t m l { r e n d e r : a c t i o n = ”new” }
26 >
27 end
28 end
29 end
30 end
16. Ruby On Rails par Rspec
La couche controller de Rails
Doit permettre de voir la liste des utilisateurs
1 d e s c r i b e U s e r s C o n t r o l l e r do
2
3 d e s c r i b e ” r e s p o n d i n g t o GET i n d e x ” do
4 i t ” s h o u l d e x p o s e a l l u s e r s a s @ u s e r s ” do
5 get : index
6 a s s i g n s [ : u s e r s ] . s h o u l d == [ u s e r s ( : s h i n g a r a ) ]
7 end
8
9 d e s c r i b e ” w i t h mime t y p e o f xml ” do
10 i t ” s h o u l d r e n d e r a l l u s e r s a s xml ” do
11 r e q u e s t . en v [ ”HTTP ACCEPT” ] = ” a p p l i c a t i o n / xml ”
12 get : index
13 r e s p o n s e . body . s h o u l d == u s e r s ( : s h i n g a r a ) . t o x m l
14 end
15 end
16 end
17 end
17. Ruby On Rails par Rspec
La couche controller de Rails
Doit permettre de voir un utilisateur particulier
1 d e s c r i b e U s e r s C o n t r o l l e r do
2 d e s c r i b e ” r e s p o n d i n g t o GET show ” do
3
4 i t ” s h o u l d e x p o s e t h e r e q u e s t e d u s e r a s @ u s e r ” do
5 g e t : show , : i d = u s e r s ( : s h i n g a r a ) . i d
>
6 a s s i g n s [ : u s e r ] . s h o u l d == u s e r s ( : s h i n g a r a )
7 end
8
9 d e s c r i b e ” w i t h mime t y p e o f xml ” do
10
11 i t ” s h o u l d r e n d e r t h e r e q u e s t e d u s e r a s xml ” do
12 r e q u e s t . en v [ ”HTTP ACCEPT” ] = ” a p p l i c a t i o n / xml ”
13 g e t : show , : i d = u s e r s ( : s h i n g a r a ) . i d
>
14 r e s p o n s e . body . s h o u l d == u s e r s ( : s h i n g a r a ) . t o x m l
15 end
16 end
17 end
18 end
18. Ruby On Rails par Rspec
La couche controller de Rails
Doit cr´er un utilisateur
e
1 d e s c r i b e U s e r s C o n t r o l l e r do
2 d e s c r i b e ” r e s p o n d i n g t o POST c r e a t e ” do
3
4 d e s c r i b e ” w i t h v a l i d params ” do
5
6 i t ” s h o u l d c r e a t e u s e r ” do
7 a s s e r t d i f f e r e n c e ’ U s e r . c o u n t ’ do
p o s t : c r e a t e , : u s e r = { : name = ’ Jean−f r a n c o i s ’ ,
8 > >
: email = ’ j f @ r u b y f r a n c e . org ’}
9 >
10 response . should r e d i r e c t t o (
11 u s e r u r l ( U s e r . f i n d b y n a m e ( ’ Jean−f r a n c o i s ’ ) ) )
12 end
13 end
14
15 end
16
17 d e s c r i b e ” w i t h i n v a l i d params ” do
18
19 i t ” s h o u l d n o t c r e a t e u s e r ” do
20 a s s e r t n o d i f f e r e n c e ’ U s e r . c o u n t ’ do
p o s t : c r e a t e , : u s e r = { : name = ’ Jean−f r a n c o i s ’ ,
21 > >
: email = ’ j f @ r u b y f r a n c e ’}
22 >
23 r e s p o n s e . s h o u l d r e n d e r t e m p l a t e ( ’ new ’ )
24 end
25 end
26 end
27
28 end
29 end
19. Ruby On Rails par Rspec
Les routes Rails
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
20. Ruby On Rails par Rspec
Les routes Rails
Une simple ligne de route
A c t i o n C o n t r o l l e r : : R o u t i n g : : R o u t e s . draw do | map |
1
2 map . r e s o u r c e s : u s e r s
3 end
21. Ruby On Rails par Rspec
Les routes Rails
Doit cr´er plein de routes
e
1 d e s c r i b e U s e r s C o n t r o l l e r do
2 d e s c r i b e ” r o u t e g e n e r a t i o n ” do
3 i t ” s h o u l d map #i n d e x ” do
4 route for (: controller = ” users ” , >
5 : a c t i o n = ” i n d e x ” ) . s h o u l d == ” / u s e r s ”
>
6 end
7
8 i t ” s h o u l d map #new” do
9 route for (: controller = ” users ” ,
>
10 : a c t i o n = ”new” ) . s h o u l d == ” / u s e r s /new”
>
11 end
12
13 i t ” s h o u l d map #show ” do
14 route for (: controller = ” users ” ,
>
15 : a c t i o n = ” show ” , : i d = 1 ) . s h o u l d == ” / u s e r s /1 ”
> >
16 end
17
18 i t ” s h o u l d map #e d i t ” do
19 route for (: controller = ” users ” ,
>
20 : a c t i o n = ” e d i t ” , : i d = 1 ) . s h o u l d == ” / u s e r s /1/ e d i t ”
> >
21 end
22
23 i t ” s h o u l d map #u p d a t e ” do
24 route for (: controller = ” users ” ,
>
25 : a c t i o n = ” u p d a t e ” , : i d = 1 ) . s h o u l d == ” / u s e r s /1 ”
> >
26 end
27
28 i t ” s h o u l d map #d e s t r o y ” do
29 route for (: controller = ” users ” ,
>
30 : a c t i o n = ” d e s t r o y ” , : i d = 1 ) . s h o u l d == ” / u s e r s /1 ”
> >
22. Ruby On Rails par Rspec
La couche Vue de Rails
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
23. Ruby On Rails par Rspec
La couche Vue de Rails
Une vue d’index
1 <h1>L i s t i n g u s e r s </ h1>
2
3 <t a b l e >
4 <t r >
5 <th>Name</ th>
6 <th>Email</ th>
7 </ t r >
8
9 <% f o r u s e r i n @ u s e r s % >
10 <t r >
11 <td> <%=h u s e r . name % </ td>
>
12 <td> <%=h u s e r . e m a i l % </ td>
>
13 <td> <%= l i n k t o ’ Show ’ , u s e r % </ td>
>
14 <td> <%= l i n k t o ’ E d i t ’ , e d i t u s e r p a t h ( u s e r ) % </ td>
>
15 <td> <%= l i n k t o ’ D e s t r o y ’ , u s e r , : c o n f i r m = ’ Are you s u r e ? ’ ,
>
16 : method = : d e l e t e % </ td>
> >
17 </ t r >
18 <% end % >
19 </ t a b l e >
24. Ruby On Rails par Rspec
La couche Vue de Rails
Doit permettre de voir les utilisateurs
1 d e s c r i b e ” / u s e r s / i n d e x . h t m l . e r b ” do
2 include UsersHelper
3
4 b e f o r e ( : e a c h ) do
5 a s s i g n s [ : u s e r s ] = User . a l l
6 #T h e r e a r e 2 u s e r s i n f i x t u r e s
7 end
8
9 i t ” s h o u l d r e n d e r l i s t o f u s e r s ” do
10 r e n d e r ”/ u s e r s / i n d e x . html . erb ”
11 r e s p o n s e . s h o u l d h a v e t a g ( ” t r >t d ” , U s e r . f i r s t . name )
12 r e s p o n s e . s h o u l d h a v e t a g ( ” t r >t d ” , U s e r . f i r s t . e m a i l )
13 end
14 end
25. Ruby On Rails par Rspec
les mocks ?
Rspec, BDD ?
1
Rails est agile avant tout
2
La couche mod`le de Rails
e
3
La couche controller de Rails
4
Les routes Rails
5
La couche Vue de Rails
6
les mocks ?
7
26. Ruby On Rails par Rspec
les mocks ?
S’il te plait, dessine moi un mock ?
mock model(User)
Comportement d’un objet ActiveRecord sans access a la BDD
Possibilite de retourner ce que l’on veux
Evite de cr´er une fixture qui gere ce cas la
e
27. Ruby On Rails par Rspec
les mocks ?
Doit s’utiliser dans les controllers
1 d e s c r i b e U s e r C o n t r o l l e r do
2 d e s c r i b e ” r e s p o n d i n g t o GET show ” do
3 b e f o r e : e a c h do
4 @ u s e r = mock model ( U s e r )
5 end
6
7 i t ” s h o u l d e x p o s e t h e r e q u e s t e d u s e r a s @ u s e r ” do
8 U s e r . s h o u l d r e c e i v e ( : f i n d ) . w i t h ( ” 37 ” ) . a n d r e t u r n ( @ u s e r )
9 g e t : show , : i d = ” 37 ” >
10 a s s i g n s [ : u s e r ] . should equal ( @user )
11 end
12
13 d e s c r i b e ” w i t h mime t y p e o f xml ” do
14
15 i t ” s h o u l d r e n d e r t h e r e q u e s t e d u s e r a s xml ” do
16 r e q u e s t . en v [ ”HTTP ACCEPT” ] = ” a p p l i c a t i o n / xml ”
17 U s e r . s h o u l d r e c e i v e ( : f i n d ) . w i t h ( ” 37 ” ) . a n d r e t u r n ( @ u s e r )
18 @ u s e r . s h o u l d r e c e i v e ( : t o x m l ) . a n d r e t u r n ( ” g e n e r a t e d XML” )
19 g e t : show , : i d = ” 37 ”>
20 r e s p o n s e . body . s h o u l d == ” g e n e r a t e d XML”
21 end
22
23 end
24 end
25 end