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

腐らないUIテストのためのStorybook + Storyshots / #react_kyoto v0.3.0

腐らないUIテストのためのStorybook + Storyshots / #react_kyoto v0.3.0

React.kyoto v0.3.0 ( https://react-kyoto.connpass.com/event/137847/ )でStorybookとStoryshotsを使ったコンポーネントのUIテストについて話しました。
質問・不備・マサカリ等はTwitterにてメンションつけてもらえると嬉しいです。
Twitter: https://twitter.com/shisama_

Masashi Hirano

July 19, 2019
Tweet

More Decks by Masashi Hirano

Other Decks in Programming

Transcript

  1. ෗Βͳ͍UIςετͷͨΊͷ
    Storybook + Storyshots
    react.kyoto v0.3.0
    ฏ໺ণ࢜ @shisama

    View Slide

  2. ฏ໺ ণ࢜ / Masashi Hirano
    @shisama_
    @shisama
    Node.js Core Collaborator
    ؔ੢NodeֶԂOrganizer

    View Slide

  3. એ఻

    View Slide

  4. Agenda
    • ίϯϙʔωϯτҰཡΛ֬ೝ͢Δ(Storybook)
    • ίϯϙʔωϯτͷڍಈΛ֬ೝ͢Δ(Storybook)
    • εφοϓγϣοτςετΛߦ͏(Storyshots)
    • ϝϯςφϯεҡ࣋ՄೳͳUIςετΛ

    Storybook + StoryshotsͰ࣮ݱ͢Δ

    View Slide

  5. Ұ౓͸ࢥͬͨ͜ͱ͕ͳ͍Ͱ͔͢…?
    • ૿͑͗ͨ͢ίϯϙʔωϯτΛҰཡͰݟ͍ͨ
    • ౉͢propsʹԠͨ͡දࣔΛνΣοΫ͍ͨ͠
    • ݸʑͷίϯϙʔωϯτͷදࣔΛνΣοΫ͠ͳ͕
    ΒϨϏϡʔ͕͍ͨ͠

    View Slide

  6. https://storybook.js.org/

    View Slide

  7. Storybook
    • ίϯϙʔωϯτΛҰཡදࣔ͢Δπʔϧ
    • ݸʑͷίϯϙʔωϯτͷද͕ࣔݟΕΔ
    • ౉͢propsʹԠͨ͡ද͕ࣔݟΕΔ
    • React, Vue, AngularʹରԠ

    View Slide

  8. View Slide

  9. ίϯϙʔωϯτ͕Ұཡ
    දࣔ͞ΕΔ
    ֤ίϯϙʔωϯτͷςετέʔε
    ίϯϙʔωϯτͷදࣔ݁Ռ

    View Slide

  10. import React from 'react';
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
    import { faHeart } from '@fortawesome/free-regular-svg-icons';
    type Props = {
    count: number;
    onClick: React.MouseEventHandler;
    };
    export const Like = ({ count, onClick }: Props) => {
    return (
    <>


    {count}

    >
    );
    };
    e.g. Likeίϯϙʔωϯτ

    View Slide

  11. Storybookಋೖ
    • @storybook/cliΛ࢖͏
    • BabelͷઃఆΛߦ͏
    • Storybook༻ͷwebpack.config.jsΛ࡞੒
    • StorybookͷઃఆϑΝΠϧΛฤू

    View Slide

  12. @storybook/cli
    • npx -p @storybook/cli sb init --type react
    • StorybookͷઃఆΛࣗಈͰߦͬͯ͘ΕΔCLI
    • npm-scripts௥Ճ
    • StorybookͷઃఆϑΝΠϧ࡞੒
    • Storybookͷαϯϓϧίʔυ࡞੒

    View Slide

  13. @storybook/cli
    TUPSZCPPLͷઃఆϑΝΠϧ
    TUPSZCPPLͷίʔυ
    JOEFYTUPSJFTKTαϯϓϧ

    View Slide

  14. Babelͷઃఆ
    • Storybook͸BabelΛ࢖͍ͬͯΔ
    • TypeScript΍React༻ʹpresetͳͲ͕ඞཁ
    • @babel/core
    • @babel/preset-typescript
    • @babel/preset-react

    View Slide

  15. module.exports = ({ config }) => {
    config.module.rules.push({
    test: /\.tsx?$/,
    use: [
    {
    loader: require.resolve('ts-loader')
    },
    {
    loader: require.resolve('react-docgen-typescript-loader')
    }
    ]
    });
    config.resolve.extensions.push('.ts', '.tsx');
    return config;
    };
    .storybook/webpack.config.js
    OQNJ%UTMPBEFS
    OQNJ%SFBDU
    EPDHFOUZQFTDSJQU

    View Slide

  16. import { configure } from '@storybook/react';
    // ͜ͷrequire.contextͰಡΈࠐΉର৅ͷ֦ுࢠΛ.js͔Β.tsxʹฤू
    // const req = require.context('../stories', true, /\.stories\.js?$/);
    const req = require.context('../stories', true, /\.stories\.tsx?$/);
    function loadStories() {
    req.keys().forEach(filename => req(filename));
    }
    configure(loadStories, module);
    .storybook/config.js
    ॳظ஋Ͱ͸KTΛࢦఆ͍ͯ͠Δ
    ͷͰUTY ͳͲʹมߋ

    View Slide

  17. import React from "react";
    import { storiesOf } from "@storybook/react";
    import { Like } from "../src/components/Like";
    storiesOf("Like", module).add("0", () => (
    {}} />
    )).add("1", () => (
    {}} />
    ));
    Storybook༻ͷίʔυΛॻ͘
    FHDPVOU͕AAͱAAͷ৔߹
    ͷTUPSJFTΛ௥Ճ͢Δ

    View Slide

  18. ࣮ߦ (npm run storybook)

    View Slide

  19. View Slide

  20. View Slide

  21. Storybook՝୊఺
    • ίϯϙʔωϯτΛमਖ਼ͨ͠ͱ͖ʹStorybookͷ
    ίʔυ͸ޙճ͠͞Εϝϯς͞Εͳ͘ͳ͍ͬͯ͘
    • ࣗಈςετ͢Δ΋ͷͰ͸ͳ͍ͨΊ໨ࢹͷνΣο
    Ϋ͕ඞཁ

    View Slide

  22. https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core

    View Slide

  23. Storyshots
    • StorybookͷίʔυΛ࢖͍ࣗಈςετ(εφοϓ
    γϣοτςετ)Λߦ͏
    • ίϯϙʔωϯτΛमਖ਼࣌ʹStorybookͷίʔυ
    ΋मਖ਼͠ͳ͍ͱεφοϓγϣοτςετ͕ࣦഊ
    ͢Δ

    View Slide

  24. Storyshotsಋೖ
    • StoryshotsΠϯετʔϧ
    • JestΠϯετʔϧ
    • Jestͷઃఆ
    • Babelͷઃఆ

    View Slide

  25. StoryshotsΠϯετʔϧ
    • StoryshotsΛΠϯετʔϧ
    • @storybook/addon-storyshots
    • Storyshotsͷ࣮ߦʹඞཁͳύοέʔδΛΠϯε
    τʔϧ
    • babel-plugin-require-context-hook
    • react-test-renderer

    View Slide

  26. JestΠϯετʔϧ
    • jestͱbabel-jestΛΠϯετʔϧ
    • babel-jestͰ͸ͳ͘ts-jestΛ࢖͏ͱ࣮ߦ࣌ʹܕ
    νΣοΫ΋ͯ͘͠ΕΔ
    • babel-jestͷํ͕ಋೖ͸؆୯
    • ܕνΣοΫ͸tscͰߦ͏
    • λεΫ͸ࡉ෼Խͯ͠ฒྻॲཧͰ͖ΔΑ͏ʹ

    View Slide

  27. Jestͷઃఆ
    • Jest࣮ߦʹඞཁͳsetupFilesΛ࡞੒
    • εφοϓγϣοτςετͷίʔυΛ࡞੒
    • jest.config.jsΛ࡞੒

    View Slide

  28. Jestͷઃఆ - setupFiles࡞੒
    // .jest/register-context.ts
    import registerRequireContextHook from “babel-plugin-
    require-context-hook/register";
    registerRequireContextHook();

    View Slide

  29. Jestͷઃఆ - ςετϑΝΠϧ࡞੒
    // stories/__tests__/Like.test.ts
    import initStoryshots from "@storybook/addon-storyshots";
    initStoryshots();

    View Slide

  30. Jestͷઃఆ - jest.config.js࡞੒
    module.exports = {
    setupFiles: ["/.jest/register-context.ts"],
    testMatch: ["/stories/__tests__/*.test.ts"]
    };
    ϑΝΠϧͷ৔ॴ͸೚ҙ

    View Slide

  31. Babelͷઃఆ
    {
    "presets": [
    [
    "@babel/preset-env",
    {
    "targets": {
    "node": "current"
    }
    }
    ],
    "@babel/preset-typescript",
    "@babel/preset-react"
    ],
    "env": {
    "test": {
    "plugins": ["require-context-hook"]
    }
    }
    }
    KFTUDPOpHKTͷઃఆϑΝΠ
    ϧͷͨΊʹQSFTFUFOWΛΠ
    ϯετʔϧ
    UFTUͷͱ͖͚ͩSFRVJSF
    DPOUFYUIPPL͕ݺ͹ΕΔΑ
    ͏ʹ͓ͯ͘͠

    View Slide

  32. ࣮ߦ (npx jest)
    4OBQTIPUϑΝΠϧ͕࡞੒͞
    Εͨ

    View Slide

  33. ࣮ߦ݁Ռ (εφοϓγϣοτϑΝΠϧ)
    4OBQTIPUϑΝΠϧ͕࡞੒͞
    Εͨ

    View Slide

  34. ࣮ߦ݁Ռ (εφοϓγϣοτϑΝΠϧ)

    View Slide

  35. ίϯϙʔωϯτΛमਖ਼ͨ͠ͱ͖
    ྫ͑͹ɺQSPQTͷ໊લ͕ม
    Θͬͨͱ͖

    View Slide

  36. ࣮ߦ (npx jest)
    લճςετ͔࣌Β݁Ռ͕ม
    ΘͬͨͨΊςετࣦഊ

    View Slide

  37. Storybook՝୊఺͕ղܾ
    • ίϯϙʔωϯτΛमਖ਼ͨ͠ͱ͖ʹStorybookͷίʔυ͸
    ޙճ͠͞Εϝϯς͞Εͳ͘ͳ͍ͬͯ͘

    ⇛Storybookͷίʔυ΋ม͑ͳ͍ͱςετ͕௨Βͳ͍ͷ
    ͰϝϯςඞਢͱͳΔ

    • ࣗಈςετ͢Δ΋ͷͰ͸ͳ͍ͨΊ໨ࢹͷνΣοΫ͕ඞཁ

    ⇛テスト自動化

    View Slide

  38. ·ͱΊ
    • StorybookͰίϯϙʔωϯτ͝ͱͷUIΛνΣο
    ΫͰ͖Δ
    • StoryshotsͰςετࣗಈԽ͠ɺStorybookΛ෗Β
    ͞ͳ͍Α͏ʹ͢Δ

    View Slide

  39. https://github.com/shisama/react-storybook-storyshots-example
    ࠓճͷσϞ

    View Slide

  40. Thanks.
    @shisama_
    shisama

    View Slide