Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 475 lines (309 sloc) 14.923 kb
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
1
2 <!DOCTYPE html>
3 <!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
4 <!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
5 <!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
6 <head>
7 <meta charset="utf-8">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
8 <title>Et si on écrivait une histoire à Rails ? - Shiny happy people coding</title>
9 <meta name="author" content="Cyril Mougel">
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
10
11
12 <meta name="description" content="Sous ce titre particulier, je voudrais parler un peu des stories de Rspec. En effet, depuis la version 1.0 de RSpec, les stories ont été ajouté à &hellip;">
13
14
15 <!-- http://t.co/dKP3o1e -->
16 <meta name="HandheldFriendly" content="True">
17 <meta name="MobileOptimized" content="320">
18 <meta name="viewport" content="width=device-width, initial-scale=1">
19
20
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
21 <link rel="canonical" href="http://blog.shingara.fr//et-si-on-ecrivait-une-histoire-a-rails.html">
22 <link href="/favicon.png" rel="icon">
23 <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
24 <script src="/javascripts/modernizr-2.0.js"></script>
25 <script src="/javascripts/ender.js"></script>
26 <script src="/javascripts/octopress.js" type="text/javascript"></script>
27 <link href="/atom.xml" rel="alternate" title="Shiny happy people coding" type="application/atom+xml">
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
28 <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
29 <link href="http://fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
30 <link href="http://fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
31
32
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
33 <script type="text/javascript">
34 var _gaq = _gaq || [];
35 _gaq.push(['_setAccount', 'UA-11352302-1']);
36 _gaq.push(['_trackPageview']);
37
38 (function() {
39 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
40 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
41 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
42 })();
43 </script>
44
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
45
46 </head>
47
48 <body >
49 <header role="banner"><hgroup>
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
50 <h1><a href="/">Shiny happy people coding</a></h1>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
51
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
52 <h2>Codons avec le sourire</h2>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
53
54 </hgroup>
55
56 </header>
57 <nav role="navigation"><ul class="subscription" data-subscription="rss">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
58 <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
59
60 </ul>
61
62 <form action="http://google.com/search" method="get">
63 <fieldset role="search">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
64 <input type="hidden" name="q" value="site:blog.shingara.fr/" />
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
65 <input class="search" type="text" name="q" results="0" placeholder="Search"/>
66 </fieldset>
67 </form>
68
69 <ul class="main-navigation">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
70 <li><a href="/">Blog</a></li>
71 <li><a href="/blog/archives">Archives</a></li>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
72 </ul>
73
74 </nav>
75 <div id="main">
76 <div id="content">
77 <div>
78 <article class="hentry" role="article">
79
80 <header>
81
82 <h1 class="entry-title">Et Si on écrivait Une Histoire à Rails ?</h1>
83
84
85 <p class="meta">
86
87
88
89
90
91
92
93
94
95
96
97
98 <time datetime="2008-04-03T00:00:00+02:00" pubdate data-updated="true">Apr 3<span>rd</span>, 2008</time>
99
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
100 | <a href="#disqus_thread">Comments</a>
101
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
102 </p>
103
104 </header>
105
106
107 <div class="entry-content"><p>
108 Sous ce titre particulier, je voudrais parler un peu des <a href="http://rspec.info/documentation/stories.html">stories de Rspec</a>. En effet, depuis la version 1.0 de <a href="http://rspec.info/">RSpec</a>, les stories ont été ajouté à Rspec. Ce système de story peux tout à fait être utilisé au sein de Rails pour permettre de créer des test d&#8217;intégrations. En effet, avec les spec traditionnels, nous ne pouvons pas réellement réaliser de test d&#8217;intégration. Avec les story nous pouvons le faire très facilement, que ca soit lisible et surtout très facilement répétable et modifiable. Mais le mieux est de vous montrer comment l&#8217;intégrer et l&#8217;utiliser à Rails.
109 </p>
110
111 <p>Si vous avez installer Rspec pour Rails et lancé la génération de rspec alors vous devez avoir dans votre arborescence un dossier stories. C&#8217;est en général dans ce dossier que nous mettons les stories.</p>
112
113 <h3>Votre première histoire</h3>
114
115 <p>Nous allons supposer que vous avez un petit système de login et que vous voulez le tester. Il suffit de créer le fichier login_story.rb comme ci-dessous</p>
116
117 <typo:code lang="ruby" linenumber="true" title="login_story.rb">
118 Story &#8220;Un Utilisateur s&#8217;authentifie&#8221;, %{
119 Je suis un utilisateur et je veux m&#8217;authentifier
120 Alors j&#8217;y arrive
121 }, :type => RailsStory do
122
123 Scenario &#8220;Logged successful&#8221; do
124 Given &#8220;un login&#8221;, &#8220;shingara&#8221; do |login|
125 @login = login
126 end
127
128 And &#8220;un mot de passe&#8221;, &#8220;mon_password&#8221; do |password|
129 @password = password
130 end
131
132 And &#8220;l&#8217;utilisateur est creer&#8221; do
133 User.create {:login => @login, :password => @password}
134 end
135
136 When &#8220;je vais sur&#8221;, &#8220;/&#8221; do |page|
137 get page
138 end
139
140 Then &#8220;je suis redirige vers la page de login&#8221; do
141 response.should redirect_to &#8216;/login&#8221;
142 follow_redirect!
143 end
144
145 When &#8220;Je me log&#8221; do
146 post &#8220;/login&#8221;, :login => @login, :password => @password
147 end
148
149 Then &#8220;Je suis redirige vers &#8220;, &#8220;/&#8221; do |path|
150 response.should redirect_to (&#8220;/&#8221;)
151 follow_redirect!
152 end
153 end
154 </typo:code>
155
156 <p>Voici donc un test de story avec Rails. Il faut bien penser à utiliser le type RailsStory pour que Story soit un Objet qui hérite de ActionController::IntegrationTest et puisse ainsi avoir toutes les méthodes utilent comme le follow_redirect!. Par contre, il faut faire attention, car le load des fixtures n&#8217;existent pas dans les Story, il faut créer soit-même un étape qui le fasse pour que cela soit possible.</p>
157
158 <h3>Et en plus répétable ?</h3>
159
160 <p>Maintenant une autre grande fonctionnalité des Story de Rspec est la possibilité de faire des stories en plain-text. Ainsi notre story précédente deviendrait tout simplement :</p>
161
162 <typo:code linenumber="true" title="login_story.rb">
163 Story: Un Utilisateur s&#8217;authentifie
164 Je suis un utilisateur et je veux m&#8217;authentifier
165 Alors j&#8217;y arrive
166
167 Scenario: Logged successful
168 Given un login shingara
169 And un mot de passe mon_password
170 And l&#8217;utilisateur est creer
171
172 When je vais sur /
173
174 Then je suis redirige vers la page de login
175
176 When Je me log
177
178 Then Je suis redirige vers /
179 </typo:code>
180
181 <p>A ce moment là plus besoin d&#8217;être développeur pour comprendre ce que fait le test. Pour cela en fait il faut créer toute une batterie de jeu d&#8217;étapes. Les étapes sont de 3 Types :</p>
182
183 <ul>
184 <li>Given : qui sont les données de base ou postulat</li>
185 <li>When : qui sont les actions</li>
186 <li>Then : qui sont les résultats</li>
187 </ul>
188
189 <p>
190 Il suffit donc de créer un fichier d&#8217;étapes qui comprenne toutes les étapes indiqués dans le fichier texte :
191 </p>
192
193 <typo:code lang="ruby" linenumber="true" title="login_steps.rb">
194 steps_for(:gallery) do
195
196 Given &#8220;un login $login&#8221; do |login|
197 @login = login
198 end
199
200 And &#8220;un mot de passe $password&#8221; do |password|
201 @password = password
202 end
203
204 And &#8220;l&#8217;utilisateur est creer&#8221; do
205 User.create {:login => @login, :password => @password}
206 end
207
208 When &#8220;je vais sur $page do |page|
209 get page
210 end
211
212 Then &#8220;je suis redirige vers la page de login&#8221; do
213 response.should redirect_to &#8216;/login&#8221;
214 follow_redirect!
215 end
216
217 When &#8220;Je me log&#8221; do
218 post &#8220;/login&#8221;, :login => @login, :password => @password
219 end
220
221 Then &#8220;Je suis redirige vers $path&#8221; do |path|
222 response.should redirect_to (&#8220;/&#8221;)
223 follow_redirect!
224 end
225 end
226 </typo:code>
227
228 <p>En indiquant que le fichier texte prend appui sur ce fichier d&#8217;étape, Rspec fait tout le reste. On appelle notre test de la façon suivante :</p>
229
230 <typo:code lang="ruby" linenumber="true" title="all.rb">
231 require File.join(File.dirname(__FILE__), *%w[helper])
232
233 with_steps_for(:login) do
234 run File.join(File.dirname(__FILE__), &#8220;login_story&#8221;, :type => RailsStory
235 end
236
237 </typo:code>
238
239 <p>Ce qui est vraiment génial dans tout ça c&#8217;est la possibilité du coup de changer l&#8217;ordre des étapes voir de leur paramètres. Ainsi le test suivant peux être réalisé sans nouveau code ruby d&#8217;ajouté : </p>
240 <typo:code linenumber="true" title="login_story.rb">
241 Story: Un Utilisateur s&#8217;authentifie
242 Je suis un utilisateur et je veux m&#8217;authentifier
243 Alors j&#8217;y arrive
244
245 Scenario: Logged successful
246 Given un login shingara
247 And un mot de passe mon_password
248 And l&#8217;utilisateur est creer
249
250 When je vais sur /
251
252 Then je suis redirige vers la page de login
253
254 When Je me log
255
256 Then Je suis redirige vers /
257
258 Scenario: Je vais directement sur la page de login et j&#8217;y reste
259 Given un login shingara
260 And un mot de passe mon_password
261 And l&#8217;utilisateur est creer
262
263 When je vais sur /login
264 And Je me log
265
266 Then Je suis redirige vers /login
267
268 </typo:code>
269 </div>
270
271
272 <footer>
273 <p class="meta">
274
275
276
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
277 <span class="byline author vcard">Posted by <span class="fn">Cyril Mougel</span></span>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
278
279
280
281
282
283
284
285
286
287
288
289
290
291 <time datetime="2008-04-03T00:00:00+02:00" pubdate data-updated="true">Apr 3<span>rd</span>, 2008</time>
292
293
294
295 </p>
296
297 <div class="sharing">
298
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
299 <a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.shingara.fr//et-si-on-ecrivait-une-histoire-a-rails.html" data-via="shingara" data-counturl="http://blog.shingara.fr//et-si-on-ecrivait-une-histoire-a-rails.html" >Tweet</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
300
301
302
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
303 <div class="fb-like" data-send="true" data-width="450" data-show-faces="false"></div>
304
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
305 </div>
306
307
308 <p class="meta">
309
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
310 <a class="basic-alignment left" href="/yoolink-sidebar-pour-typo.html" title="Previous Post: Yoolink-sidebar pour Typo">&laquo; Yoolink-sidebar pour Typo</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
311
312
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
313 <a class="basic-alignment right" href="/gestion-des-dependances-des-gems-directement-dans-rails.html" title="next Post: Gestion des dépendances des gems directement dans Rails">Gestion des dépendances des gems directement dans Rails &raquo;</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
314
315 </p>
316 </footer>
317 </article>
318
319 </div>
320
321 <aside class="sidebar">
322
323 <section>
324 <h1>Recent Posts</h1>
325 <ul id="recent_posts">
326
327 <li class="post">
81e78b6 @shingara Site updated at 2012-02-06 21:54:49 UTC
authored
328 <a href="/translate-on-mongoid.html">Localize avec mongoid</a>
329 </li>
330
331 <li class="post">
9db52e5 @shingara Site updated at 2012-01-27 17:56:52 UTC
authored
332 <a href="/mailtrap-l-aide-au-staging.html">Mailtrap l'aide au staging</a>
73d5f3f @shingara Site updated at 2012-01-27 17:50:39 UTC
authored
333 </li>
334
335 <li class="post">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
336 <a href="/une-journee-dediee-i-mongodb.html">Une journée dédiée à MongoDB</a>
337 </li>
338
339 <li class="post">
340 <a href="/periodictimer-de-eventmachine-le-cron-simplifie.html">PeriodicTimer de EventMachine, le cron simplifié</a>
341 </li>
342
343 <li class="post">
344 <a href="/oupsnow-0-5-0-est-sortie.html">Oupsnow 0.5.0 est sortie</a>
345 </li>
346
347 <li class="post">
348 <a href="/pourquoi-ruby-et-ruby-on-rails-dans-le-developpement-dapplication-web.html">Pourquoi Ruby et Ruby On Rails dans le développement d'application web ?</a>
349 </li>
350
351 <li class="post">
352 <a href="/que-cherche-un-developpeur-dans-une-offre-demploi.html">Que cherche un développeur dans une offre d'emploi ?</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
353 </li>
354
355 <li class="post">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
356 <a href="/sortie-de-typo-5-4-0.html">Sortie de Typo 5.4.0</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
357 </li>
358
359 <li class="post">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
360 <a href="/sortie-de-oupsnow-0-4-0.html">Sortie de Oupsnow 0.4.0</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
361 </li>
362
363 <li class="post">
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
364 <a href="/comment-tester-devise-reelement.html">Comment tester devise ? réélement ?</a>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
365 </li>
366
367 </ul>
368 </section>
369
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
370 <section>
371 <h1>Github Repos</h1>
372 <ul id="gh_repos">
373 <li class="loading">Status updating...</li>
374 </ul>
375
376 <a href="https://github.com/shingara">@shingara</a> on Github
377
378 <script type="text/javascript">
379 $.domReady(function(){
380 if (!window.jXHR){
381 var jxhr = document.createElement('script');
382 jxhr.type = 'text/javascript';
383 jxhr.src = '/javascripts/libs/jXHR.js';
384 var s = document.getElementsByTagName('script')[0];
385 s.parentNode.insertBefore(jxhr, s);
386 }
387
388 github.showRepos({
389 user: 'shingara',
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
390 count: 10,
391 skip_forks: false,
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
392 target: '#gh_repos'
393 });
394 });
395 </script>
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
396 <script src="/javascripts/github.js" type="text/javascript"> </script>
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
397 </section>
398
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
399
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
400 <section>
401 <h1>Latest Tweets</h1>
402 <ul id="tweets">
403 <li class="loading">Status updating...</li>
404 </ul>
405 <script type="text/javascript">
406 $.domReady(function(){
407 getTwitterFeed("shingara", 4, true);
408 });
409 </script>
410 <script src="/javascripts/twitter.js" type="text/javascript"> </script>
411
412 <a href="http://twitter.com/shingara" class="twitter-follow-button" data-show-count="true">Follow @shingara</a>
413
414 </section>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
415
416
417
418 </aside>
419
420
421 </div>
422 </div>
423 <footer role="contentinfo"><p>
1e149a0 @shingara Site updated at 2012-01-24 10:13:05 UTC
authored
424 Copyright &copy; 2012 - Cyril Mougel -
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
425 <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
426 </p>
427
428 </footer>
429
430
10781f9 @shingara Site updated at 2012-01-11 16:16:33 UTC
authored
431 <script type="text/javascript">
432 var disqus_shortname = 'shinydevblog';
433
434
435 var disqus_script = 'count.js';
436
437 (function () {
438 var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
439 dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
440 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
441 }());
442 </script>
443
444
445
446 <div id="fb-root"></div>
447 <script>(function(d, s, id) {
448 var js, fjs = d.getElementsByTagName(s)[0];
449 if (d.getElementById(id)) {return;}
450 js = d.createElement(s); js.id = id;
451 js.src = "//connect.facebook.net/en_US/all.js#appId=212934732101925&xfbml=1";
452 fjs.parentNode.insertBefore(js, fjs);
453 }(document, 'script', 'facebook-jssdk'));</script>
a9b3242 @shingara Site updated at 2012-01-11 10:28:52 UTC
authored
454
455
456
457
458
459 <script type="text/javascript">
460 (function(){
461 var twitterWidgets = document.createElement('script');
462 twitterWidgets.type = 'text/javascript';
463 twitterWidgets.async = true;
464 twitterWidgets.src = 'http://platform.twitter.com/widgets.js';
465 document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
466 })();
467 </script>
468
469
470
471
472
473 </body>
474 </html>
Something went wrong with that request. Please try again.