開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. Next.js >
  4. PlaywrightでのNext.jsのコンポーネントテストでパスエイリアスを解決する
no-image

PlaywrightでのNext.jsのコンポーネントテストでパスエイリアスを解決する

結論だけ見たい方は こちら



こんにちは。タカギです。
みなさん、テスト書いてますか?

Next.jsのテスト方法について、公式ドキュメント でさまざまなテストフレームワークが紹介されています。
E2EテストではCypressかPlaywright、コンポーネント単位のテストやロジックのユニットテストではJestが使われることが多いのではないでしょうか(要出典)。

現在私が担当しているプロジェクトで、E2EテストではPlaywrightを導入しているものの、コンポーネントテストはどうしようか?という話になり、以下の2つの選択肢が上がりました。

  • Jestを導入する
  • Playwrightのみでやってしまう

今回は記事タイトルの通り、後者を選択しました。 理由としては、

  • JestのTypeScript対応がいまいち
  • 依存ライブラリを極力増やしたくない

といったところです。

しかしいざテストを書いて実行してみたところ、tsconfig.jsonで設定したパスエイリアスがPlaywrightのコンポーネントテストコードから解決できないエラーが発生しました。
本記事ではその解決方法を記します。

環境

  • OS: macOS Monterey 12.4
  • CPU: Apple M1 Max
  • Node.js v16.14.2
  • Next.js 12.2.4
  • React 18.2.0
  • TypeScript 4.7.4
  • Playwright 1.24.2

準備

Next.jsプロジェクトを作成

npx create-next-app@latest --ts

ドキュメント を参考にパスエイリアスを設定

tsconfig.jsonに追加

{
  "baseUrl": ".",
  "paths": {
    "@/components/*": ["components/*"]
  }
}

テスト対象のコンポーネントを作成

components/Hello.tsx

export default function Hello() {
  return (
    <p>Hello World</p>
  );
};

pages/以下から呼び出して動作を確認しておきます。

pages/hello/index.tsx

import Hello from "@/components/Hello";

export default function HelloPage() {
  return <Hello />
}

テスト導入

ここからが本題です

プロジェクトにPlaywrightをインストール

npm init playwright@latest -- --ct

いくつかテスト用のファイルが作成され、package.jsonに

{
  "scripts": {
    "test-ct": "playwright test -c playwright-ct.config.ts"
  }
}

が追記されます。

参考: https://playwright.dev/docs/test-components

テスト記述

test/Hello.spec.tsx

import { test, expect } from '@playwright/experimental-ct-react';
import Hello from "@/components/Hello";

test.use({ viewport: { width: 500, height: 500 } });

test('should work', async ({ mount }) => {
  const component = await mount(<Hello />);
  await expect(component).toContainText('Hello World');
});

テストを実行

npm run test-ct

ここで以下のエラーが出ました。

[vite]: Rollup failed to resolve import "@/components/Hello" from "playwright/index.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`

importを解決できないと言っているようです。
また、エラーメッセージから内部でViteが動いていることがわかります。

Playwrightをインストールした際に作成されたplaywright-ct.config.tsの型を見ると、ctViteConfigというプロパティがあり、ここでViteの設定を定義できるようです。
Viteのドキュメントを参考にエイリアスを設定しよう…と思ったのですが、2022年8月現在、公式ドキュメント にその設定方法は見当たりませんでした。

ただ、PlaywrightTestConfigの型定義を追っていくとresolvealiasなどそれらしいプロパティはあり、下記のように記述することでエイリアスが設定できるようです。

Viteの設定でエイリアスを定義

playwright-ct.config.ts

const config: PlaywrightTestConfig = {
  // 省略

  use: {
    // 省略

    ctViteConfig: {
      resolve: {
        alias: {
          '@/components/': `${__dirname}/components/`,
        }
      }
    }
  },
};

参考: https://vueschool.io/articles/vuejs-tutorials/import-aliases-in-vite/

再度テストを実行

再度テストを実行したところ、テストが成功することが確認できました。
また、いい感じのテストレポートがHTMLに出力されるので少し嬉しいです。(もちろんテストが落ちても作成されます)

最後に

Next.jsプロジェクトでPlaywrightを使用してコンポーネントテストが書けることを確認しました。
しかし2022年8月現在、コンポーネントテストはExperimental(実験的)とドキュメントにありますので、実際の業務のプロジェクトに導入する際はその点を理解した上で判断していただくようにお願いします。

ここまでお読みいただきありがとうございました。

TOPに戻る