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

上手に付き合うコンポーネントテスト

Avatar for Yosuke Kurami Yosuke Kurami
September 20, 2024

 上手に付き合うコンポーネントテスト

Avatar for Yosuke Kurami

Yosuke Kurami

September 20, 2024
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. About me - id: @Quramy (GitHub / X ) -

    ͓࢓ࣄ: Web ϑϩϯτΤϯυΤϯδχΞ - React, Next.js, GraphQL - ՝֎׆ಈ: ςετࢧԉܥπʔϧͷ࡞੒ - Prisma ORM ؔ࿈: jest-prisma, prisma-fabbrica - Visual Testing ؔ࿈: reg-suit, Storycap
  2. ίϯϙʔωϯτςετͱ Storybook ίϯϙʔωϯτςετʹ Storybook Λ༻͍͍ͯΔཧ༝ - UI ίϯϙʔωϯτ։ൃج൫ͱͯ͠Չ઎ঢ়ଶ (ݸਓతʹ͸ଞͷπʔϧʹ΋ؤுͬͯ΄͍͕͠ɺStorybook ʹউͭͷ͕૬౰େมͳঢ়گʹͳ͍ͬͯ

    Δͱࢥ͏) - Story ͕ςετέʔεͱͯ͠ྲྀ༻ՄೳͰ͋ΔͨΊɺʮͱΓ͋͑ͣ Story ͚ͩॻ ͘Α͏ʹ͓ͯ͘͠ʯ͕ίϯϙʔωϯτςετͷඋ͑ͱͳΔ - Storybook ͕ࣗಈςετʹؔ͢ΔػೳڧԽʹྗΛೖΕ͍ͯΔ - Jest / Vitest ࿈ܞ (compositeStories), test-runner, Chromatic, etc...
  3. ίϯϙʔωϯτςετ 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 ʹηϧϑϗετ͢Δ͜ͱ΋Մೳͳπʔϧ
  4. ίϯϙʔωϯτςετ 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 ೥͔Β͋Δ)
  5. ίϯϙʔωϯτςετ 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 Ͱར༻͢ΔεΫϦʔϯγϣοτϥΠϒϥϦɻ
  6. ίϯϙʔωϯτςετ 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
  7. ͓͜ͱΘΓ - චऀ͕࣮ࡍʹӡ༻ͨ͜͠ͱͷ͋Δίϯϙʔωϯτςετͷߏ੒͸ҎԼ: - Storybook + Storycap + reg-suit -

    Storybook + Jest + compositeStories - Ҏ߱Ͱ঺հ͢Δӡ༻ Tips ͸ɺπʔϧͷબ୒ͱಠཱͨ͠಺༰ͱͳΔΑ͏ۃ ྗ৺͕͚͍ͯ·͕͢ɺ্هΛཹҙͯ͠΋Β͑Δͱॿ͔Γ·͢
  8. ฒྻ࣮ߦ (ϫʔΧʔϨϕϧ) - CI ͷ࣮ߦ؀ڥΛCPUΛ૿ڧͭͭ͠ɺ࣮ߦϒϥ΢β (worker) ਺Λ૿΍͢ - GitHub Actions

    Ͱ͋Ε͹ɺ Self Hosted Runner Ͱӡ༻͍ͯ͠Δਓ޲͚ - ίϯϙʔωϯτςετΛ࣮ߦ͢Δ CLI ͷΦϓγϣϯͰ worker ਺Λมߋ: - Storycap CLI: --parallel Φϓγϣϯ - storybook/test-runner CLI: --max-workers Φϓγϣϯ
  9. ฒྻ࣮ߦ (δϣϒϨϕϧ) - CI ͷ࣮ߦ؀ڥ͝ͱฒྻԽ͢Δύλʔϯ - GitHub Actions Ͱ͋Ε͹ matrix

    ͳͲͰ ฒྻδϣϒ࣮ߦՄೳ ※ ίϯϙʔωϯτςετ͕૸Δ·Ͱͷεςοϓ (؀ڥࣗମͷηοτΞοϓ ΍ npm i ͢Δ෦෼ ͳͲ) ͕େ͖͍ͱɺฒྻԽޮ཰͕Լ͕ΔͨΊ޻෉͕ඞཁ - storybook/test-runner ΍ Storycap ͷ --shard ΦϓγϣϯΛར༻͢Δ
  10. ϥϯφʔΛ࢖͍෼͚Δ - ࣮ϒϥ΢βΛ࢖ͬͨίϯϙʔωϯτςετ͸ͦ΋ͦ΋஗͍ - શͯͷίϯϙʔωϯτͷςετͰɺৗʹϒϥ΢β͕ඞཁͱ͍͏Θ͚Ͱ͸ ͳ͍͸ͣ (e.g. ϑΥʔϜόϦσʔγϣϯ΍ aria ଐੑͷ֬ೝ)

    - jsdom Ͱे෼ͳέʔεͰ͋Ε͹ɺJest / Vitest + compositeStories ͷςε τίʔυͱ࣮ͯ͠ߦͰ͖Ε͹ɺ஗͘ͳΓʹ͍͘ - Storycap (= Puppeteer): ਺100 msec / story - Jest + jsdom: ਺10 msec / story
  11. Flaky Test μϝθολΠ - Flaky ͳςετͱ͸ - ιʔείʔυʹมߋΛՃ͍͑ͯͳ͍ͷʹ ੒ޭ/ࣦഊ ͕҆ఆ͠ͳ͍ঢ়ଶ

    - ِཅੑ (False Positive) ͸ࣗಈςετͷఢ - ಛʹ Visual Testing ͸ݕূʹը૾Λ༻͍ΔͨΊ Flaky ςετʹؕΓ΍͍͢
  12. VRT ʹ͓͚Δᮢ஋ͷௐ੔ - ϒϥ΢βʹίϯϙʔωϯτΛඳըͤ͞Δ౎߹্ɺ׬શͳ pixel by pixel ͷ Ұக͸೉͍͠ -

    e.g. CSS ͷ border-radius ΍ box-shadow ΍ ΞϯνΤΠϦΞε - [IMO] 100 ϐΫηϧ (ॎԣ 10px ͷਖ਼ํܗͷ໘ੵ) ఔ౓ͷࠩҟ͸ڐ༰ - 100 ఔ౓ͰِӄੑʹͳΔ͜ͱ͸໓ଟʹͳ͍ - [IMO] ը૾શମʹର͢Δൺ཰Ͱࢦఆ͢ΔͷͰ͋Ε͹ɺ 0.01% Λج४ʹ
  13. ෦෼తͳࠩ͠ସ͑ ίϯϙʔωϯτͷҰ෦͕ෆ҆ఆͳ৔߹ ( 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> ); }
  14. ͦΕͰ΋μϝͳΒ skip - Ͳ͏ͯ͠΋ Flakiness Λ௵ͤͳ͍৔߹ɺͦͷέʔε(= Story) Λ ࣗಈςετର ৅֎ʹׂͯ͠Ε૭ԽΛ๷ࢭ͢Δ

    - ίʔυΛมߋͯ͠΋͍ͳ͍ͷʹ CI Ͱ VRT Λ૸ΒͤΔͨͼʹࠩ෼͕ग़ͯ͠· ͏ঢ়گΛ์ஔ͢ΔΑΓ͸Ϛγ export const MyStory = { args: {}, // storybook/test-runner ͷ৔߹ tags: ["skip"], parameters: { screenshot: { // Storycap ͷ৔߹ skip: true, }, }, } satisfies Story;
  15. ͓ΘΓʹ - ίϯϙʔωϯτςετӡ༻ͷίπ - Slow Test / Flakey Test ͸ݟա͝͞ͳ͍

    - Off topics - Ұൠతͳࣗಈςετϊ΢ϋ΢ (e.g. ςετίʔυͷೝ஌ෛՙରࡦ) ΋׆ ༻ͯ͠ɺΑΓշదͳϑϩϯτΤϯυςετΛ໨ࢦ͠·͠ΐ͏ - e.g. https://gihyo.jp/list/group/αόϯφศΓ- ~ ιϑτ΢ΣΞ։ൃͷ ߥ໺Λੜ͖ൈ͘ ~