forked from ValtechTechno/cours-du-soir-bdd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1423 lines (1284 loc) · 56.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - The HTML Presentation Framework</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Hakim El Hattab">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/default.css" id="theme">
<!-- For syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- If the query includes 'print-pdf', use the PDF print sheet -->
<script>
document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Used to fade in a background when a specific slide state is reached -->
<div class="state-background"></div>
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>BDD</h1>
<h3>Behaviour Driven Development</h3>
</section>
<section>
<h1>Votre histoire</h1>
<p>Un problème rencontré récemment</p>
<p>Quelque chose que vous auriez souhaité savoir plus tôt</p>
<p>Mettre le titre de l'histoire sur le post it</p>
</section>
<section>
<h1>Conséquences sur engagements</h1>
<p>A partir de quel moment cette décision n'était plus réversible ?</p>
<p>Quand est ce que le problème a été remonté ?</p>
<p>Quel a été le coût ?</p>
<p>Mauvaise information communiquée à un client externe ?</p>
<p>Deadline non respectée ?</p>
<p>Perte financière ?</p>
<p>Code écrit pour rien ?</p>
</section>
<section>
<h1>Découverte délibérée</h1>
<p>Comment auriez vous pu avoir l'information manquante</p>
<p>A qui auriez vous pu parler ?</p>
<p>Où était l'information</p>
<p>Comment auriez vous pu assouplir vos engagements ?</p>
</section>
<section>
<h2>A priori</h2>
<p>BDD n'est pas nécessairement un outil d'automatisation</p>
<p>BDD n'est pas associée aux tests bout en bout</p>
<p>BDD n'est pas associée aux tests sélénium</p>
<p>BDD n'est pas un outil</p>
<blockquote>Avoir les conversations est plus important que les écrire ou les automatiser - Liz Keogh</blockquote>
</section>
<section>
<h2>Quelques repères historiques</h2>
<p>Black box testing (Weinberg and Gause, 1989)</p>
<p>Exemples automatisés (Ward Cunningham, 1996)</p>
<p>DDD (Eric Evans, 2004)</p>
</section>
<section>
<h2>TDD</h2>
<p>1995: Ward Cunningham & Kent Beck</p>
<img src="img/TestDrivenGameDevelopment1.png" style="width:300px" />
<ol>
<li><span style="color:red">Red</span>: Écrire un test qui va échouer car l'implémentation n’existe pas encore (Tester le test)</li>
<li><span style="color:green">Green</span>: Écrire l'implémentation utile la plus simple possible qui va faire passer les tests.</li>
<li><span style="color:blue">Refactor</span>: Supprimer la duplication. Améliorer le design.</li>
</ol>
</section>
<section>
<h2>TDD</h2>
<img src="img/TDD-hat.jpg" style="width:100px" />
<p>Les 3 règles (Bob Martin, 2005):</p>
<section>
<blockquote>Il est interdit d'écrire du code de production à moins que cela soit dans le but de faire passer un test en échec.</blockquote>
</section>
<section>
<blockquote>Il est interdit d'écrire plus que ce qui est nécessaire d'un test unitaire afin qu'il entre en échec; les échecs de compilations comptent pour des échecs.</blockquote>
</section>
<section>
<blockquote>Il est interdit d'écrire plus que ce qui est nécessaire du code de production afin de faire passer le test en échec.</blockquote>
</section>
</section>
<section>
<h2>TDD</h2>
<img src="img/TestDrivenGameDevelopment1.png" style="width:300px" />
<p>Spécifications des interactions</p>
<p>Outil de design interne et externe incrémental</p>
<p>Écrites par les programmeurs</p>
<p>Pour les programmeurs</p>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd1.jpg"/>
<blockquote>J'écris mon code en premier puis les tests</blockquote>
<blockquote>Les tests me permettent de vérifier que mon implémentation est correcte</blockquote>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd2.jpg"/>
<blockquote>Mes tests sont un filet de sécurité</blockquote>
<blockquote>Je peux modifier mon code avec confiance</blockquote>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd3.jpg"/>
<blockquote>Si j'écris mes tests avant l'implémentation alors je finis par écrire moins de code</blockquote>
<blockquote>De plus j'arrive à écrire un code plus facilement testable ce qui améliore mon design</blockquote>
<blockquote>Cette manière de travailler permet de concentrer mon attention sur la tache en cours</blockquote>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd4.jpg"/>
<blockquote>Avec le temps qui passe mes tests me servent de documentation</blockquote>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd5.jpg"/>
<blockquote>Écrire des tests revient à designer/spécifier l'API publique que je souhaiterais avoir</blockquote>
<blockquote>J'organise mon travail en commençant sur une phase de réflexion</blockquote>
</section>
<section>
<h2>L'apprentissage du test</h2>
<img src="img/tdd6.jpg"/>
<blockquote>En écrivant ces spécifications je spécifie le comportement attendu entre l'objet que je spécifie et ses collaborateurs</blockquote>
</section>
<section>
<h2>Mi-2003: De TDD à BDD</h2>
<img src="img/dan.jpg" />
<blockquote>Par où commencer ?</blockquote>
<blockquote>Que faut-il <span class="highlight">tester</span> ?</blockquote>
<blockquote>Comment appeler les <span class="highlight">tests</span> ?</blockquote>
<blockquote>Que faut-il ne pas <span class="highlight">tester</span> ?</blockquote>
<blockquote>Mais...les <span class="highlight">tests</span>...c'est pour les <span class="highlight">testeurs</span> !!!</blockquote>
</section>
<section>
<h2>Mi-2003: De TDD à BDD</h2>
<p>Les noms des méthodes de test doivent être des phrases</p>
<section>
<pre><code class="java">
import junit.framework.*;
public class TestMath extends TestCase {
public void testAdd() {
int num1 = 3;
int num2 = 2;
int total = 5;
int sum = 0;
sum = Math.add(num1, num2);
assertEquals(sum, total);
}
}
</pre></code>
</section>
<section>
<pre><code class="java">
import junit.framework.*;
public class TestMath extends TestCase {
public void testAddingTwoNumberReturnTheirSum() {
int num1 = 3;
int num2 = 2;
int total = 5;
int sum = 0;
sum = Math.add(num1, num2);
assertEquals(sum, total);
}
}
</pre></code>
</section>
</section>
<section>
<h2>Mi-2003: De TDD à BDD</h2>
<p>PNL:Les mots et les langages influent sur notre pensée</p>
<p>Introduction du mot "should" à la place de "test"</p>
<p>Le test se lit maintenant comme une spécification</p>
<section>
<pre><code class="java">
import junit.framework.*;
public class TestTimer {
public void testStartStop() throws Exception {
Timer timer = new Timer();
timer.start();
Thread.sleep(10);
timer.stop();
assertTrue(timer.elapsedTimeMillis() > 0);
}
}
</pre></code>
</section>
<section>
<pre><code>
public class TimerSpec {
public void shouldMeasureAPeriodOfTime() throws Exception {
Timer timer = new Timer();
timer.start();
Thread.sleep(10);
timer.stop();
Verify.that(timer.elapsedTimeMillis() > 0);
}
}
</code></pre>
</section>
</section>
<section>
<h2>Mi-2003: De TDD à BDD</h2>
<p>Avantages de "should"</p>
<p>Permet de nommer facilement les méthodes de test</p>
<p>Permet d'appliquer SRP</p>
<p>Permet de remettre en cause les tests</p>
<p>Aide à comprendre les rapports de tests</p>
<img src="img/unittestreport.png"/>
</section>
<section>
<h2>Début 2004: Gherkin</h2>
<q>Tout cela ressemble fortement à de l'analyse...</q>
<pre><code class="gherkin_fr">
Scénario: Effectuer un retrait avec succès
# Le contexte
Etant donné que je possède '100€' sur mon compte
# Les événements
Quand je demande '20€'
# Le résultat attendu
Alors '20€' doivent être distribués
</pre></code>
</section>
<section>
<h2>2005-2009: Feature injection, Outside In, pull based</h2>
<p>Le développement est tiré par le besoin</p>
<p>Tout artefact existe car il provient d'un besoin plus haut dans le système</p>
<p>Permet de limiter le travail en cours</p>
</section>
<section>
<h2>2007: SDD</h2>
<p>Joshua Kerievsky (Refactoring to Patterns)</p>
<blockquote>Communities that do StorytestDrivenDevelopment (SDD) <span class="highlight">work collaboratively on storytests</span>. A <span class="highlight">domain expert</span> may write some storytest details on a whiteboard while a <span class="highlight">QA person looks on and asks questions</span> . Next, <span class="highlight">developers collaborate with the QA person and domain expert</span> to understand and then automate the storytest. <span class="highlight">Lots of dialogue between members of the customer and developer communities happens throughout this process.</span></blockquote>
</section>
<section>
<h2>2009: Dan's long definition</h2>
<section>
<blockquote>BDD is a second-generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology.It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.</blockquote>
</section>
<section>
<p>Second-generation</p>
<img src="img/DDD_TDD_BDD_intersection.png"/>
<blockquote>Comment tester ?</blockquote>
<blockquote>Comment documenter ?</blockquote>
</section>
<section>
<p>Outside-in and pull based</p>
<img src="img/PullBehaviorFromStakeholders40.png">
<div style="font-size:0.6em">
<p>Inspiré de lean</p>
<p>Développement tiré par le besoin</p>
<p>Besoin exprimé collaborativement sous forme d'exemples</p>
<p>On produit que ce qui est nécessaire</p>
<p>On produit quand c'est nécessaire</p>
</div>
</section>
<section>
<p>Agile</p>
<p>Itérations</p>
<p>Équipes multi-compétentes</p>
<p>Travail en tranches</p>
</section>
<section>
<p>High-Automation</p>
<p>Outillage</p>
<p>Vérification automatisée</p>
<p>Feedback sur travail en cours</p>
</section>
<section>
<p>Multiple stake holder (Kaizen)</p>
<p>Pousser la collaboration sur les 3 axes:</p>
<p>Métier</p>
<p>Technique</p>
<p>Personnes et les processus</p>
</section>
<section>
<p>Multiple scale</p>
<img src="img/fractale.png">
</section>
</section>
<section>
<h2>2009-2012: Specs par l'exemple</h2>
<p>Standardiser ATDD,BDD,TDR,Example Driven Development,Story Testing Driven Development, Executable specifications</p>
<div>
<img src="img/specby.jpg" style="width:200px;float:left" />
<blockquote>The fact that the same practices have so many names reflects the huge amount of innovation
in this field at the moment. It also reflects the fact that the practices described in
this book impact the ways teams approach specifications, development, and testing. To
be consistent, I had to choose one name. I settled on <span class="highlight">Specification by Example*</span>.</blockquote>
<p style="font-size:10pt">*Terme créé originellement par M.Fowler, 2002</p>
</div>
</section>
<section>
<h2>Processus de développement classique</h2>
<img src="img/classic2.png">
</section>
<section>
<h2>La communication</h2>
<p>Ambiguïtés</p>
<blockquote>Il a trouvé un avocat</blockquote>
<p>Amphibologie</p>
<blockquote>Elle est sortie en pleurant du café</blockquote>
<p>Illusions</p>
<img src="img/chevrouille.jpg" style="width:200px">
</section>
<section>
<h2>Comment communiquer ?</h2>
<section><img src="img/cell_01.jpg"/><p>Comment le client l'a expliqué</p></section>
<section><img src="img/cell_02.jpg"/><p>Comment le chef de projet l'a compris</p></section>
<section><img src="img/cell_03.jpg"/><p>Comment l'analyste l'a conçu</p></section>
<section><img src="img/cell_04.jpg"/><p>Comment les développeur l'ont implémenté</p></section>
<section><img src="img/cell_05.jpg"/><p>Ce que les testeurs ont reçu</p></section>
<section><img src="img/cell_06.jpg"/><p>Comment les commerciaux l'ont décrit</p></section>
<section><img src="img/cell_07.jpg"/><p>Comment le projet a été documenté</p></section>
<section><img src="img/cell_08.jpg"/><p>Ce que la production a installé</p></section>
<section><img src="img/cell_09.jpg"/><p>Ce que le client a été facturé</p></section>
<section><img src="img/cell_10.jpg"/><p>Le support client qui a été fourni</p></section>
<section><img src="img/cell_11.jpg"/><p>Comment le marketing la vendu</p></section>
<section><img src="img/cell_13.jpg"/><p>Ce dont le client avait vraiment besoin</p></section>
</section>
<section>
<h2>Optimisons au mieux le rôle de chacun</h2>
<blockquote class="fragment chat"><img class="shadow" src="img/ba.png" />Je possède la vision du produit, connaît les conditions d'utilisations normales, réponds aux questions.</blockquote>
<blockquote class="fragment chat"><img class="shadow" src="img/dev.png" />Je clarifie le besoin et vérifie la faisabilité technique (implem+automat)</blockquote>
<blockquote class="fragment chat"><img id="troll" class="shadow" src="img/tester.png" />Je sais où appuyer pour que ça fasse mal.</blockquote>
</section>
<section>
<h2>BDD comme processus de développement</h2>
<blockquote>Les individus et les échanges plutôt que les processus et les outils</blockquote>
<img src="img/bdddev.png">
</section>
<section>
<h2>Comment communiquer ?</h2>
<div style="font-size:0.6em">
<blockquote class="fragment chat"><img class="shadow" src="img/ba.png" />Nous voulons augmenter le nombre de commandes. Nous allons donc accorder 10% de remises sur toutes les premières commandes.</blockquote>
<blockquote class="fragment chat"><img class="shadow" src="img/dev.png" />public void CalculateDiscount(Order order){
if(order.Customer.IsNew)
order.FinalAmount = Math.Round(order.Total*0.9);
}
</blockquote>
<blockquote class="fragment chat"><img class="shadow" src="img/tester.png" />Register as "newuser"
Go to "/catalog/search"
Enter "ISBN-0955683610
Click "Search"
Click "Add to cart"
Click "View Cart"
Verify "Subtotal" is "30"</blockquote>
</div>
</section>
<section>
<h2>Comment communiquer ?</h2>
<p>Trouver un langage commun (DDD)</p>
<p>qui s'abstrait de la technologie</p>
<p>le <span class="highlight">QUOI</span> avant le <span class="highlight">COMMENT</span></p>
<p>Supprimer la différence d’impédance entre BA/DEV/Test </p>
<p>le même langage à tous les niveaux</p>
<p>Apprendre ensemble/Découvrir ensemble le comportement de l'application</p>
<p>Processus ayant pour but d'arriver à une vision commune</p>
</section>
<section>
<h2>S'exprimer en Gherkin</h2>
<img class="shadow" src="img/ba.png" />
<img class="shadow" src="img/dev.png" />
<img class="shadow" src="img/tester.png" />
<pre>
<code class="gherkin_fr">
Etant donné un utilisateur qui n’a jamais commandé
Quand l’utilisateur met un livre dans son panier
Alors il faut lui accorder une remise de 10% sur le montant total du panier
</code>
</pre>
</section>
<section>
<h2>Phase préparatoire</h2>
<p>Réalisée avant l'atelier</p>
<p>Avec responsable métier, analystes</p>
<p>Sortir les premiers exemples d'utilisation</p>
<p>Le but est de préparer les futures discussions</p>
</section>
<section>
<h2>Préparation de la session</h2>
<p>L'idéal: 1 dev, 1 testeur, 1 BA</p>
<p>Rotations de paires selon maturité</p>
<p>Idéalement une personne spécialisée dans le domaine de la fonctionnalité</p>
<p>Acteurs préparés à l'avance</p>
<p>Noter une version "allégée" des scénarios</p>
<p>Equipe entière selon maturité</p>
</section>
<section>
<h2>Les questions à se poser pour déterminer la valeur</h2>
<pre><code class="gherkin_fr">
Afin de 'valeur'
En tant que 'role'
Je veux 'fonctionnalité'
</code></pre>
<p>Comment cela doit fonctionner ?</p>
<p>Pourquoi cela doit il fonctionner comme cela ?</p>
<p>Qui a besoin de cette fonctionnalité</p>
<p>Que se passerait il si cette fonctionnalité était enlevée?</p>
<p>Quelle est la valeur pour les utilisateurs</p>
<p>Les 5 pourquoi</p>
</section>
<section>
<h2>Deliberate discovery</h2>
<p>Trouver des nouveaux scénarios à travers la collaboration et le brainstorming</p>
<pre><code class="gherkin_fr">
Etant donné 'essayer de trouver différents contextes'
Quand 'utilisation de la fonctionnalité'
Alors 'essayer de trouver des vérifications alternatives'
</code></pre>
<p>Découvrir ce que nous ne savons pas</p>
<p>Découvrir les choses critiques qui pourraient être oubliés</p>
<p>Processus d'apprentissage collaboratif</p>
</section>
<section>
<h2>Exemple déroulement session</h2>
<div style="font-size:0.5em">
<blockquote class="fragment chat"><img class="shadow" src="img/ba.png" />Nous voulons proposer aussi à nos client la livraison à domicile</blockquote>
<blockquote class="fragment chat"><img src="img/dev.png" />Existe il des cas où il ne faut pas proposer la livraison à domicile ne doit pas être proposée ?</blockquote>
<blockquote class="fragment chat"><img src="img/ba.png" />Oui il ne faut pas la proposer pour les adresses de livraisons qui ne se situent pas sur paris</blockquote>
<blockquote class="fragment chat"><img src="img/dev.png" />D'accord, il faut donc proposer cette option uniquement pour les adresses ayant pour code postal 75XXX</blockquote>
</div>
</section>
<section>
<h2>Exemple déroulement session</h2>
<div style="font-size:0.5em">
<blockquote class="fragment chat"><img src="img/tester.png" />Attention, certains pays comme l’Italie ont des codes postaux de la forme 75XXX, mais bien sûr il ne faut pas proposer cette option en italie</blockquote>
<blockquote class="fragment chat"><img src="img/dev.png" />OK, je pense qu'il faudrait écrire un scénario supplémentaire pour ce cas-ci afin de montrer que l'option n'est disponible qu'en France et que pour les code postaux situés sur Paris</blockquote>
</div>
</section>
<section>
<h2>Exemple déroulement session</h2>
<div style="font-size:0.5em">
<blockquote class="fragment chat"><img src="img/ba.png" />Nous voulons offrir la livraison gratuite pour certains produits comme certains livres par exemple</blockquote>
<blockquote class="fragment chat"><img src="img/dev.png" />Est-ce que cette livraison gratuite est disponible qu'importe le lieu de livraison ?</blockquote>
<blockquote class="fragment chat"><img src="img/ba.png" />En effet il ne faut pas proposer la livraison à domicile en dehors de la France.</blockquote>
<blockquote class="fragment chat"><img src="img/tester.png" />Que se passe-t-il si j’achète un livre avec livraison gratuite et un sans livraison gratuite ?</blockquote>
<blockquote class="fragment chat"><img src="img/ba.png" />Dans ce cas on bénéficie toujours de la livraison gratuite pour l'ensemble des livres</blockquote>
</div>
</section>
<section>
<h2>Exemple déroulement session</h2>
<div style="font-size:0.5em">
<blockquote class="fragment chat"><img src="img/dev.png" />Que se passe-t-il si je commande un livre et un frigo, certainement la livraison ne pas plus être gratuite non ?</blockquote>
<blockquote class="fragment chat"><img src="img/ba.png" />Mhmmm nous n'avons pas pensé à ce cas, je dois en discuter et je reviendrais vers vous concernant ce scénario.</blockquote>
</div>
</section>
<section>
<h2>Deliberate discovery, examples</h2>
<pre class="fragment">
<code class="gherkin_fr">
Etant donné que je possède 100€ sur mon compte
Quand je demande 20€
Alors 20€ doivent être distribués
</code>
</pre>
<pre class="fragment">
<code class="gherkin_fr">
Etant donné que je possède 100€ sur mon compte
Quand je demande 20€
Alors je dois récupérer ma carte
</code>
</pre>
<pre class="fragment">
<code class="gherkin_fr">
Etant donné que je possède 100€ sur mon compte
Quand je demande 20€
Alors mon compte doit être débité de 20€
</code>
</pre>
</section>
<section>
<h2>Avantages de Gherkin</h2>
<p>Un exemple concret vaut mieux qu'une explication générale et abstraite</p>
<blockquote>Les clients ne doivent pas pouvoir saisir de numéro de carte bleue invalide</blockquote>
<p>Laisse des questions en suspens:
Qu'est-ce qu'un numéro de carte invalide ?
Comment l'utilisateur doit être notifié ?</p>
<p>Une meilleure version:</p>
<pre>
<code class="gherkin_fr">
Scénario: saisie de numéro de carte bleue incorrect
Etant donné que le client a saisit un numéro de carte bleu avec une longueur inférieure à 16 chiffres
Quand il valide sa saisie
Alors un message doit lui indiquer que sa saisie est incorrecte
</code>
</pre>
</p>
</section>
<section>
<h2>Avantages de Gherkin</h2>
<p>Simple et souple</p>
<p>Gherkin n'impose que les mots clés Given/When/Then</p>
<p>Tout le reste peut être écrit en langage naturel !</p>
</section>
<section>
<h2>Avantages de Gherkin</h2>
<p>Écriture et lecture à la portée de tous</p>
<p>Peuvent être remises en cause</p>
</section>
<section>
<h2>Avantages découlant de l'utilisation de BDD</h2>
<p>Implication du métier en leur offrant une meilleure transparence sur l'implémentation des fonctionnalités</p>
<p>Ludique et facilite le brainstorming</p>
<p>Permet d'améliorer l'esprit d'appropriation de l'équipe face au produit car on va spécifier ensemble</p>
<p>Permet de simuler la future utilisation de la fonctionnalité et dans voir les limites</p>
<p>Permet de découvrir de nouvelles options avant de s'engager dans une voie</p>
</section>
<section>
<h2>Responsabilisation et appropriation</h2>
<img src="img/melee-scrum.jpg"/>
<div style="font-size:0.8em">
<p>L'équipe entière s'investit dans</p>
<p>La qualité du produit</p>
<p>L'automatisation des spécifications</p>
<p>La création d'une application facile à tester</p>
<p>La documentation de l'application</p>
</div>
</section>
<section>
<h2>Avantages découlant de l'utilisation de BDD</h2>
<blockquote>Working software over comprehensive documentation</blockquote>
<p>Une documentation de l'application toujours à jour !</p>
<p>Des spécification versionnées grâce au contrôle de source</p>
</section>
<section>
<h2>Avantages découlant de l'utilisation de BDD</h2>
<p>Donne un point de départ à TDD + lean code + Feature injection + YAGNI + KISS</p>
<p>Création d'un langage omniprésent (DDD, spec, code, test, conversations)</p>
</section>
<section>
<h2>Effets secondaires de BDD</h2>
<p>Servent de filet anti-régression</p>
<p>Permet de faciliter le refactoring car test boite noire</p>
<p>Donne un point de départ à TDD + lean code + Feature injection + YAGNI + KISS</p>
</section>
<section>
<h2>Ruby Cucumber</h2>
<img src="img/ruby1.png" />
<img src="img/ruby2.png" />
<img src="img/ruby3.png" />
<img src="img/ruby4.png" />
<img src="img/ruby5.png" />
<img src="img/ruby6.png" />
</section>
<section>
<h2>.NET SpecFlow</h2>
<img src="img/specflow1.png" />
<img src="img/specflow2.png" />
</section>
<section>
<h2>Cucumber JVM<h2/>
<pre style="font-size:10pt" class="sh_gherkin_en sh_sourceCode"><code><span class="sh_keyword">Feature</span>: Hello World
<span class="sh_keyword"> Scenario</span>: Say hello
<span class="sh_keyword"> Given </span>I have a hello app with <span class="sh_string">"Howdy"</span>
<span class="sh_keyword"> When </span>I ask it to say hi
<span class="sh_keyword"> Then </span>it should answer with <span class="sh_string">"Howdy World"</span>
</code></pre>
<pre style="font-size:10pt" class="sh_java sh_sourceCode"><code>
<span class="sh_keyword">public</span> <span class="sh_keyword">class</span><span class="sh_normal"> </span><span class="sh_classname">HelloStepdefs</span> <span class="sh_cbracket">{</span>
<span class="sh_keyword">private</span> <span class="sh_usertype">Hello</span><span class="sh_normal"> </span>hello<span class="sh_symbol">;</span>
<span class="sh_keyword">private</span> <span class="sh_usertype">String</span><span class="sh_normal"> </span>hi<span class="sh_symbol">;</span>
@<span class="sh_function">Given</span><span class="sh_symbol">(</span><span class="sh_string">"^I have a hello app with </span><span class="sh_specialchar">\"</span><span class="sh_string">([^</span><span class="sh_specialchar">\"</span><span class="sh_string">]*)</span><span class="sh_specialchar">\"</span><span class="sh_string">$"</span><span class="sh_symbol">)</span>
<span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">I_have_a_hello_app_with</span><span class="sh_symbol">(</span><span class="sh_usertype">String</span><span class="sh_normal"> </span>greeting<span class="sh_symbol">)</span> <span class="sh_cbracket">{</span>
hello <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">Hello</span><span class="sh_symbol">(</span>greeting<span class="sh_symbol">);</span>
<span class="sh_cbracket">}</span>
@<span class="sh_function">When</span><span class="sh_symbol">(</span><span class="sh_string">"^I ask it to say hi$"</span><span class="sh_symbol">)</span>
<span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">I_ask_it_to_say_hi</span><span class="sh_symbol">()</span> <span class="sh_cbracket">{</span>
hi <span class="sh_symbol">=</span> hello<span class="sh_symbol">.</span><span class="sh_function">sayHi</span><span class="sh_symbol">();</span>
<span class="sh_cbracket">}</span>
@<span class="sh_function">Then</span><span class="sh_symbol">(</span><span class="sh_string">"^it should answer with </span><span class="sh_specialchar">\"</span><span class="sh_string">([^</span><span class="sh_specialchar">\"</span><span class="sh_string">]*)</span><span class="sh_specialchar">\"</span><span class="sh_string">$"</span><span class="sh_symbol">)</span>
<span class="sh_keyword">public</span> <span class="sh_type">void</span> <span class="sh_function">it_should_answer_with</span><span class="sh_symbol">(</span><span class="sh_usertype">String</span><span class="sh_normal"> </span>expectedHi<span class="sh_symbol">)</span> <span class="sh_cbracket">{</span>
<span class="sh_function">assertEquals</span><span class="sh_symbol">(</span>expectedHi<span class="sh_symbol">,</span> hi<span class="sh_symbol">);</span>
<span class="sh_cbracket">}</span>
<span class="sh_cbracket">}</span>
</code></pre>
</section>
<section>
<h2>Améliorer la lisibilité à l'aide des tables</h2>
<pre>
<code class="gherkin_fr">
Etant donné le produit 'Baskets' avec un prix de '50' euros et un poids de '300' g
Et le produit 'Jeans' avec un prix de '60' euros et un poids de '200' g
Et le produit 'T-shirt' avec un prixd '20 euros' et un poids de '50' g
</code>
</pre>
</section>
<section>
<h2>Améliorer la lisibilité à l'aide des tables</h2>
<pre>
<code class="gherkin_fr">
Etant donné les produits:
|Nom |Prix (euros)|Poids (g)|
|Baskets|50 |300 |
|Jeans |60 |200 |
|T-shirt|20 |50 |
</code>
</pre>
</section>
<section>
<h2>Patrons de scénarios</h2>
<pre style="font-size:0.4em">
<code class="gherkin_fr">
Fonctionnalité: Retrait d’un montant fixe
<i>Le menu de retrait contient plusieurs montants</i>
<i>fixes afin que le client puisse retirer rapidement</i>
Scénario:Retrait de 50€
Etant donné que je possède 500€ sur mon compte
Quand je retire 50€
Alors je dois recevoir 50€
Et mon compte doit posséder un solde de 450€
Scénario:Retrait de 100€
Etant donné que je possède 500€ sur mon compte
Quand je retire 100€
Alors je dois recevoir 100€
Et mon compte doit posséder un solde de 400€
Scénario:Retrait de 200€
Etant donné que je possède 500€ sur mon compte
Quand je retire 200€
Alors je dois recevoir 200€
Et mon compte doit posséder un solde de 300€
</code>
</pre>
</section>
<section>
<h2>Patrons de scénarios</h2>
<pre>
<code class="gherkin_fr">
Fonctionnalité: Retrait d’un montant fixe
<i>Le menu de retrait contient plusieurs montants</i>
<i>fixes afin que le client puisse retirer rapidement</i>
Scénario:Retrait
Etant donné que je possède '<solde>'€ sur mon compte
Quand je retire '<retrait>'€
Alors je dois recevoir '<distribué>'€
Et mon compte doit posséder un solde de '<restant>'€
Examples:
|solde|retrait|distribué|restant|
|500 |50 |50 |450 |
|500 |100 |100 |400 |
|500 |200 |200 |300 |
</code>
</pre>
</section>
<section>
<h2>Scénarios à tables multiples</h2>
<pre>
<code class="gherkin_fr" style="font-size:0.8em">
Etant donné que j’essaie de créer un compte avec le mot de passe '<Mot de passe>'
Alors je devrais être notifié que le mot de passe est '<Validité>'
Examples: <i>Trop court</i>
<i>Les mots de passe inférieurs à 4 caractères sont invalides</i>
| Mot de passe | Validité |
| abc | invalide |
| ab1 | invalide |
Examples: <i>Lettres et chiffres</i>
<i>Les mots de passe doivent contenir des lettres et des chiffres</i>
| Mot de passe | Validité |
| abc1 | valide |
| abcd | invalide |
| abcd1 | valide |
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Éviter les scénarios trop abstraits</p>
<pre>
<code class="gherkin_fr">
Scénario: Montant total du panier
Etant donné un client avec 3 produits dans son panier
Alors il doit visualiser correctement le montant total
Scénario: Montant total du panier
Etant donné un client A
Et possédant un panier avec les produits B et C
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Éviter les scénarios trop abstraits</p>
<pre>
<code class="gherkin_fr">
Scénario: Montant total du panier
Etant donné un client avec les produits suivants dans son panier
|Nom du produit |Prix unitaire(euros)|Quantité|
|PS3 |250 |1 |
|Prince of persia|50 |1 |
Quand il consulte son panier flotant
Alors il doit visualiser un montant total de 300 euros
</code>
</pre>
</section>
<section>
<h2>Mauvaises pratiques</h2>
<p>Faire apparaître des ID techniques</p>
<pre>
<code class="gherkin_fr">
Scénario: Montant total du panier
Etant donné les produits suivants:
|Id|Produit |Prix unitaire|
|1 |PS3 |250 |
|2 |Prince of persia|50 |
Et le client suivant
|Id|Nom|
|1 |John|
Et le panier suivant:
|Id|ClientId|
|1 |1 |
Et avec les articles suivants:
|Id|PanierId|ArticleId|Quantité|
|1 |1 |1 |1 |
|2 |1 |2 |1 |
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Lisibilité avant tout (scripts à bannir)<p>
<p>Ne pas exprimer les scénarios en terme d'UI</p>
<p>Découplé de l'UI afin de faciliter le changement</p>
<p>Sont généralement trop verbeux, ennuyants à lire et fragiles</p>
<p>Exprimez vos scénarios en terme métier<p>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Éviter les tests workflow</p>
<p>=>Tester en terme d'UI ou de workflow masque l'intention, le lecteur doit refaire le chemin inverse</p>
<p>=>Le QUOI pas le COMMENT</p>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Se concentrer sur ce que doit faire l'application et non pas comment elle le réalise</p>
<pre>
<code class="gherkin_fr">
Scénario: Les utilisateurs non connectés doivent être redirigés vers le formulaire de connexion
Etant donné l’utilisateur 'Pierre'
Et ayant pour adresses email '[email protected]'
Et ayant le mot de passe 'passw0rd'
Quand l’utilisateur visite la page 'http://localhost:5740/monsite'
Alors il doit être redirigé vers la page 'https://localhost:5740/monsite/login'
Quand il saisit le login '[email protected]' dans le champ '#login'
Et qu’il saisit le mot de passe 'passw0rd' dans le champ '#mdp'
Et qu’il valide le formulaire "#formLogin" de connexion
Alors il doit être redirigé vers la page 'http://localhost:5740/monsite/home'
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Se concentrer sur ce que doit faire l'application et non pas comment elle le réalise</p>
<pre>
<code class="gherkin_fr">
Scénario: Les utilisateurs non connectés doivent être redirigés vers le formulaire de connexion
Etant donné un utilisateur non connecté
Quand il essaie d’accéder à n’importe quelle page du site
Alors il doit être redirigé vers le formulaire de connexion
Scénario: Utilisateur ayant été redirigé vers le formulaire de connexion
Etant donné un utilisateur ayant été redirigé vers le formulaire de connexion
Quand il soumet ses identifiants
Alors il doit être redirigé vers la page dont il avait essayé d’accéder
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Bien nommer ses scénarios</p>
<pre>
<code class="gherkin_fr">
Scénario: 100 euros
Etant donné que le client possède pour plus de 100 euros de produits
Quand il consulte son récapitulatif de panier
Alors il doit visualiser une réduction immédiate de 10% sur le montant total
</code>
</pre>
</section>
<section>
<h2>Bonnes pratiques</h2>
<p>Faire un résumé du scénario</p>
<pre>
<code class="gherkin_fr">
Scénario: Accorder une réduction de 10% pour les paniers de plus de 100 euros
Etant donné que le client possède pour plus de 100 euros de produits
Quand il consulte son récapitulatif de panier
Alors il doit visualiser une réduction immédiate de 10% sur le montant total
</code>
</pre>
<p>Permet de retrouver plus rapidement des scénarios d'intérêt</p>
<p>Permet par la suite d'aider à l'analyse des scénarios en échec</p>
</section>
<section>
<h2>Tags: Retrouver ses scénarios</h2>
<pre>
<code class="gherkin_fr">
@nightly @web @summary @sprint10
Scénario: Accorder une réduction de 10% pour les paniers de plus de 100 euros
Etant donné que le client possède pour plus de 100 euros de produits
Quand il consulte son récapitulatif de panier
Alors il doit visualiser une réduction immédiate de 10% sur le montant total
</code>
</pre>
</section>
<section>
<h2>Éviter de tester toutes les combinaisons</h2>
<p>Partir du happy path</p>
<p>Explorer à partir de là</p>
<p>Ces scénarios pourront servir de bases pour une autre spec plus orienté vérification.</p>
</section>
<section>
<h2>Les principes F.I.R.S.T</h2>
<p class="fragment">Fast</p>
<p class="fragment">Independent</p>
<p class="fragment">Repeatable</p>
<p class="fragment">Self Validating</p>
<p class="fragment">Timely</p>
</section>
<section>
<h2>Bugs</h2>
<p>Il n'y pas de bugs!</p>
<p>Mais que des scénarios oubliés !</p>
</section>
<section>
<h2>Mauvaises pratiques</h2>
<p>Écrire les scénarios en solo</p>
<p>Écrire les scénarios avec seulement BA et testeur puis catapultage sur le développeur</p>
<p>Les 3 acteurs doivent toujours arriver à une étape de collaboration</p>
<p>Afin de développer le langage/compréhension/vision commune</p>
</section>
<section>
<h2>Mauvaises pratiques</h2>
<p>Utiliser Specflow pour de simples TU</p>
<section><pre><code class="gherkin_en">
Feature: Stack
When a new stack is created
Then it is empty
When an element is added to the stack
Then that element is at the top of the stack
When a stack has N elements
And element E is on top of the stack
Then a pop operation returns E
And the new size of the stack is N-1
</code></pre></section>
<section><pre><code>
describe Hash do
before do
@hash = Hash.new({:hello => 'world'})
end
it "should return a blank instance" do
Hash.new.should == {}
end
it "hash the correct information in a key" do
@hash[:hello].should == 'world'
end
end
</code></pre></section>
</section>
<section>
<h2>En savoir plus ?</h2>
<p>Livres</p>
<div>
<img src="img/cukebook.jpg" style="width:100px"/>
<img src="img/specby.jpg" style="width:100px"/>
</div>
<div>
<p>Blogs</p>
<a>lizkeogh.com</a>
<a>dannorth.net</a>
</div>
<div>
<p>Wiki</p>
<p><a>behaviordrivendevelopment.wikispaces.com</a></p>
</div>
<div>
<p>Attention</p>
<a>Pas que du bon sur le net!</a>
</div>
</section>
<section>
<h2>Architecture technique</h2>
Business layer
Features
Scenarios
Steps
TEchnlogy layer
Step definitions
Support code
Automation library
SUT
</section>
<section>
<h2>Implémentation technique</h2>
<p>Outside In (Permet de YAGNI/KISS)
Toute chose provient d'un besoin code->test->feature->business</p>
<p>Specflow doit être un client de l'application comme peut l'être un navigateur ou une application desktop.
Il faut donc créer se layer applicatif qui permet à n'importe quel type de client de parler à l'application via une API.</p>
<p>Steps définitions doivent être un layer fin</p>
<p>Steps définitions doivent faire exactement ce que l'on attend d'elles, ni plus, ni moins</p>
<p>Factoriser les steps</p>
<p>L'utilisateur entre son login
L'utilisateur entre son mdp
L'utilisateur valide
=> L'utilisateur se connecte au site</p>
<p>Travailler en environnement isolé</p>