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

VRT in Action

VRT in Action

About VRT(Visual Regression Testing)

Yosuke Kurami

November 16, 2019
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. VISUAL
    REGRESSION
    TESTING
    IN ACTION
    Frontend Conference Fukuoka '19

    View full-size slide

  2. About me
    w ૔ݟ༸ีʢ!2VSBNZʣ
    w ແ৬
    w ։ൃิॿπʔϧΛ࡞Δͷ͕झຯ

    View full-size slide

  3. Agenda
    w #BDLHSPVOE
    w 5PPMTGPS735
    w 735JOSFBMXPSME
    w 4VNNBSZ

    View full-size slide

  4. Viewͷςετɺॻ͍ͯ·͔͢ʁ

    View full-size slide

  5. How to test views?
    w ͜ͷ6*ͷςετΛॻ͍ͯΈΑ͏ʂ


    {{user.name}}



    Signup


    View full-size slide

  6. How to test views?
    w ͜ͷ6*ͷςετΛॻ͍ͯΈΑ͏ʂ


    {{user.name}}



    Signup


    DMBTT͕VTFSOBNFͰ͋Δ͜ͱ
    VTFS໊͕಺ૠ͞Ε͍ͯΔ͜ͱ
    63-͕όΠϯυ͞Ε͍ͯΔ͜ͱ

    View full-size slide

  7. How to test views?
    w ͜ͷ6*ͷςετΛॻ͍ͯΈΑ͏ʂ


    {{user.name}}



    Signup


    DMBTT͕VTFSOBNFͰ͋Δ͜ͱ
    VTFS໊͕಺ૠ͞Ε͍ͯΔ͜ͱ
    63-͕όΠϯυ͞Ε͍ͯΔ͜ͱ
    VTFS͕OVMMͷͱ͖ɺCVUUPOλά͕ඳը͞Ε͍ͯΔ͜ͱ
    JNHλάͰ͋Δ͜ͱ
    EJWλάͰ͋Δ͜ͱ
    TQBOλάͰ͋Δ͜ͱ
    ΩϦ͕ແ͍ʂ

    View full-size slide

  8. Problems
    w Ͳ͜·ͰΞαʔγϣϯ͢Ε͹͍͍ͷʁ
    w UFYUOPEF ཁૉ໊ $44DMBTT໊΍ଐੑ஋ FUD
    w ΞαʔγϣϯΛॆ࣮ͤ͞Δͱ
    w ը໘࢓༷͕มΘͬͨΒΞαʔγϣϯ͕յΕͯϝϯς͠ΜͲ͍
    ʮ7JFXͷࣗಈςετ͸ίεύѱ͍͔Βը໘ͷςετ͸ਓྗͰʂʯ
    ͱͳΔͱ࠷ѱ

    View full-size slide

  9. Snapshot testing
    w ࠓճͷςετͰಘΒΕͨ%0.จࣈྻΛɺ࣍ճͷFYQFDUFEͱͯ͠ར༻͢Δख๏

    ॳճ΍ࠩ෼ൃੜ࣌͸TOBQTIPUϑΝΠϧΛϨϏϡʔ͢Δ͜ͱͰ୲อ͢Δ

    The latest snapshot(DOM string)
    The actual snapshot(DOM string)
    Update if snapshot is accepted
    Assertion

    View full-size slide

  10. Pros/Cons
    w 1SPT
    w ಋೖ͕༰қɻ+FTUͳͲʹ͸ඪ४૷උ͞Ε͍ͯΔ
    w $POT
    w จࣈྻͰςετ͢Δ͜ͱʹҙຯ͕ͲΕ͚ͩ͋Δͷ͔ʁ
    w ͦ΋ͦ΋ΤϯυϢʔβʔ͸$44DMBTT໊ʹڵຯ͕͋Δ༁Ͱ͸ͳ͍
    w ϑϩϯτΤϯυͷ੹຿͸6*ͷఏڙͷ͸ͣͳͷʹɺݟͨ໨Λςετ͠ͳͯ͘Α͍ͷ͔ʁ

    View full-size slide

  11. Visual regression testing
    w จࣈྻͰ͸ͳ͘ɺඳը͞Εͨը૾ͦͷ΋ͷΛεφοϓγϣοτʹ͢Ε͹ɺʮݟͨ໨ʯ΋
    ؚΊͯςετͰ͖ΔͷͰ͸
    5IFMBUFTUTOBQTIPU 1/(*NBHF

    5IFBDUVBMTOBQTIPU 1/(*NBHF

    6QEBUFJGTOBQTIPUJTBDDFQUFE
    Assertion

    View full-size slide

  12. Other motivations
    w 6*ίϯϙʔωϯτͷ୯ମςετҎ֎ͷ༻్ʹ΋ɿ
    w ΞϓϦέʔγϣϯશମͰ$44͕յΕ͍ͯͳ͍͔ݕূΛߦ͍͍ͨ
    w 4$44͔Βଞͷ$44QSFQSPDFTTPS΁҆શʹҠߦ͍ͨ͠
    w FUD

    View full-size slide

  13. TOOLS FOR VRT

    View full-size slide

  14. What should I do?
    w ెखۭݓͰ735ʹऔΓ૊Ήͷ͸݁ߏେมɻɻɻ
    w ͦ΋ͦ΋ࡢࠓͷϑϩϯτͷελοΫ͕ෳࡶ
    w 6*ϥΠϒϥϦ3FBDU "OHVMBS 7VFKT FUD
    w ςεςΟϯάϥΠϒϥϦ4FMFOJVN $ZQSFTTJP ,BSNB +FTU "WB +BTNJOF
    .PDIB FUD
    w $*5SBWJT$* $JSDMF$* 8FSDLFS$* (JU)VC"DUJPOT (JUMBC$* FUD
    w 735ݕ౼࣌ɺࣗ෼ͨͪͷ։ൃελοΫʹ޲͍ͨπʔϧ͕ແ͔ͬͨͨΊɺࣗ࡞͢Δ͜ͱʹ

    View full-size slide

  15. reg-viz
    w 735ʹऔΓ૊ΉաఔͰ࡞ͬͨπʔϧୡ͸IUUQTHJUIVCDPNSFHWJ[Ͱެ։த

    View full-size slide

  16. Separation of concern
    w Ұؾʹશ෦ղܾ͠Α͏ͱ͢Δͱਏ͍
    w ΤϯδχΞͷجຊʮ໰୊Λখ͘͞෼͚ΔʯʹཱͪฦΔ
    w 735ඞཁͳཁૉ
    w ςετίʔυ͔Βը૾Λग़ྗ͢Δ
    w ग़ྗ͞Εͨը૾Λൺֱ͢Δ

    View full-size slide

  17. ʮը૾ͷग़ྗʯฤ

    View full-size slide

  18. Weapon of choice
    w େ͖͘෼͚ͯ௨Γ
    w ࣮ΞϓϦέʔγϣϯΛΩϟϓνϟ͢Δύλʔϯ
    w 4FMFOJVN΍$ZQSFTTJPɺ#SPXTFS4UBDLͳͲͰࣗಈԽεΫϦϓτΛ༻ҙʢ&&ʣ
    w ը໘ͷύʔπຖʹΩϟϓνϟ͍ͯ͘͠ύλʔϯ
    w 1VQQFUFFS΍,BSNBɺ/JHIUNBSFͱ֤ςεςΟϯάϥΠϒϥϦΛ૊Έ߹Θ͍ͤͯ͘
    w 4UPSZCPPL

    View full-size slide

  19. Why Storybook?
    w 4UPSZCPPLͷར఺
    w 3FBDU 7VFKT "OHVMBS 3/ͳͲɺओཁͳϑϨʔϜϫʔΫ͕αϙʔτ͞Ε͍ͯΔ
    w 4UPSZTIPUTʢ4UPSZCPPLʹ͓͚Δ%0.จࣈྻϕʔεͷεφοϓγϣοτςετπʔϧʣ
    ͱͷซ༻΋Մೳ
    w ςετҎ֎Ͱ໾ʹཱͭγʔϯ͕ଟ͍ಋೖͷ߹ҙΛಘ΍͍͢
    w ը໘ͷΧλϩάͱͯ͠ར༻Մೳ
    w ).3͕ޮ͘ͷͰɺ6*։ൃͦΕࣗମʹ΋ศར

    View full-size slide

  20. Storycap
    w IUUQTHJUIVCDPNSFHWJ[TUPSZDBQ
    w 4UPSZCPPL͔Β֤TUPSZΛ1/(ը૾Խ͢Δ$-*
    w )FBEMFTT$ISPNFϥούͰ͋Δ1VQQFUFFSΛར༻
    w TUPSZCPPLDISPNFTDSFFOTIPU[JTVJͱ͍͏ͪΐͬͱ΍΍͍͜͠ܦྺ

    View full-size slide

  21. Storycap: Demo
    npx storycap https://storybookjs-next.now.sh/vue-kitchen-sink/

    View full-size slide

  22. Storycap features
    w 4UPSZCPPLWWWΛαϙʔτ
    w 6*'SBNFXPSLʢ3FBDU΍7VFKTʣʹґଘ͠ͳ͍
    w 4UPSZCPPLͷ63-͑͞஌͍ͬͯΕ͹ಈ͔ͤΔɻ͍ΘΏΔ[FSPDPOpHVSBUJPO
    w 4UPSZCPPLBEEPOͱͯ͠ར༻͢Δ͜ͱͰΩϟϓνϟઃఆͷΧελϚΠζ΋Մೳ
    w ݁ߏ଎͍ʢͱࢥͬͯΔʣ
    w ؀ڥ΍ΞϓϦʹґଘ͢Δ͕ɺd TUPSJFTʹରͯ͠໿ඵͰΩϟϓνϟ׬ྃ

    View full-size slide

  23. Suppress false positive
    w 'BMTFQPTJUJWFʢِཅੑޡݕग़ʣͱ͸
    w ຊདྷਖ਼͍͠΋ͷΛؒҧ͍ͱͯ͠ѻͬͯ͠·͏͜ͱɻཁ͸ΦΦΧϛগ೥
    w ʮιʔείʔυΛม͍͑ͯͳ͍ͷʹΩϟϓνϟը૾ͷൺֱ࣌ʹࠩ෼͕ݕग़͞Εͯ͠·͏ʯ
    Λແ͘͞ͳͯ͘͸ͳΒͳ͍
    w จࣈྻϕʔεͷ4OBQTIPUςετͱൺֱͨ͠ͱ͖ʹɺ࣮ϒϥ΢βΛ࢖͏735ͷ೉қ౓͕ߴ
    ͘ͳͬͯ͠·͏ཧ༝ͷͭ
    w 4UPSZDBQͰ͸1VQQFUFFSͷ"1*Λ࢖ͬͯɺGBMTFQPTJUJWFΛ๷͙࢓૊ΈΛೖΕ͍ͯΔ

    View full-size slide

  24. 1. Turn off animation
    w $44Ξχϝʔγϣϯ͸ڧ੍ఀࢭ
    w +4ʹΑΔΞχϝʔγϣϯʢFHIJHIDIBSUT 3PUUJFͳͲʣ͸ϢʔβʔଆͰ੾Γସ͑ͯ΋Β
    ͏͔͠ͳ͍
    /* animation-off.css */
    *, *::before, *::after {
    transition: none !important;
    animation: none !important;
    }
    page.addStyleTags({ path: 'animation-off.css' });

    View full-size slide

  25. 2. Wait for assets loaded
    w ը૾΍ϑΥϯτͳͲͷϦιʔεಡΈࠐΈ׬ྃલ

    ʹΩϟϓνϟͯ͠͠·͏ͱɺGBMTFQPTJUJWFʹͳͬͯ͠·͏
    w page.on('request')Λ؂ࢹ
    w request.resourceType()Ͱ$ISPNF͕൑ผͨ͠Ϧιʔεछผ͕ࣄલʹΘ͔Δ
    w ಛఆͷϦιʔελΠϓʢJNBHFͳͲʣʹ͍ͭͯɺͦͷϦΫΤετ͕׬͔ྃͨ͠Ͳ͏͔Λݕ
    ূ͔ͯ͠ΒɺTDSFFOTIPUΛ࣮ߦ͢ΔΑ͏ʹ͍ͯ͠Δ
    w ϦιʔελΠϓΛݟ͓͔ͯͳ͍ͱɺTFSWFSTFOUFWFOUTʢFH4UPSZCPPLͷ).3ʣ
    ͳͲɺʮ׬ྃ͠ͳ͍ʯϦΫΤετΛ؂ࢹ͠ଓ͚Δ͜ͱʹͳΔ

    View full-size slide

  26. 3. Wait til metrics stabled
    w .FUSJDT"1*ΛͰ$ISPNFSFOEFSJOHQJQFMJOFʹ͓͚Δॲཧ࣮ߦճ਺͕ܭଌ
    w ௚ۙͷϑϨʔϜͱଌఆ஋Λൺֱͯࠩ͠෼͕ແ͘ͳ͔ͬͯΒTDSFFOTIPUΛ࣮ߦ͢ΔΑ͏ʹ
    ͍ͯ͠Δ

    ʢ྘৭ͷ෦෼͕ఆৗ͔Ͳ͏͔Λ஌Δज़͕ͳ͍ͨΊɺͪΐͬͱෆ׬શʣ
    const { Nodes, RecalcStyleCount, LayoutCount } = await page.metrics();

    View full-size slide

  27. ʮը૾ͷൺֱʯฤ

    View full-size slide

  28. reg-cli
    w IUUQTHJUIVCDPNSFHWJ[SFHDMJ
    w SFHWJ[ͷதͰ࠷΋ݹ͍ύοέʔδ
    w ը૾ΛؚΜͩσΟϨΫτϦಉ࢜ΛҾ਺ʹͱΓɺಉ໊ը૾ϑΝΠϧͷࠩ෼ൺֱΛߦ͏$-*
    w ʮඞཁͳͷ͸ࣄલͱࣄޙͷը૾܈͚ͩʯͱ͍͏γϯϓϧ͕͞ಛ௃
    npx reg-cli actural-img-dir expected-img-dir diff-img-dir

    View full-size slide

  29. Report UI
    w -R ΦϓγϣϯΛ෇͚͓ͯ͘ͱɺൺֱ݁ՌΛϨϙʔτͱͯ͠ࢀরՄೳ

    View full-size slide

  30. Various ways to visualize diff
    w 1JYFMEJ⒎Ҏ֎ʹ΋ɺ4XJQF VQ 0OJPOTLJOOJOHͳͲ༷ʑͳൺֱํ๏Λఏڙ

    View full-size slide

  31. reg-suit
    w IUUQTHJUIVCDPNSFHWJ[SFHTVJU
    w SFHDMJΛճؼςετͷϫʔΫϑϩʔʹ૊ΈࠐΉͨΊͷϥούʔπʔϧ
    w ۀ຿ͰॳΊͯSFHDMJΛ࢖ͬͨͱ͖ɺपลͷγΣϧεΫϦϓτ͕ංେԽ͖ͯͯ͠Ϡόͦ
    ͏ͩͬͨͷͰɺϦϑΝΫλϦϯάΛ݉Ͷͯ044Խͨ͠΋ͷ
    w ʮ$*΍4$.ʹґଘͤͣɺ൚༻తʹ࢖͑ΔʯΛϞοτʔʹ࡞੒
    w ࣮αʔϏεʢ(JU)VCͳͲʣͱ࿈ܞ͢Δ෦෼͸QMVHJOͱͯࠩ͠͠ࠐΊΔΑ͏ʹͯ͋͠Δ

    View full-size slide

  32. Automation via reg-suit

    View full-size slide

  33. Publishing images
    w 735ʹऔΓ૊Μͩ౰ॳɺ+FTUͳͲͱಉ͘͡ը૾ϑΝΠϧࣗମ΋DPNNJUʹؚΊ͍͕ͯͨɺ
    ςετ࣮ߦऀͷ୺຤ࠩҟͰେྔʹEJ⒎͕ੜ͡Δͱ͍͏ਏΈ͕͋ͬͨ
    w $*Ͱੜ੒͞Εͨը૾ΛΫϥ΢υʹอଘ͓͖ͯ͠ɺ࣍ճςετ࣌ʹμ΢ϯϩʔυ͢ΔΑ͏ʹ
    ઃܭ
    w Ϋϥ΢υલఏʹͨ͜͠ͱʹΑΓɺࠩ෼༗ແʹؔΘΒͣϩʔΧϧͰը૾औಘΛճ͢ඞཁ͕
    ແ͘ͳΔͱ͍͏ϝϦοτ͕෭࡞༻తʹಘΒΕͨ
    w ݱঢ়ɺ"844($4Λอଘઌͱ͢ΔͨΊͷQMVHJOΛެ։த
    w தʹ͸$JSDMF$*ͷBSUJGBDUTͱͯ͠อଘ͢Δ0SCΛ࡞੒͍ͯ͠Δ໠ऀ΋

    View full-size slide

  34. Workflow
    w ࣮ߦ࣌ʹൺֱର৅ͷDPNNJUΛಛఆ͠ɺετϨʔδ͔ΒFYQFDUFEը૾Λμ΢ϯϩʔυ

    View full-size slide

  35. GitHub integration
    w SFHTVJUͷࠩ෼ൺֱ׬ྃ࣌ʹɺ(JU)VCͷ13ίϝϯτͱͯ͠௨஌Λߦ͏ػೳ

    View full-size slide

  36. GitHub integration
    w ίϝϯτͷ˔˔˔˔˔͸ࠩ෼ͷ಺༰ʢ੺ɿࠩ෼༗ɺ੨ɿࠩ෼ͳ͠ɺനɿ৽نϑΝΠϧʣ
    w ྫ͑͹ɺ੺ؙݸ͸ʮϑΝΠϧͰࠩ෼͕ੜ͍ͯ͡Δʯͱ͍͏ҙຯ
    w നؙ͚ͩ૿͍͑ͯΔ৔߹ɺͨͩςετέʔε͕૿͚͑ͨͩͳͷͰتΜͰྑ͍
    w ٯʹݸ͘Β͍੺ؙ͕͋Δͱʮ͜Ε͸৺ͯ͠ϨϏϡʔ͠ͳ͍ͱʯͱ֮ޛΛܾΊͨΓ

    View full-size slide

  37. GitHub integration
    w ͭͰ΋ࠩ෼ϑΝΠϧ͕͋Ε͹ςετࣦഊͷՄೳੑ͕͋ΔͨΊɺ$PNNJU4UBUVTΛGBJMFE
    ͱ͍ͤͯ͞Δ
    w ϨϏϡΞ͕13Λঝೝ͢Δͱɺ$PNNJU4UBUVTΛ4VDDFFEFEʹมߋ
    w εφοϓγϣοτςετͰ͋Γɺʮҙਤతͳࠩ෼ʯ͔Ͳ͏͔͸ϨϏϡʔ͕ඞཁ
    w (JU)VC13ʹࠩ෼༗ແΛ௨஌͢Δ͜ͱͰɺ։ൃϑϩʔʹࣗવͳܗͰεφοϓγϣοτϨ
    ϏϡʔΛࠩ͠ࠐΊΔ

    View full-size slide

  38. Review with images
    w SFHDMJͷϨϙʔτը໘ʹ13ίϝϯτ͔ΒભҠՄೳͱ͍͏͜ͱ͸ʮϨϏϡΞ͕μΠϨΫτ
    ʹը૾Λ֬ೝͰ͖Δʯͱ͍͏͜ͱ
    w ʮͲͷΑ͏ͳݟͨ໨ͷมߋͳͷ͔ʯ͕ՄࢹԽ͞ΕΔͨΊɺϨϏϡʔͷෛՙ͕ܰݮ͞ΕΔ
    w WJFXͷΈͷमਖ਼Ͱ͋Ε͹ɺϩʔΧϧͰىಈ֬ೝ͢Δ·Ͱ΋ແ͘ͳΔɻͳΜͳΒ௨ۈதʹ
    ిं಺ͰϨϏϡʔ׬ྃ͢Δ͜ͱ͢Β͋Δ

    View full-size slide

  39. Maintainers
    w SFHWJ[ͷϝϯόʔͱओͳ୲౰ൣғ
    w !2VSBNZSFHTVJU 4UPSZDBQWͳͲ
    w !CPLVXFCSFHDMJͷॳ൛ SFHTVJUͷFYQFDUFEDPNNJUݕग़෦෼ͳͲ
    w !XBEBDLFM4UPSZDBQͷॳ൛ SFHDMJͷϨϙʔτ6* SFHWJ[શମͷσβΠϯͳͲ
    w 13ͳͲ͸͍ͭͰ΋΢ΣϧΧϜͰ͢ʂ

    View full-size slide

  40. Other tools
    w IUUQTHJUIVCDPNSFHWJ[OPEFYDC
    w $ISPNFΛIFBEMFTTͰಈ࡞ͤ͞ΔͨΊʹඞཁͳMJCYDCͳͲΛࣄલʹম͖෇͚ͨ
    %PDLFSpMFɻ$*ͷCBTFΠϝʔδʹ͢Δͱศར
    w IUUQTHJUIVCDPNSFHWJ[JNHEJ⒎KT
    w /PEFKT͚ͩͰ׬݁ͯ͠ը૾ͷEJ⒎ੜ੒͕ߦ͑ΔϥΠϒϥϦɻSFHDJM͕಺ଆͰ͜ΕΛୟ
    ͍͍ͯΔ
    w ࠷ॳظɺSFHDMJ͕JNBHFNBHJDLͷDPNQBSFίϚϯυʹґଘ͓ͯ͠Γɺ͜ΕΛണ͕͢
    ͨΊʹ࣮૷

    View full-size slide

  41. Other tools
    w IUUQTHJUIVCDPNSFHWJ[YJNHEJ⒎KT
    w ࠩ෼ϨϙʔτͰ༻͍͍ͯΔࠩ෼ՕॴͷϚʔΩϯά༻ͷϥΠϒϥϦɻ0QFO$7ͷہॴಛ
    ௃ྔͰը૾಺෦ͷύʔπͷҐஔมಈΛநग़͍ͯ͠Δ
    w KTͱॻ͍͍ͯΔ͚Ͳɺ࣮ࡍ͸0QFO$7$ΛFNTDSJQUFOͰXBTNԽͨ͠୅෺
    w ਪఆ͕؁͘ɺΘ͚Θ͔ΒΜදࣔʹͳΔ͜ͱ΋݁ߏଟ͍

    View full-size slide

  42. VRT IN REAL WORLD

    View full-size slide

  43. Users of reg-viz tools
    w SFHWJ[ͷπʔϧΛಋೖͯ͘͠Ε͍ͯΔاۀʢΞϧϑΝϕοτॱɺࠓճܝࡌڐՄ໯ͬͨͱ͜ͷΈʣ
    w 4NBSU)3ࣾ͸QVCMJDSFQPӡ༻Ͱεΰ͍
    w IUUQTHJUIVCDPNLVGVTNBSUISVJQVMM

    View full-size slide

  44. Users of reg-suit
    w SFHTVJU͕(JU)VC΁ίϝϯτͨ͠ճ਺Λաڈϲ݄෼άϥϑԽ
    w dສճ݄ສճ݄

    View full-size slide

  45. How many images tested
    w ҰճͷςετͰฏۉdຕఔ౓ɻࡉ͔͍ϩάͰΈΔͱ ຕҎ্ͷϢʔβʔ΋
    ԜΜͰΔͷ͸౔೔ɻ΍͸Γ࢓ࣄͰ࢖ΘΕΔέʔε͕ѹ౗తͬΆ͍

    View full-size slide

  46. Performance
    w ۀ຿Ͱ͸ճͷ13Ͱݕূର৅ͷը૾͕ ຕΛ௒͑Δ͜ͱ΋
    w ʮ735ͷ͍ͤͰ$*͕஗͍ʯͱͳΓ͕ͪ
    w ࣗಈςετͰར༻͞ΕΔπʔϧ܈ͷͨΊɺ$*Ͱͷ࣮ߦ࣌ؒ͸ۃྗ୹͍ͨ͘͠
    w ֤πʔϧͦΕͧΕͰɺߴ଎Խͷ޻෉Λ࣮ࢪ͍ͯ͠Δ

    View full-size slide

  47. Tuning: Storycap
    w ຕͷੈքͰ͸ʮը૾ͷൺֱʯΑΓ΋ʮը૾ͷੜ੒ʯ͕ࢧ഑త
    w 1VQQFUFFSͷϓϩηεΛฒྻՔಇͤͯ͞$16Λ༡͹ͤͳ͍
    w খωλ
    1VQQFUFFSͰ͸1BHFΛෳ਺࡞ͬͯ΋5$1ίωΫγϣϯ੍ݶͷ౎߹্ɺMPBE
    BWFSBHF͕Ք͛ͳ͍ɻ#SPXTFSຖฒྻԽ͢Δํ͕݁Ռͱͯ͠ޮ཰త
    w 4UPSZͷ੾Γସ͑͸JGSBNFʹ௚઀QPTUNFTTBHF͢Δ
    w 4UPSZCPPLͷXFCQBDLʹCVOEMF͞Εͨ+BWB4DSJQUͷධՁ͕Ұ౓͚ͩʹͳΔ

    View full-size slide

  48. CVOEMF͞ΕͨKTͷධՁ͚ͩͰNTFDҎ্͍͔࣋ͬͯΕΔ

    View full-size slide

  49. Tuning: reg-cli
    w $-*ຊମ
    w ը૾ͷNEϋογϡ͕Ұகͨ͠৔߹ɺϐΫηϧൺֱΛߦΘͳ͍Α͏ʹ͍ͯ͠Δ
    w 3FQPSU6*΋ ຕͰ΋αΫαΫݟΕΔΑ͏ʹ޻෉
    w ը૾ͷ஗Ԇϩʔυʢ*OUFSTFDUJPO0CTFSWFSMPBEJOHMB[Z

    w 4΍($4΁ͷը૾(&5ճ਺͕࠷খԽ͞ΕΔͷͰɺ͓ࡒ෍ʹ΋༏͍͠
    w Ծ૝εΫϩʔϧʢࣗલ࣮૷ʣ

    View full-size slide

  50. Your responsibilities

    View full-size slide

  51. Your responsibilities
    w 4UPSZDBQ SFHDMJSFHTVJUΛಋೖ͢Ε͹ɺ735Λ࣮ݱ͢Δ͜ͱ͸Ͱ͖Δ
    w ʢ735ʹݶͬͨ࿩Ͱ͸ແ͍͚ΕͲʣπʔϧΛಋೖ͓ͯ͠ऴ͍ɺͱ͍͏༁͡Όͳ͍
    w Ή͠ΖΑ͏΍͘ελʔτ஍఺ʹཱ͚ͬͨͩ
    ʮͪΌΜͱςετΛճ͍ͯ͘͠ʯͷ͸։ൃνʔϜͷ੹຿

    View full-size slide

  52. Scaffolding
    w εφοϓγϣοτςετͰ͋ͬͯ΋ɺςετίʔυΛॻ͔Ͷ͹Կ΋࢝·Βͳ͍
    w ίϯϙʔωϯτ࡞੒࣌ʹରͱͳΔςετίʔυʢ4UPSZCPPLʣͷ਽ܗ΋ੜ੒͢ΔΑ͏ʹ
    ؀ڥΛ੔͓͑ͯ͘ͱΑ͍
    w TDB⒎PMEJOHʹ࢖͑Δ/1.QBDLBHFT
    w !BOHVMBSEFWLJUTDIFNBUJDTIUUQTHJUIVCDPNBOHVMBSBOHVMBSDMJCMPC
    NBTUFSQBDLBHFTBOHVMBS@EFWLJUTDIFNBUJDT
    w TDB⒎EPHIUUQTHJUIVCDPNDBUTPTTTDB⒎EPH

    View full-size slide

  53. Scaffolding
    w TDIFNBUJDTͰͷTUPSJFTUTYͷྫɿ
    import React from 'react';
    import { storiesOf } from '@storybook/react';
    import { action } from '@storybook/addon-actions';
    import <%= classify(name) %>, { Props } from './<%= classify(name) %>';
    const stories = storiesOf('<%= target %>/components/<%= classify(name) %>', module);
    const props: Props = {
    };
    stories.add('<%= classify(name) %>', () => <<%= classify(name) %> {...props} />);

    View full-size slide

  54. Separate presentation
    w WJFXͷঢ়ଶ͸ςετίʔυ͔Β੍ޚͰ͖ΔΑ͏ʹ͓ͯ͘͠΂͠
    w MPDBMTUBUFʢ3FBDUͰ͍͏ͱ͜ΖͷVTF4UBUFʣʹཔΓ͗͢ͳ͍ɻଞͷ6*ϑϨʔϜϫʔ
    ΫͰ΋$PNQPOFOUQSJWBUFͳϑΟʔϧυΛ࢖͑Δ͕ɺ͜ΕΒͷѻ͍͸৻ॏʹ
    w ίϯϙʔωϯτͷݟͨ໨͸QSPQTͰมߋͰ͖ΔΑ͏ʹ͓ͯ͘͠
    w TUBUF͸3FEVYʢPS/H3Y 7VFYʣͷTUPSFʹ੾Γग़ͯ͠ɺςετ࣌͸ϞοΫΛ%*Ͱ͖
    ΔΑ͏ʹ͓ͯ͘͠
    w 4UPSZCPPLͰ͋Ε͹ɺ%FDPSBUPSΛ༻ҙͯ͠1SPWJEFSΛט·͓ͤͯ͘ɺͳͲ

    View full-size slide

  55. No side effect

    View full-size slide

  56. No new Date() !
    ˞!OPCVIJLPTBXBJʹڐՄ໯ͬͯܝࡌ
    ͓Θ͔ΓͩΖ͏͔

    View full-size slide

  57. Keep your view testable
    w ςελϏϦςΟͷҡ͕࣋։ൃऀͷ੹຿Ͱ͋Δͷ͸735΋Ұॹ
    w ʮݱࡏ࣌ࠁ͕ؔΘΔϢχοτςετ͔Βɺςετ༰қੑઃܭΛֶͿʯ

    IUUQTUXBEBIBUFOBCMPHKQFOUSZEFTJHOGPSUFTUBCJMJUZ
    w ίϯϙʔωϯτͷςετʹ͖ͪΜͱ޲͖߹͏͜ͱ͸ɺΞϓϦέʔγϣϯͷઃܭʹ΋ͪΌ
    Μͱ޲͖߹͏ͷͱಉٛ

    View full-size slide

  58. Summary
    w 735ͪΌΜͱճ͢ͱελΠϧ·ͰݕূͰ͖Δ
    w 4UPSZCPPL͔ͭͬͯΔͷͰ͋Ε͹ɺ4UPSZDBQ࢖͏ͱ͍͍ͱࢥ͏
    w SFHTVJU SFHDMJ
    ͸ը૾ͷൺֱʹಛԽͨ͠πʔϧ
    w 7JFXͷςετΛ͠΍͍͢Α͏ʹ౒ྗ͸ଵΒͣʹʂ
    w ςετʹ޲͖߹͏͜ͱ͸ઃܭ΍%9ͷ޲্ʹͭͳ͕Δ

    View full-size slide