Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
上手に付き合うコンポーネントテスト
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Yosuke Kurami
September 20, 2024
Programming
2.4k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
上手に付き合うコンポーネントテスト
Yosuke Kurami
September 20, 2024
More Decks by Yosuke Kurami
See All by Yosuke Kurami
TypeScript LSP の今までとこれから
quramy
1
2.2k
フロントエンドテストの育て方
quramy
12
3.9k
App Router 悲喜交々
quramy
8
770
Patched fetch did not work
quramy
6
810
GraphQL あるいは React における自律的なデータ取得について
quramy
18
6k
Next.js App Router
quramy
15
4k
Fragment Composition of GraphQL
quramy
17
4.9k
reg-viz VRT tools
quramy
4
1.8k
NoInfer
quramy
0
410
Other Decks in Programming
See All in Programming
SREの越境 / SRE Collaboration
y0hgi
2
290
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
410
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
400
Webの地図
yosuke_furukawa
PRO
6
5k
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
600
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
33
14k
AWSに止められる覚悟してますか?
morizo_1984
2
500
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
330
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
470
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.2k
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
77
5.6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
A designer walks into a library…
pauljervisheath
211
25k
The Language of Interfaces
destraynor
162
27k
sira's awesome portfolio website redesign presentation
elsirapls
0
440
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
260
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
710
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Transcript
্खʹ͖߹͏ ίϯϙʔωϯτςετ 2024.09.20 @Quramy
About me - id: @Quramy (GitHub / X ) -
͓ࣄ: Web ϑϩϯτΤϯυΤϯδχΞ - React, Next.js, GraphQL - ՝֎׆ಈ: ςετࢧԉܥπʔϧͷ࡞ - Prisma ORM ؔ࿈: jest-prisma, prisma-fabbrica - Visual Testing ؔ࿈: reg-suit, Storycap
Visual Testing ಉձ https://speakerdeck.com/quramy/reg-viz-vrt-tools?slide=6
Agenda - ίϯϙʔωϯτςετͷಋೖ - ίϯϙʔωϯτςετͷӡ༻
ಋೖฤ
ࣗಈςετͷత - εϐʔυΛଛͳΘͣʹ։ൃΛଓ͚ΔͨΊ - طଘͷػೳ͕ͳ͘ಈ࡞͚͍ͭͮͯ͠Δ͜ͱΛ୲อͯ͘͠ΕΔ - ϑϩϯτΤϯυͷ߹ʮݟ͕ͨͲͷΑ͏ʹมߋ͞ΕΔͷ͔ʯ͕Մࢹ Խ͞ΕΔͱɺϨϏϡΞଆͷ֬ೝίετݮʹͭͳ͕Δ
උ͑େࣄ - ϓϩδΣΫτ্ཱͪ͛࣌ίϯϙʔωϯτςετಋೖΛݟૹΔͷબ ࢶͱͯ͠ΞϦͱࢥ͏ - ͨͩ͠ɺޙ͔ΒಋೖͰ͖ΔΑ͏ʹඋ͓͑ͯ͘͜ͱॏཁ - ϓϩδΣΫτ͕ҭ͔ͬͯΒಥવʮΑ͠ ίϯϙʔωϯτͷ Visual
Testing Ζ͏ʂʯͱٸʹࢥཱ͍ͬͯɺθϩ͔ΒςετέʔεΛॻ͘ͷେม
ίϯϙʔωϯτςετͱ Storybook ίϯϙʔωϯτςετʹ Storybook Λ༻͍͍ͯΔཧ༝ - UI ίϯϙʔωϯτ։ൃج൫ͱͯ͠Չঢ়ଶ (ݸਓతʹଞͷπʔϧʹؤுͬͯ΄͍͕͠ɺStorybook ʹউͭͷ͕૬େมͳঢ়گʹͳ͍ͬͯ
Δͱࢥ͏) - Story ͕ςετέʔεͱͯ͠ྲྀ༻ՄೳͰ͋ΔͨΊɺʮͱΓ͋͑ͣ Story ͚ͩॻ ͘Α͏ʹ͓ͯ͘͠ʯ͕ίϯϙʔωϯτςετͷඋ͑ͱͳΔ - Storybook ͕ࣗಈςετʹؔ͢ΔػೳڧԽʹྗΛೖΕ͍ͯΔ - Jest / Vitest ࿈ܞ (compositeStories), test-runner, Chromatic, etc...
ίϯϙʔωϯτςετ with Storybook Storybook ͱ࿈ܞ͢ΔςετπʔϧςετϓϥοτϑΥʔϜ༷ʑͳͷ ͕͋ΔɻओཁͳͷΛհ (1/4) - Chromatic: https://www.chromatic.com/
Storybook ͷϗεςΟϯάࣗಈςετΛ݉Ͷඋ͑ͨ all-in-one ͳαʔϏ εɻStorybook ΦϑΟγϟϧ - Lost Pixel: https://www.lost-pixel.com/ VRT πʔϧɻChromatic ͷΑ͏ͳ SaaS ͱͯ͠ͷఏڙܗଶͷଞɺࣗલͷ CI ʹηϧϑϗετ͢Δ͜ͱՄೳͳπʔϧ
ίϯϙʔωϯτςετ with Storybook Storybook ͱ࿈ܞ͢ΔςετπʔϧςετϓϥοτϑΥʔϜ༷ʑͳͷ ͕͋ΔɻओཁͳͷΛհ (2/4) - Storycap: https://github.com/reg-viz/storycap
Storybook Λ Puppeteer ͰΫϩʔϧͯ͠ը૾Խ͢Δ CLI reg-suit reg-actions (͜ΕΒ reg-vizͷπʔϧ) ͱΈ߹ΘͤΔ͜ͱͰ ίϯϙʔωϯτ୯Ґͷ Visual Regression Test Λ࣮ݱ͢Δɻ Storybook x VRT ͱͯ͠ฮͷ෦ྨ (2017 ͔Β͋Δ)
ίϯϙʔωϯτςετ with Storybook Storybook ͱ࿈ܞ͢ΔςετπʔϧςετϓϥοτϑΥʔϜ༷ʑͳͷ ͕͋ΔɻओཁͳͷΛհ (3/4) - storybook/test-runner: https://storybook.js.org/docs/writing-tests/test-runner
Storybook ެࣜͷςετϥϯφʔɻࣗલ CI Ͱ Story ͷϨϯμϦϯά Play function Λ࣮ߦՄೳɻ jest-playwright Λ෦తʹར༻͍ͯ͠Δ - storycap-testrun: https://github.com/reg-viz/storycap-testrun storybook/test-runner Ͱར༻͢ΔεΫϦʔϯγϣοτϥΠϒϥϦɻ
ίϯϙʔωϯτςετ with Storybook Storybook ͱ࿈ܞ͢ΔςετπʔϧςετϓϥοτϑΥʔϜ༷ʑͳͷ ͕͋ΔɻओཁͳͷΛհ (4/4) - Jest /
Vitest: ୯ମςετͷπʔϧͰ͋Δ͕ɺStorybook ͕ఏڙ͢Δ composeStories ؔͱΈ߹ΘͤΔ͜ͱͰ Story ͷςετ͕Մೳɻ https://storybook.js.org/docs/writing-tests/import-stories-in-tests/ stories-in-unit-tests
͓͜ͱΘΓ - චऀ͕࣮ࡍʹӡ༻ͨ͜͠ͱͷ͋ΔίϯϙʔωϯτςετͷߏҎԼ: - Storybook + Storycap + reg-suit -
Storybook + Jest + compositeStories - Ҏ߱Ͱհ͢Δӡ༻ Tips ɺπʔϧͷબͱಠཱͨ͠༰ͱͳΔΑ͏ۃ ྗ৺͕͚͍ͯ·͕͢ɺ্هΛཹҙͯ͠Β͑Δͱॿ͔Γ·͢
ӡ༻ฤ
ӡ༻ฤ Εʂ ࣮ߦ࣌ؒ
Կ·Ͱ͑ΒΕΔʁ - Pull Request ࣌ͷ CI ࣮ߦ࣌ؒɺͲΕ͘Β͍·ͰզຫͰ͖·͔͢ʁ - ݸਓࠩ͋Δ͕ɺࣗͷ؍ଌൣғͰ 5ลΓʹᮢ͕͋Γͦ͏
- ίϯϙʔωϯτςετͷ࣮ߦ͕࣌ؒ͘ͳΕͳΔ΄ͲɺνʔϜͷϔΠ τ͕ཷ·͍ͬͯ͘
(ࢀߟ) ࣗಈςετ࣮ߦ࣌ؒਪҠ https://qiita.com/Quramy/items/46d0b09ae4d8887b0941 ߦ ίϯϙʔωϯτ έʔε $*࣮ߦ࣌ؒ
ฒྻ࣮ߦ (ϫʔΧʔϨϕϧ) - CI ͷ࣮ߦڥΛCPUΛ૿ڧͭͭ͠ɺ࣮ߦϒϥβ (worker) Λ૿͢ - GitHub Actions
Ͱ͋Εɺ Self Hosted Runner Ͱӡ༻͍ͯ͠Δਓ͚ - ίϯϙʔωϯτςετΛ࣮ߦ͢Δ CLI ͷΦϓγϣϯͰ worker Λมߋ: - Storycap CLI: --parallel Φϓγϣϯ - storybook/test-runner CLI: --max-workers Φϓγϣϯ
ฒྻ࣮ߦ (δϣϒϨϕϧ) - CI ͷ࣮ߦڥ͝ͱฒྻԽ͢Δύλʔϯ - GitHub Actions Ͱ͋Ε matrix
ͳͲͰ ฒྻδϣϒ࣮ߦՄೳ ※ ίϯϙʔωϯτςετ͕Δ·Ͱͷεςοϓ (ڥࣗମͷηοτΞοϓ npm i ͢Δ෦ ͳͲ) ͕େ͖͍ͱɺฒྻԽޮ͕Լ͕ΔͨΊ͕ඞཁ - storybook/test-runner Storycap ͷ --shard ΦϓγϣϯΛར༻͢Δ
ϥϯφʔΛ͍͚Δ - ࣮ϒϥβΛͬͨίϯϙʔωϯτςετ͍ͦͦ - શͯͷίϯϙʔωϯτͷςετͰɺৗʹϒϥβ͕ඞཁͱ͍͏Θ͚Ͱ ͳ͍ͣ (e.g. ϑΥʔϜόϦσʔγϣϯ aria ଐੑͷ֬ೝ)
- jsdom ͰेͳέʔεͰ͋ΕɺJest / Vitest + compositeStories ͷςε τίʔυͱ࣮ͯ͠ߦͰ͖Εɺ͘ͳΓʹ͍͘ - Storycap (= Puppeteer): 100 msec / story - Jest + jsdom: 10 msec / story
࣮ફฤ ௵ͤʂ Flakiness
Flaky Test μϝθολΠ - Flaky ͳςετͱ - ιʔείʔυʹมߋΛՃ͍͑ͯͳ͍ͷʹ ޭ/ࣦഊ ͕҆ఆ͠ͳ͍ঢ়ଶ
- ِཅੑ (False Positive) ࣗಈςετͷఢ - ಛʹ Visual Testing ݕূʹը૾Λ༻͍ΔͨΊ Flaky ςετʹؕΓ͍͢
VRT ʹ͓͚Δᮢͷௐ - ϒϥβʹίϯϙʔωϯτΛඳըͤ͞Δ߹্ɺશͳ pixel by pixel ͷ Ұக͍͠ -
e.g. CSS ͷ border-radius box-shadow ΞϯνΤΠϦΞε - [IMO] 100 ϐΫηϧ (ॎԣ 10px ͷਖ਼ํܗͷ໘ੵ) ఔͷࠩҟڐ༰ - 100 ఔͰِӄੑʹͳΔ͜ͱ໓ଟʹͳ͍ - [IMO] ը૾શମʹର͢ΔൺͰࢦఆ͢ΔͷͰ͋Εɺ 0.01% Λج४ʹ
෦తͳࠩ͠ସ͑ ίϯϙʔωϯτͷҰ෦͕ෆ҆ఆͳ߹ ( e.g. YouTube ຒࠐಈը, iframe) ɺ VRT ࣌ͷΈผ
div ʹࠩ͠ସ͑ͯɺFlaky Test ʹͳΒͳ͍Α͏ʹ͢Δ export function MyComponent() { return ( <div> {/* ͕͜͜ෆ҆ఆͳཁૉ */} <iframe style={{ height: 400, width: "100%" }} src="https://example.com/hogehoge" /> </div> ); } import { isScreenshot } from "storycap"; export function MyComponent() { return ( <div> {process.env.NODE_ENV !== "production" && isScreenshot() ? ( <div style={{ height: 400, background: "#888" }} /> ) : ( <iframe style={{ height: 400, width: "100%" }} src="https://example.com/hogehoge" /> )} </div> ); }
ͦΕͰμϝͳΒ skip - Ͳ͏ͯ͠ Flakiness Λ௵ͤͳ͍߹ɺͦͷέʔε(= Story) Λ ࣗಈςετର ֎ʹׂͯ͠Ε૭ԽΛࢭ͢Δ
- ίʔυΛมߋ͍ͯ͠ͳ͍ͷʹ CI Ͱ VRT ΛΒͤΔͨͼʹ͕ࠩग़ͯ͠· ͏ঢ়گΛ์ஔ͢ΔΑΓϚγ export const MyStory = { args: {}, // storybook/test-runner ͷ߹ tags: ["skip"], parameters: { screenshot: { // Storycap ͷ߹ skip: true, }, }, } satisfies Story;
͓ΘΓʹ - ίϯϙʔωϯτςετӡ༻ͷίπ - Slow Test / Flakey Test ݟա͝͞ͳ͍
- Off topics - Ұൠతͳࣗಈςετϊϋ (e.g. ςετίʔυͷೝෛՙରࡦ) ׆ ༻ͯ͠ɺΑΓշదͳϑϩϯτΤϯυςετΛࢦ͠·͠ΐ͏ - e.g. https://gihyo.jp/list/group/αόϯφศΓ- ~ ιϑτΣΞ։ൃͷ ߥΛੜ͖ൈ͘ ~
Thank you !