Upgrade to Pro — share decks privately, control downloads, hide ads and more …

『アジャイルソフトウェア開発の奥義』から学ぶテスト駆動開発

2722ca734f5f05badb74f976d1f2b6c8?s=47 yonetty
February 16, 2021

 『アジャイルソフトウェア開発の奥義』から学ぶテスト駆動開発

社内の勉強会で使用した資料。

2722ca734f5f05badb74f976d1f2b6c8?s=128

yonetty

February 16, 2021
Tweet

Transcript

  1. ʰΞδϟΠϧιϑτ΢ΣΞ։ൃͷ Ԟٛʱ͔ΒֶͿςετۦಈ։ൃ +BOVBSZUI  5BLFTIJ:POFLVCP !UZPOFLVCP

  2. ςετϑΝʔετ ͱ ςετۦಈ։ൃ

  3. ςετϑΝʔετ ϓϩμΫτίʔυΑΓઌʹ ςετίʔυΛॻ͘͜ͱ

  4. ςετۦಈ։ൃ 5FTU%SJWFO%FWFMPQNFOU ςετίʔυΛಓ۩ʹ 
 ͯ͠ɺ։ൃΛճ͢͜ͱ

  5. ϨουάϦʔϯϦϑΝΫλϦϯά ᶃࣦഊ͢ΔςετΛॻ͘ ᶄςετ͕௨Δγϯϓϧ ͳίʔυΛॻ͘ ᶅϦϑΝΫλϦϯά͠ ͯίʔυΛ៉ྷʹ͢Δ

  6. ςετϑΝʔετ͕ͩ ςετۦಈ։ൃͰͳ͍ྫ  ઌʹ͢΂ͯͷςετίʔυΛॻ͘ class FooTest { def testFoo1() {

    } def testFoo2() { } def testFoo3() { } def testFoo4() { } … } class Foo { // ͜Ε͔Β࣮૷ }
  7. ςετϑΝʔετ͕ͩ ςετۦಈ։ൃͰͳ͍ྫ  ໰୊఺ ᶃࣦഊ͢ΔςετΛॻ͘ ᶄςετ͕௨Δγϯϓϧ ͳίʔυΛॻ͘ ᶅϦϑΝΫλϦϯά͠ ͯίʔυΛ៉ྷʹ͢Δ ϑΟʔυόοΫͷܽ೗

  8. ςετϑΝʔετ͕ͩ ςετۦಈ։ൃͰͳ͍ྫ  ࣄલʹઃܭ͠ա͗Δ class FooTest { def testDoFoo() {

    } } class BarTest { def testDoBar() { } }
  9. ςετϑΝʔετ͕ͩ ςετۦಈ։ൃͰͳ͍ྫ  ໰୊఺ ᶃࣦഊ͢ΔςετΛॻ͘ ᶄςετ͕௨Δγϯϓϧ ͳίʔυΛॻ͘ ᶅϦϑΝΫλϦϯά͠ ͯίʔυΛ៉ྷʹ͢Δ ϧʔϓ͸ճΔ͕ޮՌ͕ݮΔ

  10. #%6' ࣄલͷઃܭΛ΍Γա͗Δͱ ޡͬͨઃܭ΍ա৒ઃܭΛੜΉ #JH%FTJHO6Q'SPOU

  11. αϯΫίετ ઌʹίετΛ෷ͬͯߦͬͨઃܭ͸ ࣺͯͮΒ͍ʢଛ੾ΓͰ͖ͳ͍ʣ 4VOL$PTU

  12. 2 5%%Ͱ͸ࣄલઃܭ͸͠ͳ͍ͷʁ

  13. " ඞཁͳΒɺखॻ͖ͷϥϑεέον ΍$3$ͳͲखܰʹ࡞੒Ͱ͖ࣺͯͯ ΍͍͢πʔϧΛ࢖͏

  14. ʮͳΜͱͳ͘ཧղ͸Ͱ͖͚ͨͲ ۩ମతʹͲ͏΍ͬͯ5%%Λ ਐΊ͍͍͔ͯΘ͔Βͳ͍ʯ

  15. ͱͯ΋ྑ͍ྫ͕͋Γ·ͨ͠ʂ

  16. ʲୈষʳ ϓϩάϥϛϯά Τϐιʔυ

  17. Ϙ΢ϦϯάͷείΞूܭ ΞϓϦέʔγϣϯΛ5%% Ͱ։ൃ͢Δαϯϓϧ 4 5 1 5 14 4 29

    6 6 133 2 49 5 60 1 61 0 77 7 97 6 117
  18. w ౤ٿॱʹ౗ͨ͠ϐϯ਺Λه࿥͢Δ w ࢦఆͨ͠ϑϨʔϜʹ͓͚ΔείΞΛܭࢉ Ͱ͖Δ w ࠷৽ͷείΞΛܭࢉͰ͖Δʢશͯͷ౤ٿ ͕׬͍ྃͯ͠Ε͹ɺ࠷ऴతͳείΞʣ 4 5

    1 5 14 4 29 6 6 133 2 49 5 60 1 61 0 77 7 97 6 117 ৼΔ෣͍ʢΞϓϦέʔγϣϯ࢓༷ʣ
  19. ࣄલઃܭʢϥϑεέονʣ

  20. Ϙϒ͓͡͞Μͱಉ྅͕ ϖΞϓϩͰḷͬͨಓے

  21. w ςετ͢΂͖5ISPXͷৼ෣͍͕ݟ͍ͩͤͣɺ 'SBNFͷςετ͔Βॻ͖࢝Ίͨɻ w ࠷΋୯७ͳςετέʔε͔Β࢝Ίɺ࠷΋୯७ͳ ࣮૷ͰςετΛ௨͢ɻ ࠷ॳͷςετέʔε public class Frame

    { public int getScore() { return 0 ; } } class FrameSpec extends Specification { def "ະ౤ٿͷͱ͖ͷείΞ͸0Ͱ͋Δ"() { given : def f = new Frame( ) when : def score = f.getScore( ) then : score == 0 } } ˞ॻ੶Ͱ͸+6OJUΛ࢖͍ͬͯΔ ͕ɺຊࢿྉͰ͸4QPDLΛ࢖༻
  22. w ࣍ʹ୯७ͳςετέʔεΛ௥Ճ͠ɺςετ͕௨ ΔΑ͏ʹίʔυΛमਖ਼͢Δ ࣍ͷςετέʔε class FrameSpec extends Specification { ..

    def "1ճ౤ٿͨ͠ͱ͖ʹείΞ͕ਖ਼͍͠"() { given : def f = new Frame( ) when : f.add(5 ) then : f.getScore() == 5 } } public class Frame { private int itsScore = 0 ; public int getScore() { return itsScore ; } public void add(int pins) { itsScore += pins ; } }
  23. ग़ͩ͠͸ॱௐʂ

  24. w εϖΞ΍ετϥΠΫΛग़ͨ͠৔߹ɺϑϨʔϜͷ είΞܭࢉʹ͸ޙଓͷϑϨʔϜͷ৘ใ͕ඞཁɻ w (BNFΦϒδΣΫτ͸'SBNFΛϦϯΫϦετͰ ؅ཧ͢΂͖ʁ w 'SBNFͷ࡞ۀΛதஅͯ͠ɺ(BNFͷ࡞ۀʹ੾Γ ସ͑Δɻ ෳ਺ճ౤ٿͨ͠৔߹ʁ

  25. (BNFͷ࣮૷Λগͣͭ͠ਐΊΔ class GameSpec extends Specification { when : g.add(5 )

    g.add(4 ) g.add(7 ) g.add(2 ) then : g.score() == 1 8 g.scoreForFrame(1) == 9 g.scoreForFrame(2) == 1 8 } public class Game { private int itsScore = 0 ; private int[] itsThrows = new int[21] ; private int itsCurrentThrow = 0 ; public int score() { return itsScore ; } public void add(int pins) { itsThrows[itsCurrentThrow++] = pins ; itsScore += pins ; } public int scoreForFrame(int frame) { int score = 0 ; for (int ball = 0; frame > 0 && (ball < itsCurrentThrow) ; ball += 2, frame--) { score += itsThrows[ball] + itsThrows[ball + 1] ; } return score ; } }
  26. lίʔυ͕ͦΕΛඞཁͩͱ ओு͠ͳ͍ݶΓɺϦϯΫϦετ͸ ༻ҙͨ͘͠ͳ͍Μͩz

  27. w ୯ͳΔ഑ྻͰ༻Λ଍͢ͳΒɺͦΕͰ0, w ઃܭ্ͷ൑அΛ஗ΒͤΔ γϯϓϧͳઃܭΛબ୒͠Α͏ public class Game { private

    int itsScore = 0 ; private int[] itsThrows = new int[21] ; private int itsCurrentThrow = 0 ;
  28. w ςετ͕͋Δ͔Β҆৺ϦϑΝΫλϦϯά ৗʹϦϑΝΫλϦϯά͠Α͏ public int scoreForFrame(int frame) { int score

    = 0 ; for (int ball = 0; frame > 0 && (ball < itsCurrentThrow) ; ball += 2, frame--) { score += itsThrows[ball] + itsThrows[ball + 1] ; } return score ; } public int scoreForFrame(int theFrame) { int ball = 0 ; int score = 0 ; for (int currentFrame = 0; currentFrame < theFrame ; currentFrame++) { int firstThrow = itsThrows[ball++] ; int secondThrow = itsThrows[ball++] ; score += firstThrow + secondThrow ; } return score ; }
  29. w εϖΞΛग़ͨ͠ͱ͖ w ετϥΠΫΛग़ͨ͠ͱ͖ w ύʔϑΣΫτήʔϜ w ϦΞϧͳαϯϓϧ w ΤοδέʔεʢύʔϑΣΫτήʔϜະ਱ͳͲʣ

    ઴ਐతʹ(BNFͷ࣮૷ΛਐΊΔ 4 5 1 5 14 4 29 6 6 133 2 49 5 60 1 61 0 77 7 97 6 117
  30. w શͯͷςετέʔε͕௨ΓɺΞϓϦέʔγϣϯ ͷৼΔ෣͍͕׬੒͕ͨ͠ɺϦϑΝΫλϦϯά͸ ଓ͍͍ͯ͘ɻ w 4DPSFSΦϒδΣΫτͷඞཁੑΛ೏Θͤͳ͕ Βɺͪ͝Ό͍ͭͨίʔυΛ͖Ε͍ʹ͍ͯ͘͠ɻ ͞ΒͳΔϦϑΝΫλϦϯά

  31. if (strike()) { score += 10 + nextTwoBallsForStrike() ; ball++

    ; } else if (spare()) { score += 10 + nextBallForSpare() ; ball+=2 ; } else { score += handleSecondThrow() ; } l͜ͷTDPSF'PS'SBNFؔ਺Λݟͯ͝ΒΜΑʂ ͜Εͦ͜Ϙ΢ϦϯάͷϧʔϧΛ͖ΘΊͯ؆ܿ ʹهड़ͨ࢟ͩ͠Αʂz
  32. ׬੒ܗ l͜ΕͰɺ(BNF͸ϑϨʔϜͷ؅ཧ͚ͩΛͯ͠ɺ 4DPSFS͸είΞͷܭࢉ͚ͩΛ୲౰͢Δਤࣜʹͳͬ ͨͶɻ͜Εͧɺ୯Ұ੹೚ͷݪଇʢ431ʣͩʂz

  33. ͲͪΒͷઃܭ͕͙͢Ε͍ͯΔ͔ʁ if (strike()) { score += 10 + nextTwoBallsForStrike() ;

    ball++ ; } else if (spare()) { score += 10 + nextBallForSpare() ; ball+=2 ; } else { score += handleSecondThrow() ; } ࣄલͷઃܭ 5%%ʹΑΔઃܭ
  34. ద੾ͳϞσϦϯά ࣮ੈքͷ֓೦ߏ଄Λ஧࣮ʹղܾྖ Ҭʹ࠶ݱ͢Δ͜ͱ͕͍ͭ΋ਖ਼͍͠ ͱ͸ݶΒͳ͍

  35. ٙ໰ 4DPSFS͸ςετ͠ͳ͍ͷʁ

  36. ϢχοτςετͷʮϢχοτʯ lϢχοτͱ͸;Δ·͍ͷ୯ Ґɺͭ·Γಠཱͨ͠ݕূՄ ೳͳ;Δ·͍ͷ͜ͱͩz

  37. ৼ෣͍ͷू߹ମΛςετ͢Δ l͋ΒΏΔ؍࡯Մೳͳ;Δ· ͍͕ɺͦΕʹඥͮ͘ςετ Λ࣋ͭ΂͖Ͱ͋Δ͜ͱΛҙ ຯ͢Δɻz

  38. ৼΔ෣͍ͷू߹ମͷϑΝαʔυͰ ͋Δ(BNFΛςετ͢Ε͹0,

  39. ࣮ࡍɺΧόϨοδ΋໰୊ͳ͔ͬͨ

  40. w 5%%ͷαΠΫϧͰ(BNFͷৼ෣͍Λશ࣮ͯ૷͠ ͨޙɺϦϑΝΫλϦϯάͰ4DPSFSΛநग़ɻ w (BNF4QFDͰৼ෣͍Λݻఆ͢Δ͜ͱͰɺϦ ϑΝΫλϦϯάΛߦ͏͜ͱ͕Ͱ͖ͨɻ Ϙϒ͓͡͞Μୡ͕ḷͬͨ࿏

  41. w ॻ੶ͷதͰϘϒ͓͡͞Μୡ͕ḷͬͨ࿏ΛɺԾʹ ηΠόʔϧʔτͱݺͿʢ࣭໰͸ड͚෇͚ͳ͍ʣ 5%%ͷϧʔτ͸Ұͭͱ͸ݶΒͳ͍

  42. w 4DPSFSͷඞཁੑ͕ݟ͑ͨஈ֊Ͱ4DPSFS4QFD Λ࡞੒͠ɺ5%%Ͱ4DPSFSΛઌʹ࢓্͛Δɻ w ΠϯαΠυΞ΢τʢϘτϜΞοϓʣɻ ႒ϧʔτ

  43. w 4DPSFSͷඞཁੑ͕ݟ͑ͨΒɺ4DPSFSͷϞοΫ Λ࢖ͬͯ(BNFͷ࣮૷ΛਐΊ͍ͯ͘ɻ w Ξ΢ταΠυΠϯʢτοϓμ΢ϯʣɻ ࡩϧʔτ

  44. ϞοΫΛ࢖ͬͨςετ private Game g private Scorer s def setup() {

    s = Mock() // ScorerͷϞοΫ g = new Game(s ) } def "2ճ౤ٿͨ͠ͱ͖ͷείΞ͕ਖ਼͍͠"() { when : g.add(5 ) g.add(4 ) def score = g.score( ) then : score == 9 1 * s.addThrow(5 ) 1 * s.addThrow(4 ) 1 * s.scoreForFrame(2) >> 9 } ؒ઀ೖྗ ؒ઀ग़ྗ ʨ ૬ޓ࡞༻ͷݕূ
  45. w (BNFΛपΓ͔Βಠཱͯ͠ςετͰ͖Δɻ w 4DPSFSͷ࣮૷͕ͳ͍࣌఺Ͱɺઌʹ(BNFΛςε τͰ͖Δɻ w ϞοΫΛܦ༝͠ɺؒ઀ೖྗ΍ؒ઀ग़ྗΛ࢖ͬͯ (BNFͷৼ෣͍΍ঢ়ଶΛνΣοΫͰ͖Δɻ w (BNFͱ4DPSFSͷ૬ޓ࡞༻ΛδϟετΠϯλΠ

    ϜͰઃܭͰ͖Δɻ ϞοΫΞϓϩʔνͷϝϦοτ
  46. w ࣮૷ͷৄࡉʹґଘ͢ΔͨΊɺ੬͍ςετͱͳΓ ΍͍͢ɻ w ॻ͘ͷʹख͕͔͔ؒΔɻ w (BNF 4DPSFSʢৼ෣͍ͷू߹ମʣʹର͢Δ ςετ΋ผ్ॻ͘ඞཁ͕͋Δɻ ϞοΫΞϓϩʔνͷσϝϦοτ

  47. w ϞοΫΛ࢖ͬͯॻ͍ͨ(BNF4QFD͸͋͘·Ͱ ઃܭΛਐΊΔҰ࣌తͳಓ۩ͱߟ͑ɺࣺͯͯΑ͠ ʢৼ෣͍ͷू߹ମʹର͢Δςετ͕࢒Ε͹Մʣ ઃܭͷͨΊ͚ͩͷςετίʔυ

  48. ·ͱΊ

  49. 5%%ͷຊ࣭͸ɺ ϨουάϦʔϯϦϑΝΫλϦϯά ͷαΠΫϧͰߦ͏ δϟετΠϯλΠϜͷઃܭͰ͋Δ

  50. Ϣχοτςετͷ୯Ґ͸ ৼ෣͍ͷू߹ମͱ͠Α͏

  51. ʰΞδϟΠϧιϑτ΢ΣΞ։ൃͷ ԞٛʱষΛࣸܦͯ͠Έ·͠ΐ͏

  52. ʰΞδϟΠϧιϑτ΢ΣΞ։ൃͷԞٛୈ̎൛ʱ ϩόʔτɾ$ɾϚʔνϯஶ4#ΫϦΤΠςΟϒץ   ʰϨΨγʔίʔυ͔Βͷ୤٫ʱ %BWJE4DPUU#FSOTUFJOஶΦϥΠϦʔɾδϟύϯץ  ࢀߟจݙ