Save 37% off PRO during our Black Friday Sale! »

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

B765faf519f19520e1495bd870f4d7f0?s=47 PoohSunny
September 15, 2017

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

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

B765faf519f19520e1495bd870f4d7f0?s=128

PoohSunny

September 15, 2017
Tweet

Transcript

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

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

    lang: ["Java", "Groovy", "Swift"] } 2
  3. εϥΠυ͸ ެ։ࡁΈͰ͢ 3

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

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

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

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

  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 8
  9. xUTPͱͷग़ձ͍ 9

  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

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

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

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

  14. ςετͷʮ΂͖ʯ࿦ • ςετ͸[඼࣭޲্, SUTͷཧղ, ϦεΫݮগ]Λ ॿ͚Δ • ςετ͸[࣮ߦ, ϝϯςφϯε, هड़]͕༰қ5

    5 http://xunitpatterns.com/Goals%20of%20Test%20Automation.html͔Βཁ໿ 14
  15. هड़ ཧղ ϝϯςφϯε 15

  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 16
  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 17
  18. ཧղʢղಡʣ͠Α͏ ͜ͷίʔυͬͯɺͦͷ೔ͷۈ຿࣌ؒΛೖΕͯɺ࿑ ಇ࣌ؒͱٳܜ࣌ؒΛܭࢉͯ͘͠ΕΔϝιουͳΜ ͩΑͶɻ ͜ͷςετͩͱɺҰ೔ೋճۈ຿͢Δ΍͔ͭͩΒɺ ࢝ۀबۀ࣌ؒΛෳ਺ೖΕͯςετͯ͠ΔͶɻٳܜ ͸ෳ਺ճܭࢉ͞ΕͯΔͶɻ — ϓϩμΫτઋਓ 18

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

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

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

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

    Exception { 22
  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 23
  24. ஈམΘ͚Λ͠Α͏ 24

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

  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
  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 27
  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
  29. When WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser, workingStartTime1, workingEndTime1, workingStartTime2, workingEndTime2);

    Class<WorkingTimeCalculator> c = WorkingTimeCalculator.class; Method m = c.getDeclaredMethod("calculation", null); m.setAccessible(true); m.invoke(target, null); CalculationResult result = target.getCaluculationResult(); 29
  30. Then // then assertEquals(720, result.getWorkTime()); List<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2,

    breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); 30
  31. Ͳ͔͜Βݟ͍ͯ͘ʁ • ͍ΖΜͳͱ͜ΖΛߦͬͨΓདྷͨΓ • ݸਓతʹ͸·ͣ͸Then͔Β 31

  32. ෳ਺ͷΞαʔγϣϯ // then assertEquals(720, result.getWorkTime()); List<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2,

    breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); 32
  33. ໰୊఺ • ΞαʔγϣϯϧʔϨοτ8 • ͲΕ͕མͪͨͷ͔Θ͔Βͳ͍ 8 http://xunitpatterns.com/Assertion%20Roulette.html 33

  34. ରࡦ: γϯάϧΞαʔγϣϯ9 • ࿑ಇ࣌ؒܭࢉͷςετ // then assertEquals(720, result.getWorkTime()); • ٳܜ࣌ؒܭࢉͷςετ

    // then List<Integer> 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
  35. ·ͱΊ͓͍ͯͨํ͕ Θ͔Γ΍ͦ͢͏ // then List<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size());

    assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); 35
  36. ಡΈ΍͍͢ܗʹ ϦϑΝΫλϦϯά • ྫ͑͹JUnit5 + AssertJΛར༻ // then List<Integer> breakTimeList

    = result.getBreakTimeList(); assertThat(breakTimeList).hasSize(2).containsExactly(60, 45); 36
  37. ΧελϜΞαʔγϣϯ10 • ϔϧύʔΛ࡞੒͠ɺΞαʔγϣϯͷ࣮ॲཧ͸ͦ ͪΒʹҠಈ 10 http://xunitpatterns.com/Custom%20Assertion.html 37

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

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

  40. ಡΈ΍͘͢ͳΒͳ͍Α͏ͳΒ ΋͠ಡΈ΍͘͢ͳΒͳ͍ͳΒɺγϯάϧΞαʔγ ϣϯਥʹͳΔͭ΋Γ͸ͳ͍Α — Principle: Verify One Condition per Test

    11 11 http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Single Condition Test ΑΓҙ༁ 40
  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<WorkingTimeCalculator> c = WorkingTimeCalculator.class; Method m = c.getDeclaredMethod("calculation", null); m.setAccessible(true); m.invoke(target, null); CalculationResult result = target.getCaluculationResult(); // then List<Integer> breakTimeList = result.getBreakTimeList(); ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList, _1ͭ໨ͷܭࢉ࣌ؒ͸(60), _2ͭ໨ͷܭࢉ࣌ؒ͸(45)); 41
  42. ଓ͍ͯWhen // when WorkingTimeCalculator target = new WorkingTimeCalculator(targetUser, workingStartTime1, workingEndTime1,

    workingStartTime2, workingEndTime2); Class<WorkingTimeCalculator> c = WorkingTimeCalculator.class; Method m = c.getDeclaredMethod("calculation", null); m.setAccessible(true); m.invoke(target, null); CalculationResult result = target.getCaluculationResult(); 42
  43. ϦϑϨΫγϣϯʁ // when Class<WorkingTimeCalculator> c = WorkingTimeCalculator.class; Method m =

    c.getDeclaredMethod("calculation", null); m.setAccessible(true); m.invoke(target, null); 43
  44. ςετର৅ͷprivateʹհೖ͠ ͍ͨ • ର৅ϝιουΛσϑΥϧτείʔϓʹ • Test-Specific SubclassΛར༻ 44

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

  46. Test-Specific Subclass12 // ςετ಺ʹϔϧύʔͱͯ͠ class WorkingCaluculatorForTest extends WorkingCaluculator { public

    calucuation() { super.caluculation(); } } // ςετଆ͸ݺͿ͚ͩ workingCalculator.calucuation(); 12 http://xunitpatterns.com/Test-Specific%20Subclass.html 46
  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<Integer> breakTimeList = result.getBreakTimeList(); ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList, _1ͭ໨ͷܭࢉ࣌ؒ͸(60), _2ͭ໨ͷܭࢉ࣌ؒ͸(45)); } } 47
  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
  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
  50. ͦ΋ͦ΋͜ͷςετʹඞཁͳ ৘ใʁ ͜ͷςετͩͱɺҰ೔ೋճۈ຿͢Δ΍͔ͭͩΒɺ ࢝ۀबۀ࣌ؒΛͦΕͧΕೖΕͯΔͶɻ — ϓϩμΫτઋਓ 50

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

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

    createFirstWorkEndTime(); LocalDateTime workingStartTime2 = createSecondWorkStartTime(); LocalDateTime workingEndTime2 = createSecondWorkEndTime(); 52
  53. ೔ຊޠʹ͢Δͷ΋ΞϦ LocalDateTime ࠷ॳͷۈ຿ͷ։࢝࣌ؒ = ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(); LocalDateTime ࠷ॳͷۈ຿ͷऴྃ࣌ؒ = ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(); LocalDateTime

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

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

    = new User(contract); ܖ໿಺༰Λ࡞੒Λ໌ࣔ͢Δඞཁ͸ͳ͍ // given User ਖ਼ࣾһͷϢʔβʔ = ਖ਼ࣾһͷϢʔβʔͷ࡞੒(); 55
  56. Ұ࣌ม਺ඞཁʁ // given User ਖ਼ࣾһͷϢʔβʔ = ਖ਼ࣾһͷϢʔβʔͷ࡞੒(); LocalDateTime ࠷ॳͷۈ຿ͷ։࢝࣌ؒ =

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

    ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(), ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(), ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒()); 57
  58. implicit setup14 class WorkingTimeCalculatorTest { WorkingTimeCalculator target = null; @BeforeEach

    void WorkingTimeCalculatorͷ࡞੒() { // given target = new WorkingTimeCalculatorForTest( ਖ਼ࣾһͷϢʔβʔͷ࡞੒(), ࠷ॳͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(), ࠷ॳͷۈ຿ͷऴྃ࣌ؒΛ࡞੒(), ೋͭ໨ͷۈ຿ͷ։࢝࣌ؒΛ࡞੒(), ೋͭ໨ͷۈ຿ͷऴྃ࣌ؒΛ࡞੒()); } @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰") 14 http://xunitpatterns.com/Implicit%20Setup.html 58
  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<Integer> breakTimeList = result.getBreakTimeList(); ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList, _1ͭ໨ͷܭࢉ࣌ؒ͸(60), _2ͭ໨ͷܭࢉ࣌ؒ͸(45)); } } 59
  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<WorkingTimeCalculator> 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<Integer> breakTimeList = result.getBreakTimeList(); assertEquals(2, breakTimeList.size()); assertEquals(60, breakTimeList[0]); assertEquals(45, breakTimeList[1]); } } 60
  61. ಡΈ΍͘͢ͳͬͨ @DisplayName("ෳ਺ۈ຿ͨ͠ࡍͷۈ຿࣌ؒͷ߹ܭͱٳܜ͕࣌ؒܭࢉ͞ΕΔ΂͖⏰") @Test void breakTimeCalculation() throws Exception { // when

    workingCalculator.calucuation(); CalculationResult result = sut.getCaluculationResult(); // then List<Integer> breakTimeList = result.getBreakTimeList(); ٳܜ͸2ճ෼ܭࢉ͞Εͯ(breakTimeList, _1ͭ໨ͷܭࢉ࣌ؒ͸(60), _2ͭ໨ͷܭࢉ࣌ؒ͸(45)); 61
  62. One more thing • ςετର৅ΛSUT(System Under Test)ͱهड़ ͢Δͷ͸xUTPจԽ15 CalculationResult result

    = sut.getCaluculationResult(); 15 http://xunitpatterns.com/SUT.html 62
  63. ·ͱΊʹ͔͑ͯ 63

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

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

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

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

  68. ͓͠·͍ 68