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

WACATE2019_summer_BPP

 WACATE2019_summer_BPP

WACATE2019 夏のBPPセッションスライドです。

Daiki Katayama

June 15, 2019
Tweet

More Decks by Daiki Katayama

Other Decks in Programming

Transcript

  1. ։ൃऀ͔ΒݟΔςετ
    2019/06/15~16 WACATE2019 Ն BPPηογϣϯ
    kariad/͔Γ͋Ͳ(@kariad_uu)
    1

    View Slide

  2. ࣗݾ঺հ
    • kariad / @kariad_uu
    • ยࢁ େथ
    • ΦΠγοΫεɾϥɾେ஍ iOS App Developer
    • / / V / ςετ / ઃܭ / ྉཧ / ήʔϜ
    2

    View Slide

  3. ςετͱͷؔΘΓ
    • ৽ଔ: SIer ͻͨ͢ΒؤுΔखಈςετɺऴΘΒͳ͍ɺؼΕͳ͍ɺਏ͍….
    • ҟಈ: ΞδϟΠϧɺTDDɺςετָ͍͠
    • స৬: ΞδϟΠϧɺUnitςετಋೖɺςετ΍͍͖ͬͯ
    • QAΤϯδχΞɺςετΤϯδχΞͱݺ͹ΕΔํͱҰॹʹ࢓ࣄΛͨ͜͠
    ͱ͸ͳ͍Ͱ͢
    3

    View Slide

  4. ࠓ೔࿩͢͜ͱ
    • લճͷࢲͷϙδγϣϯϖʔύʔৼΓฦΓ
    • ։ൃऀ(ࢲ)͸͜͏͍͏෩ʹςετʹ޲͖߹ͬͯ·͢ͱ͍͏࿩

    - ςετ΁ͷϞνϕʔγϣϯ

    - ։ൃऀ͕ςετΛ͠ͳ͍(Ͱ͖ͳ͍)ཧ༝
    4

    View Slide

  5. ஫ҙʂ
    • ͋͘·Ͱ΋ࢲͷओ؍Ͱ͢ɻશͯͷ։ൃऀ͕͜͏Ͱ͋Δʂͱ͍
    ͏࿩Ͱ͸ͳ͍ͷͰྃ͝ঝ͍ͩ͘͞

    View Slide

  6. લճ(WACATE2018 ౙ)ͷ
    ࢲͷϙδγϣϯϖʔύʔ
    6

    View Slide

  7. 7

    View Slide

  8. ౰೔վΊͯݟͨ࣌ͷࢲͷײ૝
    • ΈΜͳͱൺ΂ͯϑΥϯτ͕Ͱ͔͍
    • †ͱ͔࢖ͬͯதೋප
    • ͳΜ͔ΤϞ͍͚ͩ
    • ਖ਼௚ͪΐͬͱஏ͔͔ͣͬͨ͠…
    8

    View Slide

  9. ͭ·ΓԿ͕ݴ͍͔ͨͬͨͷ͔
    • ։ൃऀ͔Βࢹ఺Ͱͷςετ΁ͷ૝͍

    ςετ͕͋Δ͜ͱͰ৺ཧత҆શੑͷ͋Δ։ൃ͕Ͱ͖Δ

    Ͱ΋΍Δ͔Βʹ͸ޮ཰తʹ΍Γ͍ͨ
    • ςετ͕޷͖͔ͩΒ஥ྑͯ͘͠Ͷ

    ςετք۾ͷίϛϡχςΟॳࢀՃͩͬͨ
    9

    View Slide

  10. • ࠓճ΋஌Γ߹͍ͱ͔΄΅͍ͳ͍ͷͰؾܰʹ࿩͔͚ͯ͘͠
    ΕΔͱخ͍͠Ͱ͢
    10

    View Slide

  11. ։ൃऀͷςετ΁ͷ޲͖߹͍ํ

    View Slide

  12. ςετ΁ͷϞνϕʔγϣϯ
    (ࢲͳΓʹ)
    12

    View Slide

  13. • ࢲͨͪͷϛογϣϯ͸ϢʔβʔʹͱͬͯՁ஋͋Δ

    αʔϏεΛఏڙ͢Δ͜ͱ
    • Ձ஋͕͋Δ = ͓٬༷(Ϣʔβʔ)͕خ͍͔͠
    13

    View Slide

  14. • Ͱ΋࠷ॳ͔Β࠷େԽ͞ΕͨՁ஋Λఏڙ͢Δͷ͸೉͍͠
    • ߟ͑ͨ͜ͱ͕ਖ਼͍͠(Ձ஋͕͋Δ)ͱ͸ݶΒͳ͍

    ϦʔϯɾελʔτΞοϓ
    14

    View Slide

  15. ϦʔϯɾελʔτΞοϓ
    15

    View Slide

  16. ϦʔϯɾελʔτΞοϓ
    • ݁ہͲΜͳʹ͍͍΋ͷΛߟ͑ͨͱ͜ΖͰͦΕ͸ࢥ͍ࠐΈ΍Ծ
    આʹ͗͢ͳ͍
    • MVP(Minimum Valuable Product)Ͱݕূ͢Δ
    • Ծઆ → Ծઆݕূ → ֶͼ →ҙࢥܾఆͷαΠΫϧΛճ͢
    16

    View Slide

  17. ࠷ۙͷτϨϯυʁ

    (σʔλ෼ੳΛݩʹͨ͠։ൃ)
    • ԾઆΛݩʹ࣮૷ͯ͠ϦϦʔε
    • σʔλΛऔಘͯ͠෼ੳ
    • ෼ੳ݁ՌΛݩʹվળͯ͠ϦϦʔε

    View Slide

  18. • ͲͪΒ΋ͱʹ͔͘ૣ͘αΠΫϧΛճ͍ͨ͠
    • ͱ͸͍͑όά͕͋Γਖ਼ৗʹ࢖͑ͳ͚Ε͹ԾઆݕূͰ͖ͳ
    ͍

    ‎ ࠷௿ݶChecking͸ߦ͍͍ͨ
    18

    View Slide

  19. • ΞδϟΠϧ։ൃऀͱͯ͠͸ૣ͘Ձ஋ͷ͋ΔαʔϏεΛఏ
    ڙ͢ΔͨΊʹCheckingΛ͍ͨ͠

    ʢͦ΋ͦ΋඼࣭͕௿͔ͬͨΒՁ஋΋Լ͕Δ…ʣ
    19

    View Slide

  20. ͡Ό͋ͳΜͰChecking(ࠓճ͸Unitςετ)
    ΍Βͳ͍ͷʁ
    20

    View Slide

  21. • ΊΜͲ͍͘͞
    • ςετʹڵຯ͕ͳ͍
    • ΍Γํ͕Θ͔Βͳ͍
    • CheckingͷॏཁੑΛཧղ͍ͯ͠ͳ͍

    View Slide

  22. • ΊΜͲ͍͘͞
    • ςετʹڵຯ͕ͳ͍
    • ΍Γํ͕Θ͔Βͳ͍
    • CheckingͷॏཁੑΛཧղ͍ͯ͠ͳ͍
    ΋ͬͱݴ͏ͱɺ
    ΍Γͨͯ͘΋Ͱ͖ͳ͍

    View Slide

  23. • ΊΜͲ͍͘͞
    • ςετʹڵຯ͕ͳ͍
    • ΍Γํ͕Θ͔Βͳ͍
    • CheckingͷॏཁੑΛཧղ͍ͯ͠ͳ͍
    ΋ͬͱݴ͏ͱɺ
    ΍Γͨͯ͘΋Ͱ͖ͳ͍
    ࢲ͕ߟ͑ΔUnitςετΛ
    ΍Βͳ͍ཧ༝ͷେ͖ͳҰͭ

    View Slide

  24. Unitςετ࣮ͬͯ͸ͦΜͳʹ
    ؆୯Ͱ͸ͳ͍
    24

    View Slide

  25. ςετΛॻ͘ͷ͕೉͍͠ཧ༝
    • ςετ͕ॻ͖΍͍͢ઃܭ(Testable)ʹͳ͍ͬͯͳ͍ͱॻ͘͜
    ͱ͕೉͍͠
    • (ແཧ໼ཧ)ॻ͚ͯ΋ځ۶Ͱมߋʹ΋ऑ͘ͳΔ
    • ޙ͔Βઃܭมߋ͸ຊ౰ʹେม…(ςετ͕ͳ͍ͱঘߋ)
    25

    View Slide

  26. • ଟ͘ͷ৔߹͸ઃܭʹ໰୊͕͋Δ
    • ΋ͪΖΜϑϩʔతͳ໰୊ͷ৔߹΋͋Δ

    UnitςετΛॻ͘ϑϩʔʹͳ͍ͬͯͳ͍ɻ͕࣌ؒͳ͍ɻ
    26

    View Slide

  27. ͦ΋ͦ΋ઃܭͱ͸
    ”ؔ৺ͷ෼཭ʹΑͬͯ

    ෳࡶͳ໰୊Λ୯७ͳ໰୊ͷ܈ͱͯ͠੾Γ෼͚Δ͜ͱ”
    -iOSΞϓϦઃܭύλʔϯೖ໳ P23 ΑΓ
    27

    View Slide

  28. • ࠷ۙ͸υϝΠϯతʹ΋ٕज़తʹ΋ෳࡶԽ͍ͯ͠Δ
    • ͦͷͨΊʹઃܭΛߦ͍ෳࡶ͞ʹཱͪ޲͔͏
    • ͖ͪΜͱઃܭ͞Ε͍ͯΔ = ໰୊͕୯७Խ͞Ε͍ͯΔ

    ‎ Testable΁ͷୈҰา
    28

    View Slide

  29. ઃܭύλʔϯ(ΞʔΩςΫνϟ)
    • MVC / MVP / MVVM / Clean Architecture / Flux…
    • ઃܭํ਑ͱͯ͠ͷϕετϓϥΫςΟεू
    • ͜ΕΒͷଟ͘͸Testable΋ಉ࣌ʹߟ͑ΒΕ͍ͯΔ
    29

    View Slide

  30. ςετ͕ॻ͖΍͍͢ઃܭͱ͸
    • ໰୊͕୯७Խ͞Ε͍ͯΔ

    Ϟδϡʔϧ͝ͱʹςετ͍ͨ͠੹຿͕γϯϓϧͰ໌֬
    • Ϟδϡʔϧؒͷґଘੑ͕ͳ͍

    ςετ͍ͨ͠੹຿͕ଞϞδϡʔϧͷӨڹΛड͚ͳ͍
    30

    View Slide

  31. ෳࡶͳ੹຿Λ࣋ͬͨϞδϡʔϧ
    • xxઍߦΈ͍ͨͳΫϥε
    • ௕͗ͯ͢΋͸΍ԿΛ΍͍ͬͯΔͷ͔Θ͔Βͳ͍ϝιου
    • ΍ͨΒͱίϝϯτͰઆ໌ͯ͋͠Δ(ݸਓతҙݟ)
    31

    View Slide

  32. ੹຿աଟΛͲ͏ݟ෼͚Δ͔ʁ
    32

    View Slide

  33. “ίʔυͷ੠Λௌ͘”
    33

    View Slide

  34. • ςετ͕ॻ͖ͮΒ͍…
    • ॲཧ͕ෳࡶԽ͖͍ͯͯ͠Δ…
    • ඞͣͦ͜ʹࠟ੻͸͋Δ
    • ίʔυͷष͍ͱ΋
    34

    View Slide

  35. ઃܭͷݪଇ
    • ༗໊ͳ΋ͷͰ͸SOLIDݪଇ
    • ୯Ұ੹೚ݪଇɺ։์ด࠯ݪଇɺϦείϑͷஔ׵ݪଇɺΠϯ
    λʔϑΣʔε෼཭ͷݪଇɺґଘؔ܎ٯసͷݪଇ
    • ઃܭͷݪଇΛ༻͍ͯίʔυͷष͍ΛऔΓআ͘

    View Slide

  36. Ϟδϡʔϧؒͷґଘੑ͕͋Δ
    • ଞϞδϡʔϧͷ࣮૷͕มΘΔ͜ͱͰͪ͜Βͷॲཧ͕ӨڹΛड
    ͚ͯ͠·͏͜ͱ
    36

    View Slide

  37. func didTapSearchButton(text: String?) {
    ~~~ লུ ~~~
    SearchModel().search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    37

    View Slide

  38. func didTapSearchButton(text: String?) {
    ~~~ লུ ~~~
    SearchModel().search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    ͜͜ͷॲཧΛςετ͍ͨ͠
    38

    View Slide

  39. func didTapSearchButton(text: String?) {
    ~~~ লུ ~~~
    SearchModel().search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    SearchModelͷ࣮૷ʹ
    ґଘ͍ͯ͠Δ
    39

    View Slide

  40. func didTapSearchButton(text: String?) {
    ~~~ লུ ~~~
    SearchModel().search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    SearchModelͷ࣮૷͕มΘΔͱ
    ͪ͜Βͷ݁Ռ΋มΘͬͯ͠·͏
    40

    View Slide

  41. func didTapSearchButton(text: String?, model: SearchModel) {
    ~~~ লུ ~~~
    model.search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    ֎ଆ͔ΒΦϒδΣΫτΛ
    ౉͢Α͏ʹ
    41

    View Slide

  42. func didTapSearchButton(text: String?, model: SearchModelProtocol) {
    ~~~ লུ ~~~
    model.search(searchWord: searchWord) { result in
    switch result {
    case .success(let events):
    ~~ লུ ~~
    case .failure:
    ~~ লུ ~~
    }
    }
    }
    ౉͢ܕΛந৅Խ͞Εͨ
    ܕʹ͢Δ
    42

    View Slide

  43. 43
    protocol SearchEventModelProtocol {
    func search(searchWord: String, completion: @escaping ((Result<[ConnpassEvent]>) -> ()))
    }
    Protocol

    View Slide

  44. class FakeSearchEventModel: SearchEventModelProtocol {
    var search_successValue = [ConnpassEvent]()
    func search(searchWord: String, completion: @escaping ((Result<[ConnpassEvent]>) -> ())) {
    search_callCount += 1
    search_arguments = searchWord
    completion(.success(search_successValue))
    }
    }
    class FakeFailureSearchEventModel: SearchEventModelProtocol {
    func search(searchWord: String, completion: @escaping ((Result<[ConnpassEvent]>) -> ())) {
    search_arguments = searchWord
    completion(.failure)
    }
    }
    ελϒ
    ґଘ͢ΔΦϒδΣΫτͷ݁ՌΛ
    ίϯτϩʔϧͰ͖Δ

    View Slide

  45. • ͜ͷґଘ͢ΔΦϒδΣΫτΛ֎ଆ͔Β౉্ͯ͛͠Δ͜ͱ
    ΛDI(Dependency Injection)ͱ͍͏
    • ౉͢ΦϒδΣΫτ͸ந৅Խ͞Ε͍ͯΔͷͰɺςετίʔ
    υ͔Β͸ελϒΛ౉͢͜ͱ͕Ͱ͖Δ
    • Modelͷ࣮૷ʹґଘͤͣ੒ޭɺࣦഊͦΕͧΕͷςετ͕
    ՄೳͱͳΔ
    45

    View Slide

  46. • ࣮ࡍʹ͸JavaͰ͋Ε͹MockitoΛ࢖͑͹΋͏গָ͠ʹͳͬ
    ͨΓ͸͋Δ
    • ͕ɺSwiftͰ͸ϥΠϒϥϦΛ༻͍ͳ͍͜ͷύλʔϯ͕ൺֱ
    తଟ͍
    • ͜ΕΒͷ஌͕ࣝͳ͍ͱॻ͘͜ͱ͕೉͍͠
    46

    View Slide

  47. ઃܭҎ֎ͷཁૉ
    • ςεςΟϯάϑϨʔϜϫʔΫͷ࢖͍ํ(XCTest, Quick/Nimble)
    • ඇಉظॲཧͷςετ
    • ಛʹඇಉظ͸׳Εͳ͍ͱ೉͍͠

    iOSͰ͸ReactiveX(RxSwift)͕ελϯμʔυ(Combine)
    47

    View Slide

  48. ReactiveX
    • FRP(Functional Reactive Programming)
    • ௒ͬ͘͟Γ͍͏ͱStreamͱ͍͏࣌ؒͷྲྀΕΛ༻͍ͯඇಉظॲཧΛ؆
    ܿʹॻ͚ΔΑ͏ʹͨ͠ख๏
    • บ͕͋ΔͷͰ׳Εͳ͍ͱগ͠೉͍͠
    • ςετͰ΋ಉظతʹѻͬͯ͋͛ͨΓɺςετ༻ͷStreamͰ؅ཧͨ͠Γ
    48

    View Slide

  49. ςετΛॻͨ͘Ίʹ஌Βͳ͖Ό
    ͍͚ͳ͍͜ͱ͸ଟ͍
    49

    View Slide

  50. • ΍Βͳ͍ͷͰ͸ͳ͘΍ΔεΩϧ͕ແ͔ͬͨ
    • ΍Γͨͯ͘΋αΫοͱͰ͖ΔઃܭͰ͸ແ͔ͬͨ
    • Ͱ΋͜ͷลͷ஌ࣝɺͲ͜Ͱֶ΂͹͍͍ͷ…ʁ

    View Slide

  51. ֶͿͨΊͷ໌Δ͍ஹ͠
    51

    View Slide

  52. ίϛϡχςΟͷಇ͖
    • ςετʹؔ͢Δษڧձ (TestNight)
    • Ϋϥ΢υϑΝ΢ϯσΟϯά(PEAKS)ʹΑΔ

    Android / iOSςετશॻץߦ(iOS͸8݄༧ఆ)
    52

    View Slide

  53. ٕज़ॻయ
    લճࢲ΋͜Μͳͷग़͠·ͨ͠

    View Slide

  54. ·ͱΊ
    • গͳ͘ͱ΋ϞόΠϧΞϓϦ։ൃऀ಺Ͱ΋ςετʹର͢Δҙࣝ
    ͸ؒҧ͍ͳ͘ߴ·͍ͬͯΔ(ͱࢥ͏)
    • αʔόɺϑϩϯτͳͲ΋ϑϨʔϜϫʔΫͷൃల΍ΞδϟΠϧ
    ͷਁಁͱͱ΋ʹҙࣝ͸ߴ·͍ͬͯΔΑ͏ʹݟ͑Δ
    54

    View Slide

  55. • ؍ଌൣғͰ͸ςετΛͲ͏ʹ͔͍ͨ͠ͱࢥ͍ͬͯΔ։ൃ
    ऀ͕ଟ͍
    • Ձ஋͋ΔαʔϏεΛಧ͚͍ͨͱ͍͏ࢥ͍͸୭͠΋ಉ͡ͳ
    ͸ͣ
    • ։ൃऀ/ςετΤϯδχΞ͕ڠྗͯ͠ςετʹର͢Δ஌ݟ
    ΛਂΊ͍͚ͯͨΒخ͍͠
    55

    View Slide

  56. • iOSΞϓϦઃܭύλʔϯೖ໳

    ؔ ོٛɾদؗ େًɾླ໦ େوɾਿ্ ༸ฏɾ࢙ ᠳ৽ɾాத ݡ
    ࣏ɾՃ౻ ׮ਓ ஶ

    https://peaks.cc/books/iOS_architecture
    • Clean Architecture ୡਓʹֶͿιϑτ΢ΣΞͷߏ଄ͱઃܭ

    Robert.C.Martinஶ ֯ ੐యɾߴ໦ ਖ਼߂ ༁
    ࢀߟॻ੶

    View Slide

  57. • Test Night

    https://testnight.connpass.com/
    • Androidςετશॻ

    https://peaks.cc/books/android_testing
    • iOSςετશॻ

    https://peaks.cc/iOS_testing

    View Slide

  58. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
    58

    View Slide