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

XUTPから学ぶ記述性の高いユニットテスト 〜俺たちを助けるユニットテストへ〜 / xUTP in #xpjug

PoohSunny
September 15, 2017

XUTPから学ぶ記述性の高いユニットテスト 〜俺たちを助けるユニットテストへ〜 / xUTP in #xpjug

XP祭り2017での発表資料です。
http://xpjug.com/xp2017/

PoohSunny

September 15, 2017
Tweet

More Decks by PoohSunny

Other Decks in Technology

Transcript

  1. XUTP͔ΒֶͿ
    هड़ੑͷߴ͍
    Ϣχοτςετ
    ʙԶͨͪΛॿ͚ΔϢχοτςετ΁ʙ
    ߴڮཅଠ࿠(a.k.a. @PoohSunny)
    1

    View Slide

  2. ߴڮ ཅଠ࿠(@PoohSunny)
    {
    team: ["͸ͨΒ͍͘", "ͱΒ͹ʔΏ"],
    role: "Engineer team leader",
    lang: ["Java", "Groovy", "Swift"]
    }
    2

    View Slide

  3. εϥΠυ͸
    ެ։ࡁΈͰ͢
    3

    View Slide

  4. QCDͷτϨʔυΦϑͳΜͯ
    ຊ౰͸ͳ͔ͬͨΜͩ1
    1 http://i2key.hateblo.jp/entry/2017/05/15/082655
    4

    View Slide

  5. ࣗಈςετͩͬͯҰॹ2
    2 http://xunitpatterns.com/Goals%20of%20Test%20Automation.html
    5

    View Slide

  6. ςετ
    ॻ͍ͯ·͔͢ʔʁ
    6

    View Slide

  7. ʮ্खʹʯ
    ςετ
    ॻ͍ͯ·͔͢ʔʁ
    7

    View Slide

  8. ΄Μ·͢·Μ͔ͬͨ
    class WorkingTimeCalculatorTest {
    @Test
    void ਖ਼ৗܥͷςετ() throws Exception {
    // (ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    8

    View Slide

  9. xUTPͱͷग़ձ͍
    9

    View Slide

  10. ਺೥ޙ3
    3 photo: https://www.flickr.com/photos/daverusso88/20860542330/in/photolist-
    xMnJsW-8H8jnW-8BDdLz-fS9XhN-e3qtWG-oaibHC-eRMCCx-q9Ftni-n7Lmvm-supyFV-gXyxGZ-
    fEKqSK-sqqxce-sfR8k1-q7N9Ta-dDw4Zq-9ML2MP-oa6sWm-J5F4zN-4vX6LP-nW3r1Q-
    rF4QJJ-8BWJj9-A1MjG7-sqqpKR-HgcdWN-7Dy6QC-s7M3Dn-w2RjN3-TZXibu-mMD2tR-o9TZi6-
    shS8mE-hWRzr-WJPkXw-xe6Rnv-DWz4Ra-yGju6j-fkfg3o-ghz6JD-wR4HYP-7xhvzK-rN2UEW-
    krfJu3-Duju1z-FSwQ8h-8yNSK2-4vXc2a-DaLuo5-zZyYuS
    10

    View Slide

  11. xUTPͱͷग़ձ͍(෺ཧ)4
    4 ಈը: https://engineers.sg/video/unit-test-craftsmanship-agile-singapore-
    conference-2016--1168
    εϥΠυ: http://singapore2016.xunitpatterns.com/
    11

    View Slide

  12. xUTPͷྗΛआΓͯ
    ςετΛୟ͖௚͢
    12

    View Slide

  13. ͳΜͷͨΊͷ
    ςετࣗಈԽʁ
    13

    View Slide

  14. ςετͷʮ΂͖ʯ࿦
    • ςετ͸[඼࣭޲্, SUTͷཧղ, ϦεΫݮগ]Λ
    ॿ͚Δ
    • ςετ͸[࣮ߦ, ϝϯςφϯε, هड़]͕༰қ5
    5 http://xunitpatterns.com/Goals%20of%20Test%20Automation.html͔Βཁ໿
    14

    View Slide

  15. هड़
    ཧղ
    ϝϯςφϯε
    15

    View Slide

  16. ·ͣ΍Δ͜ͱ
    class WorkingTimeCalculatorTest {
    @Test
    void ਖ਼ৗܥͷςετ() throws Exception {
    // (ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    16

    View Slide

  17. ͜Εͳʹͯ͠Δͷʁ
    class WorkingTimeCalculatorTest {
    @Test
    void ਖ਼ৗܥͷςετ() throws Exception {
    // (ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    17

    View Slide

  18. ཧղʢղಡʣ͠Α͏
    ͜ͷίʔυͬͯɺͦͷ೔ͷۈ຿࣌ؒΛೖΕͯɺ࿑
    ಇ࣌ؒͱٳܜ࣌ؒΛܭࢉͯ͘͠ΕΔϝιουͳΜ
    ͩΑͶɻ
    ͜ͷςετͩͱɺҰ೔ೋճۈ຿͢Δ΍͔ͭͩΒɺ
    ࢝ۀबۀ࣌ؒΛෳ਺ೖΕͯςετͯ͠ΔͶɻٳܜ
    ͸ෳ਺ճܭࢉ͞ΕͯΔͶɻ
    — ϓϩμΫτઋਓ
    18

    View Slide

  19. ۈ຿࣌ؒͱٳܜ࣌ؒͷ
    ܭࢉςετΛ͍ͯ͠Δ
    19

    View Slide

  20. ͳʹΛͯ͠Δͷ͔Λ
    ςετ໊ʹ൓өͤ͞Δ
    class WorkingTimeCalculatorTest {
    @Test
    void ۈ຿࣌ؒͱٳܜ࣌ؒͷܭࢉςετ_ਖ਼ৗܥ() throws Exception {
    20

    View Slide

  21. ໊લΛͳΔ΂͘۩ମతʹ
    class WorkingTimeCalculatorTest {
    @Test
    void _1೔ෳ਺ճۈ຿ͨ࣌͠ͷ_ۈ຿࣌ؒͱٳܜ࣌ؒͷܭࢉ() throws Exception {
    21

    View Slide

  22. with JUnit5!
    class WorkingTimeCalculatorTest {
    @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void workingTimeCalculation() throws Exception {
    22

    View Slide

  23. ߏ଄Խ͍ͯ͠ͳ͍
    class WorkingTimeCalculatorTest {
    @DisplayName("1೔ʹෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void workingTimeCalculationTest() throws Exception {
    // (ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    23

    View Slide

  24. ஈམΘ͚Λ͠Α͏
    24

    View Slide

  25. 4 phase test6
    6 http://singapore2016.xunitpatterns.com/
    25

    View Slide

  26. ߏ଄Խ͍Ζ͍Ζ
    4 phase 3A7 BDD Spock
    setup arrange given given
    exercise act when -
    verify assert then expect
    teardown - - -
    7 http://xp123.com/articles/3a-arrange-act-assert/
    26

    View Slide

  27. Given-When-Then
    class WorkingTimeCalculatorTest {
    @DisplayName("1೔ʹෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void workingTimeCalculationTest() throws Exception {
    // given
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    // when
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    // then
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    27

    View Slide

  28. Given
    // given
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    28

    View Slide

  29. When
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    29

    View Slide

  30. Then
    // then
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    30

    View Slide

  31. Ͳ͔͜Βݟ͍ͯ͘ʁ
    • ͍ΖΜͳͱ͜ΖΛߦͬͨΓདྷͨΓ
    • ݸਓతʹ͸·ͣ͸Then͔Β
    31

    View Slide

  32. ෳ਺ͷΞαʔγϣϯ
    // then
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    32

    View Slide

  33. ໰୊఺
    • ΞαʔγϣϯϧʔϨοτ8
    • ͲΕ͕མͪͨͷ͔Θ͔Βͳ͍
    8 http://xunitpatterns.com/Assertion%20Roulette.html
    33

    View Slide

  34. ରࡦ: γϯάϧΞαʔγϣϯ9
    • ࿑ಇ࣌ؒܭࢉͷςετ
    // then
    assertEquals(720, result.getWorkTime());
    • ٳܜ࣌ؒܭࢉͷςετ
    // then
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    9 http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Single Condition Test
    34

    View Slide

  35. ·ͱΊ͓͍ͯͨํ͕
    Θ͔Γ΍ͦ͢͏
    // then
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    35

    View Slide

  36. ಡΈ΍͍͢ܗʹ
    ϦϑΝΫλϦϯά
    • ྫ͑͹JUnit5 + AssertJΛར༻
    // then
    List breakTimeList = result.getBreakTimeList();
    assertThat(breakTimeList).hasSize(2).containsExactly(60, 45);
    36

    View Slide

  37. ΧελϜΞαʔγϣϯ10
    • ϔϧύʔΛ࡞੒͠ɺΞαʔγϣϯͷ࣮ॲཧ͸ͦ
    ͪΒʹҠಈ
    10 http://xunitpatterns.com/Custom%20Assertion.html
    37

    View Slide

  38. ϝιου೔ຊޠԽ΋ख
    // then
    List breakTimeList = result.getBreakTimeList();
    ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList,
    _1ͭ໨ͷܭࢉ࣌ؒ͸(60),
    _2ͭ໨ͷܭࢉ࣌ؒ͸(45));
    38

    View Slide

  39. ϝϯςφϯεੑ͕٘ਜ਼ʹͳ
    Δʁ
    • ςετͷڞ௨ԽͬͯͲΕ΄Ͳॏཁʁ
    • ͜ΕʹΑͬͯͲͷ͘Β͍ಡΈ΍͕͢͞૿͢ʁ
    39

    View Slide

  40. ಡΈ΍͘͢ͳΒͳ͍Α͏ͳΒ
    ΋͠ಡΈ΍͘͢ͳΒͳ͍ͳΒɺγϯάϧΞαʔγ
    ϣϯਥʹͳΔͭ΋Γ͸ͳ͍Α
    — Principle: Verify One Condition per Test 11
    11 http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Single Condition Test
    ΑΓҙ༁
    40

    View Slide

  41. Then͸׬ྃ
    // given
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    // when
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    // then
    List breakTimeList = result.getBreakTimeList();
    ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList,
    _1ͭ໨ͷܭࢉ࣌ؒ͸(60),
    _2ͭ໨ͷܭࢉ࣌ؒ͸(45));
    41

    View Slide

  42. ଓ͍ͯWhen
    // when
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    42

    View Slide

  43. ϦϑϨΫγϣϯʁ
    // when
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    43

    View Slide

  44. ςετର৅ͷprivateʹհೖ͠
    ͍ͨ
    • ର৅ϝιουΛσϑΥϧτείʔϓʹ
    • Test-Specific SubclassΛར༻
    44

    View Slide

  45. Test-Specific Subclass12
    • ςετ༻ʹSUTͷαϒΫϥεΛ࡞੒͢Δ
    • Javaͩͱର৅ϝιουΛprotectedʹ
    12 http://xunitpatterns.com/Test-Specific%20Subclass.html
    45

    View Slide

  46. Test-Specific Subclass12
    // ςετ಺ʹϔϧύʔͱͯ͠
    class WorkingCaluculatorForTest extends WorkingCaluculator {
    public calucuation() {
    super.caluculation();
    }
    }
    // ςετଆ͸ݺͿ͚ͩ
    workingCalculator.calucuation();
    12 http://xunitpatterns.com/Test-Specific%20Subclass.html
    46

    View Slide

  47. When׬ྃ
    class WorkingTimeCalculatorTest {
    @DisplayName("1೔ʹෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void workingTimeCalculationTest() throws Exception {
    // given
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    // when
    workingCalculator.calucuation();
    CalculationResult result = target.getCaluculationResult();
    // then
    List breakTimeList = result.getBreakTimeList();
    ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList,
    _1ͭ໨ͷܭࢉ࣌ؒ͸(60),
    _2ͭ໨ͷܭࢉ࣌ؒ͸(45));
    }
    }
    47

    View Slide

  48. ࠷ޙʹGiven
    // given
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    48

    View Slide

  49. ࣅͨΑ͏ͳσʔληοτ
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    49

    View Slide

  50. ͦ΋ͦ΋͜ͷςετʹඞཁͳ
    ৘ใʁ
    ͜ͷςετͩͱɺҰ೔ೋճۈ຿͢Δ΍͔ͭͩΒɺ
    ࢝ۀबۀ࣌ؒΛͦΕͧΕೖΕͯΔͶɻ
    — ϓϩμΫτઋਓ
    50

    View Slide

  51. Creation Method13
    13 http://xunitpatterns.com/Creation%20Method.html
    51

    View Slide

  52. Creation Methodʹͯ͠
    ෆཁ৘ใΛӅṭ
    LocalDateTime workingStartTime1 = createFirstWorkStartTime();
    LocalDateTime workingEndTime1 = createFirstWorkEndTime();
    LocalDateTime workingStartTime2 = createSecondWorkStartTime();
    LocalDateTime workingEndTime2 = createSecondWorkEndTime();
    52

    View Slide

  53. ೔ຊޠʹ͢Δͷ΋ΞϦ
    LocalDateTime ࠷ॳͷۈ຿ͷ։࢝࣌ؒ = ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ࠷ॳͷۈ຿ͷऴྃ࣌ؒ = ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒ = ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒ = ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    53

    View Slide

  54. Given
    // given(ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime ࠷ॳͷۈ຿ͷ։࢝࣌ؒ = ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ࠷ॳͷۈ຿ͷऴྃ࣌ؒ = ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒ = ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒ = ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    54

    View Slide

  55. Ϣʔβʔͷ࡞੒΋
    // given(ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    ܖ໿಺༰Λ࡞੒Λ໌ࣔ͢Δඞཁ͸ͳ͍
    // given
    User ਖ਼ࣾһͷϢʔβʔ = ਖ਼ࣾһͷϢʔβʔͷ࡞੒();
    55

    View Slide

  56. Ұ࣌ม਺ඞཁʁ
    // given
    User ਖ਼ࣾһͷϢʔβʔ = ਖ਼ࣾһͷϢʔβʔͷ࡞੒();
    LocalDateTime ࠷ॳͷۈ຿ͷ։࢝࣌ؒ = ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ࠷ॳͷۈ຿ͷऴྃ࣌ؒ = ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒ = ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒();
    LocalDateTime ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒ = ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒();
    WorkingTimeCalculator target = new WorkingTimeCalculatorForTest(ਖ਼ࣾһͷϢʔβʔ,
    ࠷ॳͷۈ຿ͷ։࢝࣌ؒ,
    ࠷ॳͷۈ຿ͷऴྃ࣌ؒ,
    ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒ,
    ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒ);
    56

    View Slide

  57. Ұ࣌ม਺Λফڈ
    // given
    WorkingTimeCalculator target = new WorkingTimeCalculatorForTest(
    ਖ਼ࣾһͷϢʔβʔͷ࡞੒(),
    ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒());
    57

    View Slide

  58. implicit setup14
    class WorkingTimeCalculatorTest {
    WorkingTimeCalculator target = null;
    @BeforeEach
    void WorkingTimeCalculatorͷ࡞੒() {
    // given
    target = new WorkingTimeCalculatorForTest(
    ਖ਼ࣾһͷϢʔβʔͷ࡞੒(),
    ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒());
    }
    @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    14 http://xunitpatterns.com/Implicit%20Setup.html
    58

    View Slide

  59. ׬੒
    class WorkingTimeCalculatorTest {
    WorkingTimeCalculator target = null;
    @BeforeEach
    void WorkingTimeCalculatorͷ࡞੒() {
    // given
    target = new WorkingTimeCalculatorForTest(
    ਖ਼ࣾһͷϢʔβʔͷ࡞੒(),
    ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(),
    ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒());
    }
    @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void breakTimeCalculation() throws Exception {
    // when
    workingCalculator.calucuation();
    CalculationResult result = target.getCaluculationResult();
    // then
    List breakTimeList = result.getBreakTimeList();
    ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList,
    _1ͭ໨ͷܭࢉ࣌ؒ͸(60),
    _2ͭ໨ͷܭࢉ࣌ؒ͸(45));
    }
    }
    59

    View Slide

  60. ࠷ॳͷ࣌ͱൺֱ͢Δͱ
    class WorkingTimeCalculatorTest {
    @Test
    void ਖ਼ৗܥͷςετ() throws Exception {
    // (ུ)
    Contract contract = new Contract();
    User targetUser = new User(contract);
    LocalDateTime workingStartTime1 = LocalDateTime.of(2017, 9, 1, 10, 00);
    LocalDateTime workingEndTime1 = LocalDateTime.of(2017, 9, 1, 18, 00);
    LocalDateTime workingStartTime2 = LocalDateTime.of(2017, 9, 1, 22, 00);
    LocalDateTime workingEndTime2 = LocalDateTime.of(2017, 9, 2, 4, 00);
    WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser,
    workingStartTime1,
    workingEndTime1,
    workingStartTime2,
    workingEndTime2);
    Class c = WorkingTimeCalculator.class;
    Method m = c.getDeclaredMethod("calculation", null);
    m.setAccessible(true);
    m.invoke(target, null);
    CalculationResult result = target.getCaluculationResult();
    assertEquals(720, result.getWorkTime());
    List breakTimeList = result.getBreakTimeList();
    assertEquals(2, breakTimeList.size());
    assertEquals(60, breakTimeList[0]);
    assertEquals(45, breakTimeList[1]);
    }
    }
    60

    View Slide

  61. ಡΈ΍͘͢ͳͬͨ
    @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰")
    @Test
    void breakTimeCalculation() throws Exception {
    // when
    workingCalculator.calucuation();
    CalculationResult result = sut.getCaluculationResult();
    // then
    List breakTimeList = result.getBreakTimeList();
    ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList,
    _1ͭ໨ͷܭࢉ࣌ؒ͸(60),
    _2ͭ໨ͷܭࢉ࣌ؒ͸(45));
    61

    View Slide

  62. One more thing
    • ςετର৅ΛSUT(System Under Test)ͱهड़
    ͢Δͷ͸xUTPจԽ15
    CalculationResult result = sut.getCaluculationResult();
    15 http://xunitpatterns.com/SUT.html
    62

    View Slide

  63. ·ͱΊʹ͔͑ͯ
    63

    View Slide

  64. ͜͜·Ͱ
    ΍͖ͬͯͨ͜ͱ
    ʮಡΈ΍͍͢ʯ
    ςετࢤ޲
    64

    View Slide

  65. ಡΈ΍͍͢ςετ
    • ॻ͖΍͍͢
    • ཧղ͠΍͍͢
    • ϝϯςφϯε͕༰қ
    65

    View Slide

  66. xUTPͰಡΈ΍͍͢
    ςετΛ
    66

    View Slide

  67. ಡΈ΍͢͞Λຯํ
    ʹ͚ͭͯ͋ͳͨΛ
    ॿ͚ΔςετΛ
    67

    View Slide

  68. ͓͠·͍
    68

    View Slide