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

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

yonetty
February 16, 2021

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

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

yonetty

February 16, 2021
Tweet

More Decks by yonetty

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. ςετۦಈ։ൃ
    5FTU%SJWFO%FWFMPQNFOU
    ςετίʔυΛಓ۩ʹ

    ͯ͠ɺ։ൃΛճ͢͜ͱ

    View Slide

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

    View Slide

  6. ςετϑΝʔετ͕ͩ
    ςετۦಈ։ൃͰͳ͍ྫ

    ઌʹ͢΂ͯͷςετίʔυΛॻ͘
    class FooTest
    {

    def testFoo1() {
    }

    def testFoo2() {
    }

    def testFoo3() {
    }

    def testFoo4() {
    }



    }
    class Foo
    {

    // ͜Ε͔Β࣮૷
    }

    View Slide

  7. ςετϑΝʔετ͕ͩ
    ςετۦಈ։ൃͰͳ͍ྫ
    ໰୊఺
    ᶃࣦഊ͢ΔςετΛॻ͘
    ᶄςετ͕௨Δγϯϓϧ
    ͳίʔυΛॻ͘
    ᶅϦϑΝΫλϦϯά͠
    ͯίʔυΛ៉ྷʹ͢Δ
    ϑΟʔυόοΫͷܽ೗

    View Slide

  8. ςετϑΝʔετ͕ͩ
    ςετۦಈ։ൃͰͳ͍ྫ

    ࣄલʹઃܭ͠ա͗Δ
    class FooTest
    {

    def testDoFoo() {
    }

    }

    class BarTest
    {

    def testDoBar() {
    }

    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. Ϙ΢ϦϯάͷείΞूܭ
    ΞϓϦέʔγϣϯΛ5%%
    Ͱ։ൃ͢Δαϯϓϧ
    4
    5
    1 5
    14
    4
    29
    6 6
    133
    2
    49
    5
    60
    1
    61
    0
    77
    7
    97
    6
    117

    View Slide

  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
    ৼΔ෣͍ʢΞϓϦέʔγϣϯ࢓༷ʣ

    View Slide

  19. ࣄલઃܭʢϥϑεέονʣ

    View Slide

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

    View Slide

  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Λ࢖༻

    View Slide

  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
    ;

    }

    }

    View Slide

  23. ग़ͩ͠͸ॱௐʂ

    View Slide

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

    View Slide

  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
    ;

    }

    }

    View Slide

  26. lίʔυ͕ͦΕΛඞཁͩͱ
    ओு͠ͳ͍ݶΓɺϦϯΫϦετ͸
    ༻ҙͨ͘͠ͳ͍Μͩz

    View Slide

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

    private int itsScore = 0
    ;

    private int[] itsThrows = new int[21]
    ;

    private int itsCurrentThrow = 0
    ;

    View Slide

  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
    ;

    }

    View Slide

  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

    View Slide

  30. w શͯͷςετέʔε͕௨ΓɺΞϓϦέʔγϣϯ
    ͷৼΔ෣͍͕׬੒͕ͨ͠ɺϦϑΝΫλϦϯά͸
    ଓ͍͍ͯ͘ɻ
    w 4DPSFSΦϒδΣΫτͷඞཁੑΛ೏Θͤͳ͕
    Βɺͪ͝Ό͍ͭͨίʔυΛ͖Ε͍ʹ͍ͯ͘͠ɻ
    ͞ΒͳΔϦϑΝΫλϦϯά

    View Slide

  31. if (strike())
    {

    score += 10 + nextTwoBallsForStrike()
    ;

    ball++
    ;

    } else if (spare())
    {

    score += 10 + nextBallForSpare()
    ;

    ball+=2
    ;

    } else
    {

    score += handleSecondThrow()
    ;

    }
    l͜ͷTDPSF'PS'SBNFؔ਺Λݟͯ͝ΒΜΑʂ
    ͜Εͦ͜Ϙ΢ϦϯάͷϧʔϧΛ͖ΘΊͯ؆ܿ
    ʹهड़ͨ࢟ͩ͠Αʂz

    View Slide

  32. ׬੒ܗ
    l͜ΕͰɺ(BNF͸ϑϨʔϜͷ؅ཧ͚ͩΛͯ͠ɺ
    4DPSFS͸είΞͷܭࢉ͚ͩΛ୲౰͢Δਤࣜʹͳͬ
    ͨͶɻ͜Εͧɺ୯Ұ੹೚ͷݪଇʢ431ʣͩʂz

    View Slide

  33. ͲͪΒͷઃܭ͕͙͢Ε͍ͯΔ͔ʁ
    if (strike())
    {

    score += 10 + nextTwoBallsForStrike()
    ;

    ball++
    ;

    } else if (spare())
    {

    score += 10 + nextBallForSpare()
    ;

    ball+=2
    ;

    } else
    {

    score += handleSecondThrow()
    ;

    }
    ࣄલͷઃܭ 5%%ʹΑΔઃܭ

    View Slide

  34. ద੾ͳϞσϦϯά
    ࣮ੈքͷ֓೦ߏ଄Λ஧࣮ʹղܾྖ
    Ҭʹ࠶ݱ͢Δ͜ͱ͕͍ͭ΋ਖ਼͍͠
    ͱ͸ݶΒͳ͍

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    }

    ؒ઀ೖྗ
    ؒ઀ग़ྗ
    ʨ
    ૬ޓ࡞༻ͷݕূ

    View Slide

  45. w (BNFΛपΓ͔Βಠཱͯ͠ςετͰ͖Δɻ
    w 4DPSFSͷ࣮૷͕ͳ͍࣌఺Ͱɺઌʹ(BNFΛςε
    τͰ͖Δɻ
    w ϞοΫΛܦ༝͠ɺؒ઀ೖྗ΍ؒ઀ग़ྗΛ࢖ͬͯ
    (BNFͷৼ෣͍΍ঢ়ଶΛνΣοΫͰ͖Δɻ
    w (BNFͱ4DPSFSͷ૬ޓ࡞༻ΛδϟετΠϯλΠ
    ϜͰઃܭͰ͖Δɻ
    ϞοΫΞϓϩʔνͷϝϦοτ

    View Slide

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

    View Slide

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

    View Slide

  48. ·ͱΊ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  52. ʰΞδϟΠϧιϑτ΢ΣΞ։ൃͷԞٛୈ̎൛ʱ
    ϩόʔτɾ$ɾϚʔνϯஶ4#ΫϦΤΠςΟϒץ

    ʰϨΨγʔίʔυ͔Βͷ୤٫ʱ
    %BWJE4DPUU#FSOTUFJOஶΦϥΠϦʔɾδϟύϯץ

    ࢀߟจݙ

    View Slide