Skip to content

Latest commit

 

History

History
202 lines (153 loc) · 12.6 KB

test.md

File metadata and controls

202 lines (153 loc) · 12.6 KB

🧪テスト

フロントエンド開発においてもテスト自動化はメジャーなものとなってきました。テストの必要性や方法論を掴むため、まずは以下の文献がおすすめです🦁

テストは大きく分類すると

  • 静的(Static)テスト
  • 単体(Unit)テスト
  • 結合(Integration)テスト
  • E2E(end to end)テスト

にわけられ、名称や範囲の違いからシナリオテストやビジュアルリグレッションテストなどが存在します。 詳細はこちらをご覧ください。

一方で、テスト自動化の導入はコストは決して低くなくメンテナンスの問題が否めません。
メジャーになってきた傾向のあるフロントエンドのテストですが、テストに慣れていないメンバーが多い場合記述コストが高くつき過ぎてしまうケースも否めません。

たしかなことは費用対効果が高ければ導入すべきということです。(資料🦁)

上記を全体的に鑑み、本リポジトリでは記述コストとメンテナンスコストをできるだけ低く漸進的なテストの導入を目指します。

方針

基本的に先ほどの資料を踏襲します。

  1. トレードオフの観点でバランスのよい結合テストを厚めに書く
  2. E2E テストは、課金導線やタイムラインなどの、不具合が発生するとビジネス上のネガティブインパクトの大きい箇所だけ書く
  3. 単体テストは、明らかにテストしなくても自明なロジックに対しては書かない。複雑性が高いビジネスロジックの関数に関しては書く
  4. 静的テストはベースラインとして必ず引く。導入が後回しになればなるほど導入コストが跳ね上がるので、プロジェクトの最初に必ず入れる

これをベースに本リポジトリに落とし込んでいきましょう。

結合テスト

model-componentに対して実行します。したがって対象は以下です。

  • src/components/features
  • src/component/pages/Component
  • src/component/pages/Component/components/Component

featuresには再利用可能なmodel-componentが格納されているため基本的に記述します。
結合テストの区分は曖昧であるためpagesのテスト戦略は場合によって異なります。API通信やビジネスロジックがトップのpages/Componentに集中しているのであればこちらに記述すると良いでしょう。
一方で、pagesはview-componentのようにレイアウト的な役割が主なこともあるはずです。そのような切り分けの場合は子ディレクトリにmodel-componentが集中するはずですのでそちらにテストを書いていきましょう。

ツールはJesttesting-libraryを用います。

E2Eテスト

基本的に必須ではありません。記述する場合は「不具合が発生するとビジネス上のネガティブインパクトの大きい箇所」に追加します。

ツールにはPlaywrightを用います。

単体テスト

グローバルなhooksに対して記述します。各コンポーネントのロジックは結合テストでカバーされているため書かない想定です。 例外として、ロジックのあるようなpartsには記述した方が良いかもしれません。例を挙げるとスナックバーやモーダルなどになります。

ツールにはJesttesting-libraryを用います。

導入ツール

本プロジェクトには以下のツールを導入しています。

それぞれの使い方と参考文献を以下に記載します。

Storybook

カタログツールです。src/parts配下のコンポーネントを管理し再利用性を高めます。
最近ですとStorybook Playfunctionという機能が追加されテストの実行や可視化ができるようになりました。 大変便利な機能ではあるのですが、Storybookは破壊的な変更が多くまたストーリーの管理にもコストがかかります。 費用対効果を考えた際に重要なことは「コンポーネントの管理と再利用性の向上」であると考え、本リポジトリではカタログとテストは分離しコンポーネントの管理に専念してもらうこととしました。

後述するyarn partsコマンドを実行すると.storyファイルが自動生成されます。

import { action } from '@storybook/addon-actions'
import type { ComponentMeta, ComponentStoryObj } from '@storybook/react'

import { ComponentName } from './ComponentName'

export default {
  component: ComponentName,
} as ComponentMeta<typeof ComponentName>

export const Default: ComponentStoryObj<typeof ComponentName> = {
  args: { text: 'サンプルボタン', handleClick: action('ボタン押下') },
  parameters: {
    docs: {
      description: {
        component: 'Some component _markdown_',
      },
    },
  },
}
export const Story: ComponentStoryObj<typeof ComponentName> = {
  args: { text: 'サンプルボタン', handleClick: action('ボタン押下') },
  parameters: {
    docs: {
      description: {
        story: 'Some story **markdown**',
      },
    },
  },
}

yarn parts時にコンポーネント名の入力が求められ、そちらの内容がComponentNameとして扱われ雛形が出力されます。
したがって私たちが主に追記するのはargs部です。サンプルコードのtexthandleClickがコンポーネントのpropsに対応していますので、作成したコンポーネントに合わせて修正してください。 parameters.docs.descriptionはStorybookのドキュメントに表示される説明文です。componentはコンポーネントの、storyはストーリーの説明文になります。

場合に応じてStoryを増やし、バリエーションを増やすことが可能です。

参考文献

Mock Service Worker

API通信をモック化するツールです。開発時やテストの際に仮のAPIサーバーとして用います。そもそもなぜこちらのツールを使うのか。という点についてはこちらをご覧ください。なぜMock Service Workerなのか。入門編

.mocksフォルダに必要なファイルが格納されており、主にhandler.tsを編集しモックしたいエンドポイントとレスポンスを追加します。.mocks/index.tsをからエクスポートされているserverもしくはworkerが実行されることによりモッキングが開始します。

本リポジトリではあらかじめ_app.tsxにてworker.start()が動くよう設定されていますので、開発時はhander.tsに記述を追加していくだけでモックAPIが追加可能です。 テスト時はコンポーネント単位、またnode環境で実行されるため別途mswを起動する必要があります。
こちらを参考に以下のようなコードを追加しましょう。

describe("コンポーネントのテスト", () => {
    // Establish API mocking before all tests.
    beforeAll(() => server.listen());
    // Reset any request handlers that we may add during the tests,
    // so they don't affect other tests.
    afterEach(() => server.resetHandlers());
    // Clean up after the tests are finished.
    afterAll(() => server.close());

    //以下にテストケースを記述
});

英語になってしまいますが、詳しい使い方は公式ドキュメントのDocsやExampleがよくまとまっています。また、実践的な使い方についてはこちらもご覧ください。

参考文献

Jest/testing-library

単体、結合テスト用のライブラリです。本リポジトリでは主にsrc/components/featuresに対する結合テスト、src/hooksへの単体テストに用います。

はじめにJesttesting-library別のライブラリだということを抑えてください。
まず、JestはJavascript用のテストランナーであり以下のような関数のテストができます。

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

Nodeサーバーならこれで十分かもしれませんが、私たちの目指すゴールはReactのコンポーネントをテストすることです。したがって、testing-libraryを導入することによりJSXのレンダリングやHooksが動く環境を作りコンポーネントの要素取得やインタラクティブなテストを実現します。

import { Sample } from "@/components/Sample";
import { render } from "@testing-library/react";

describe("Sampleコンポーネント", () => {
  test("should first", () => {
    const { getByText } = render(<Sample />);
    expect(getByText("Nextjs+Jestのサンプルサプリ")).toBeTruthy();
    expect(getByText("設定がすごく楽になりました。")).toBeTruthy();
  });
});

https://zenn.dev/miruoon_892/articles/e42e64fbb55137 より引用

より詳細を掴むにはReactでTesting Library/Jestを使ってテストを学ぼうJest, testing-libraryの公式ドキュメントがおすすめです。

参考文献

Playwright

E2Eテスト用のライブラリです。/e2eに記述します。使い方は公式ドキュメントを参考にしてください。
また、playwrightにはユーザー操作によるテストコード自動生成機能があります。
本リポジトリでは以下のコマンドで実行可能です。

yarn test:e2e:codegen

参考文献




>>「🐶ファイル生成(Scaffold)」へ進む