概要
以前プロジェクトにStorybookを導入しました。
その後、ある程度規模の大きい開発が入ったためコンポーネントが追加されましたが、Storybookの対応ができていませんでした。
今回まとめてテスト追加等含めてメンテナンスしてみます。
Storybook関連の記事はこちら↓です。
バージョン更新
まずは新しいバージョンが出ていたので、バージョン更新します。
$ npx sb upgrade
※マイグレーションについて聞かれるのでyと答える
自動テスト追加
ひとまずのゴール
- stories.mdxがcromium環境で正常に開けるかチェック(破損していないか)
上記はだけでは、npm run storybobk実行後、ブラウザで確認できるコンポーネントしかテスト対象になりません。
つまり、必要なstoriesファイルが不足しており、そもそもブラウザで確認できない場合はテスト対象外となります。
そこで以下の対応も追加します。
- atomsのvueコンポーネントファイルに対応するstories.mdxが全て存在するかチェック
自動テストの候補
StoryShots
以前よく使われていたようなので使おうと思いましたが、非推奨になるので移行ガイドに従ってみます。
マイグレーション先は2種類。
1. Portable Stories
こちらは情報が少ないため2のtest-runnerを使う。
2. test-runner(情報が多いためこちらを使う)
こちらを使用すると実際にchromeなどのブラウザで、Storyが正常に開けるか等のテストが行えます。
Storybook test-runner は、あなたのストーリーをすべて実行可能なテストに変換します。JestとPlaywrightを搭載しています。スタンドアロンでフレームワークに依存しないユーティリティで、Storybookと並行して動作します。play関数によるインタラクションテスト、DOMスナップショット、アクセシビリティテストなど、複数のテストパターンをマルチブラウザ環境で実行できます。
導入
$ npm install @storybook/test-runner --save-dev
設定
package.jsonに以下を追加
"test-storybook": "test-storybook --url http://localhost:6006",
stories.mdxを使用している場合は、上記のままでは以下のようにテスト対象ファイルを見つけられない場合があります。
$ npm run storybook-test
> client_vue@0.1.0 storybook-test
> test-storybook --url http://localhost:6006
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /your/project/path
485 files checked.
testMatch: /your/project/path/stories/**/*.stories.mdx, /your/project/path/stories/**/*.stories.@(js|jsx|ts|tsx) - 0 matches
testPathIgnorePatterns: /node_modules/ - 485 matches
testRegex: - 0 matches
Pattern: - 0 matches
そこで、--stories-jsonを追加しておきます。
"test-storybook": "test-storybook --stories-json --url http://localhost:6006",
さらに.storybook/main.jsに以下を追加します。
module.exports = {
// 省略
features: {
buildStoriesJson: true // これを追加
},
// 省略
}
テスト実行
まずstroybookを起動させてからテストを実施します。
$ npm run storybook
$ npm run test-storybook
テスト実行時に以下のようなエラーが発生した場合、
Error: Executable doesn't exist at /Users/yourname/Library/Caches/ms-playwright/chromium-1091/chrome-mac/Chromium.app/Contents/MacOS/Chromium
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ npx playwright install ║
║ ║
║ <3 Playwright Team ║
╚═════════════════════════════════════════════════════════════════════════╝ Failed to launch browser.
必要に応じて以下のコマンドを実行し、最新のchromiumをインストール
$ npx playwright install
再度テスト実行
$ npm run test-storybook
> client_vue@0.1.0 test-storybook
> test-storybook --stories-json --url http://localhost:6006
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/06b3322848fb97ab5618598b36fe0209/components-atoms-vkselectbtn.test.js
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/06b3322848fb97ab5618598b36fe0209/components-atoms-vkbtn.test.js
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/06b3322848fb97ab5618598b36fe0209/components-atoms-vkstickyfooter.test.js
~~~~~~~~~~~~~~~~~~~~~~~~~~~
省略
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Test Suites: 53 passed, 53 total
Tests: 74 passed, 74 total
Snapshots: 0 total
Time: 11.905 s
Ran all test suites.
[test-storybook] Cleaning up /private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/06b3322848fb97ab5618598b36fe0209
対象stories.mdxが全て存在するかチェックするスクリプトを追加
以下のスクリプトを追加します。
"test-all-storybook": "chmod +x .storybook/scripts/check-stories-exist && .storybook/scripts/check-stories-exist",
次に、/.storybook/scripts/check-stories-existを追加します。
#!/bin/bash
# このスクリプトは、client_vueディレクトリで
# run test-all-storybookによって実行してください。
# ANSIエスケープコードを変数に格納
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# atomsに存在するコンポーネントのファイル名を取得
atoms_file_names=()
for file in $PWD/src/components/atoms/*.vue; do
filename=$(basename -- "$file")
atoms_file_names+=("${filename%.vue}")
done
# atomsに存在するstoryファイル名を取得
stories_file_names=()
for file in $PWD/stories/components/atoms/*.stories.mdx; do
filename=$(basename -- "$file")
stories_file_names+=("${filename%.stories.mdx}")
done
missing_stories_names=($(comm -23 <(printf "%s\n" "${atoms_file_names[@]}" | sort) <(printf "%s\n" "${stories_file_names[@]}" | sort)))
missing_stories_file_names=("${missing_stories_names[@]/%/.stories.mdx}")
wrong_stories_file_names=($(comm -13 <(printf "%s.stories.mdx\n" "${atoms_file_names[@]}" | sort) <(printf "%s.stories.mdx\n" "${stories_file_names[@]}" | sort)))
is_pass=false
is_pass_missing_file_test=false
is_pass_wrong_file_test=false
if [ ${#missing_stories_file_names[@]} -eq 0 ]; then
echo -e "${GREEN}PASS: 不足stories.mdxファイルはありません${NC}"
is_pass_missing_file_test=true
else
echo -e "${RED}ERROR:stories.mdxが不足しています、以下のファイルを自動生成します。${NC}"
for file in "${missing_stories_file_names[@]}"; do
echo -e " ${RED}./stories/components/atoms/${file}${NC}"
done
is_pass_missing_file_test=false
fi
if [ ${#wrong_stories_file_names[@]} -eq 0 ]; then
echo -e "${GREEN}PASS: 不要なstories.mdxファイルはありません${NC}"
is_pass_wrong_file_test=true
else
echo -e "${RED}ERROR: 以下のstories.mdxのファイル名が間違っている、または不要です。削除・修正してください。${NC}"
for file in "${wrong_stories_file_names[@]}"; do
echo -e " ${RED}./stories/components/atoms/${file}${NC}"
done
is_pass_wrong_file_test=false
fi
if [ "$is_pass_wrong_file_test" = true ] && [ "$is_pass_missing_file_test" = true ]; then
is_pass=true
fi
if $is_pass; then
npm run test-storybook
else
# 足りないstoriesファイルを自動生成する
for file_name in ${missing_stories_names[@]}; do
$(grep -q "slot" ${PWD}/src/components/atoms/${file_name}.vue)
has_slot=$?
if [ ${has_slot} -eq 0 ]; then
has_slot="y"
else
has_slot="n"
fi
expect -c "
set timeout 5
spawn npm run hygen:stories
expect \"コンポーネントの名前を指定してください\"
send \"${file_name}\n\"
expect \"storyを生成する対象のコンポーネントが配置されているディレクトリの、src以下のパスを指定してください。\"
send \"components\/atoms\n\"
expect "Slotsは持ちますか?"
send \"${has_slot}\n\"
interact
"
done
fi
テスト実施
テストの結果、不足しているstories.mdxファイルがある場合以下のようになります。
さらに、以下の記事で設定したstories.mdxファイルの自動生成スクリプトが実行され、
不足ファイルが生成されます。
$ npm run test-all-storybook
> client_vue@0.1.0 test-all-storybook
> chmod +x .storybook/scripts/check-stories-exist && .storybook/scripts/check-stories-exist
ERROR: stories.mdxが不足しています、以下のファイルを自動生成します。
VkAudioTag.stories.mdx
VkCaution.stories.mdx
VkLoading.stories.mdx
VkSecondaryBtn.stories.mdx
VkSpacer.stories.mdx
VkSubTitle.stories.mdx
PASS: 不要なstories.mdxファイルはありません
成功した場合は、test-runnnerまで実行されます。
npm run test-all-storybook
> client_vue@0.1.0 test-all-storybook
> chmod +x .storybook/scripts/check-stories-exist && .storybook/scripts/check-stories-exist
PASS: 不足stories.mdxファイルはありません
PASS: 不要なstories.mdxファイルはありません
> client_vue@0.1.0 test-storybook
> test-storybook --stories-json --url http://localhost:6006
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/f6cf69158ba11254bc13750363cde930/components-atoms-vkstepprogressarrow.test.js
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/f6cf69158ba11254bc13750363cde930/components-atoms-vkstickyfooter.test.js
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/f6cf69158ba11254bc13750363cde930/components-atoms-searchresultnotfound.test.js
PASS browser: chromium ../../../../../../../private/var/folders/pb/9tvfmpzd5gx6lzfb0yppqs3w0000gp/T/f6cf69158ba11254bc13750363cde930/components-atoms-vksmallcheckboxarray.test.js
~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~
Test Suites: 58 passed, 58 total
Tests: 82 passed, 82 total
Snapshots: 0 total
Time: 31.387 s
Ran all test suites.
まとめ
新機能等の開発で忙しくなると、Storybookのメンテナンスがどうしても後回しになってしまうことが分かってきました。
更新忘れがあると後々負債になってしまうので、少しずつメンテナビリティが高くなるように改善をしていきたいですね。運用は難しい...