Slide 1

Slide 1 text

VISUAL REGRESSION TESTING IN ACTION Frontend Conference Fukuoka '19

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

BACKGROUND

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

How to test views? w ͜ͷ6*ͷςετΛॻ͍ͯΈΑ͏ʂ
{{user.name}}
Signup
DMBTT͕VTFSOBNFͰ͋Δ͜ͱ VTFS໊͕಺ૠ͞Ε͍ͯΔ͜ͱ 63-͕όΠϯυ͞Ε͍ͯΔ͜ͱ

Slide 8

Slide 8 text

How to test views? w ͜ͷ6*ͷςετΛॻ͍ͯΈΑ͏ʂ
{{user.name}}
Signup
DMBTT͕VTFSOBNFͰ͋Δ͜ͱ VTFS໊͕಺ૠ͞Ε͍ͯΔ͜ͱ 63-͕όΠϯυ͞Ε͍ͯΔ͜ͱ VTFS͕OVMMͷͱ͖ɺCVUUPOλά͕ඳը͞Ε͍ͯΔ͜ͱ JNHλάͰ͋Δ͜ͱ EJWλάͰ͋Δ͜ͱ TQBOλάͰ͋Δ͜ͱ ΩϦ͕ແ͍ʂ

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Snapshot testing w ࠓճͷςετͰಘΒΕͨ%0.จࣈྻΛɺ࣍ճͷFYQFDUFEͱͯ͠ར༻͢Δख๏
 ॳճ΍ࠩ෼ൃੜ࣌͸TOBQTIPUϑΝΠϧΛϨϏϡʔ͢Δ͜ͱͰ୲อ͢Δ The latest snapshot(DOM string) The actual snapshot(DOM string) Update if snapshot is accepted Assertion

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

TOOLS FOR VRT

Slide 15

Slide 15 text

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ݕ౼࣌ɺࣗ෼ͨͪͷ։ൃελοΫʹ޲͍ͨπʔϧ͕ແ͔ͬͨͨΊɺࣗ࡞͢Δ͜ͱʹ

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

ʮը૾ͷग़ྗʯฤ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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' });

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

3. Wait til metrics stabled w .FUSJDT"1*ΛͰ$ISPNFSFOEFSJOHQJQFMJOFʹ͓͚Δॲཧ࣮ߦճ਺͕ܭଌ w ௚ۙͷϑϨʔϜͱଌఆ஋Λൺֱͯࠩ͠෼͕ແ͘ͳ͔ͬͯΒTDSFFOTIPUΛ࣮ߦ͢ΔΑ͏ʹ ͍ͯ͠Δ
 ʢ྘৭ͷ෦෼͕ఆৗ͔Ͳ͏͔Λ஌Δज़͕ͳ͍ͨΊɺͪΐͬͱෆ׬શʣ const { Nodes, RecalcStyleCount, LayoutCount } = await page.metrics();

Slide 28

Slide 28 text

ʮը૾ͷൺֱʯฤ

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Automation via reg-suit

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

About us

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

VRT IN REAL WORLD

Slide 45

Slide 45 text

Users

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Performance

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

Tuning: reg-cli w $-*ຊମ w ը૾ͷNEϋογϡ͕Ұகͨ͠৔߹ɺϐΫηϧൺֱΛߦΘͳ͍Α͏ʹ͍ͯ͠Δ w 3FQPSU6*΋ ຕͰ΋αΫαΫݟΕΔΑ͏ʹ޻෉ w ը૾ͷ஗Ԇϩʔυʢ*OUFSTFDUJPO0CTFSWFSMPBEJOHMB[Z w 4΍($4΁ͷը૾(&5ճ਺͕࠷খԽ͞ΕΔͷͰɺ͓ࡒ෍ʹ΋༏͍͠ w Ծ૝εΫϩʔϧʢࣗલ࣮૷ʣ

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

Your responsibilities

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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} />);

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

No side effect

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

Keep your view testable w ςελϏϦςΟͷҡ͕࣋։ൃऀͷ੹຿Ͱ͋Δͷ͸735΋Ұॹ w ʮݱࡏ࣌ࠁ͕ؔΘΔϢχοτςετ͔Βɺςετ༰қੑઃܭΛֶͿʯ
 IUUQTUXBEBIBUFOBCMPHKQFOUSZEFTJHOGPSUFTUBCJMJUZ w ίϯϙʔωϯτͷςετʹ͖ͪΜͱ޲͖߹͏͜ͱ͸ɺΞϓϦέʔγϣϯͷઃܭʹ΋ͪΌ Μͱ޲͖߹͏ͷͱಉٛ

Slide 63

Slide 63 text

SUMMARY

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Thank you !