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

VRT in Action

Yosuke Kurami
November 16, 2019

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 Slide

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

    View Slide

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

    View Slide

  4. BACKGROUND

    View Slide

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

    View Slide

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


    {{user.name}}



    Signup


    View Slide

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


    {{user.name}}



    Signup


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

    View Slide

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


    {{user.name}}



    Signup


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

    View Slide

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

    View Slide

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

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

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

    View Slide

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

    View Slide

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

    5IFBDUVBMTOBQTIPU 1/(*NBHF

    6QEBUFJGTOBQTIPUJTBDDFQUFE
    Assertion

    View Slide

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

    View Slide

  14. TOOLS FOR VRT

    View Slide

  15. 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 Slide

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

    View Slide

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

    View Slide

  18. ʮը૾ͷग़ྗʯฤ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. 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 Slide

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

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

    View Slide

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

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

    View Slide

  28. ʮը૾ͷൺֱʯฤ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. Automation via reg-suit

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. About us

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  44. VRT IN REAL WORLD

    View Slide

  45. Users

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. Performance

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

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

    View Slide

  54. View Slide

  55. Your responsibilities

    View Slide

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

    View Slide

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

    View Slide

  58. 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 Slide

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

    View Slide

  60. No side effect

    View Slide

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

    View Slide

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

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

    View Slide

  63. SUMMARY

    View Slide

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

    View Slide

  65. Thank you !

    View Slide