unit-tests について
bklit-ui向けに、ユニットテストを追加する場面と方法を示すスキルです。純粋なロジックやユーザーに見える回帰を優先し、脆弱なテストや網羅率だけを目的とするテストを避けます。
主な機能
- 01テストの追加・省略の判断基準
- 02Node組み込みテストランナーとtsx
- 03テスト配置とアサーションのパターン
- 04パッケージとTurboのテスト設定
- 05テスト判断チェックリスト
活用シーン
- 01変更にテストが必要か評価
- 02純粋なヘルパーの回帰テスト追加
- 03新規パッケージのテスト設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bklit/ bklit-ui --skill unit-testsインストール後、Claude Code で/unit-testsを入力して読み込まれたか確認します。
詳細
ユニットテスト(bklit-ui)
テストを提案または作成する前に、このスキルを読んでください。基本方針:数を絞り、シグナルの強いテストを作成します。
テストを追加する場合
気付かないうちに壊れやすい動作を固定できる場合に、テストを追加します。
| テストする価値があるもの | 理由 |
|---|---|
| 純粋関数/モジュール | 入力が安定すれば出力も安定し、高速で、DOM も不要です |
| フォーマッター、パーサー、スケール計算、境界値 | 文字列/数値の出力に関するリグレッションはユーザーから見えます |
| コード生成/エクスポート/レジストリのヘルパー | 出力の形式が契約です |
| 一見して分かりにくいエッジケース | 空のデータ、範囲の逆転、クランプ処理 |
このリポジトリでの例: chart-formatters.test.ts、highlight-segment-bounds.test.ts、animation.test.ts、apps/web/lib/studio/__tests__/*。
テストを追加しない場合(明示的に依頼された場合を除く)
カバレッジを増やしたり「念入りに」確認したりするだけのために、テストを追加しないでください。
| 省略するもの | 理由 |
|---|---|
| React コンポーネントのレンダリングスモークテスト | visx、motion、ポータルは壊れやすいため、手動確認やドキュメントの確認のほうが低コストです |
memo()/ガードの切り出し(#65 のようなケース) | 構造的なパフォーマンス改善で、出力は変わりません。RTL によるマウント検証は負荷が高いです |
| デフォルトのプロパティ受け渡し | formatValue = intFmt の場合、型とフォーマッターテストでカバーできます |
| サードパーティライブラリの動作 | d3、visx、React を再テストしないでください |
| 単純なゲッター/1 行のラッパー | リグレッションのシグナルがありません |
| チャートの SVG/JSX 全体のスナップショット | 変更頻度が高く、シグナルが弱いです |
ユーザーから「X をテストすべきですか?」と聞かれた場合、X がこの表に当てはまるならいいえと回答し、より軽い代替案(純粋なヘルパーのテスト、手動確認、CI ビルド)を提案してください。
リポジトリの規約
テストランナー: Node 組み込みのテストランナー+tsx(後にリポジトリで採用されない限り、Jest/Vitest は使いません)。
pnpm test # root — turbo runs packages with a test script
pnpm --filter @bklitui/ui test
cd apps/web && pnpm test
テストの配置場所: テスト対象のコードと同じ階層にある **/__tests__/**/*.test.ts。
パターン:
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { myFn } from "../my-module";
describe("myFn", () => {
it("handles empty input", () => {
assert.equal(myFn([]), expected);
});
});
同等性テスト(フォーマッターで推奨):共有モジュールの出力が、以前のインライン呼び出し(例:同じロケール/オプションを使った toLocaleDateString)と一致することを検証します。タイムゾーンに左右されず、視覚的なリグレッションがないことを確認できます。
新しいパッケージのテストスクリプト: package.json に追加します。
"test": "node scripts/run-tests.mjs"
__tests__ から *.test.ts を収集して node --import tsx --test を実行する、小さな scripts/run-tests.mjs を使用してください。シェルのグロブは Linux CI で動作しないためです。tsx がない場合は devDependency として追加します。ルートの turbo.json の test タスクに接続し、CI では pnpm test を実行します。
判断チェックリスト(作成前に確認)
- ロジックは純粋ですか、それとも純粋関数に切り出せますか? → そこをテストします。まず切り出しを検討してください。
- 実際にユーザーから見えるバグがあれば、テストは失敗しますか? → 有力な候補です。
- jsdom/RTL/Playwright が必要ですか? → いったん止めて、ユーザーに理由を説明するか、手動/視覚確認に回してください。
- ユーザーはテストを依頼しましたか? → それでもこのスキルに従い、必要以上に対応しないでください。
- ケースはいくつ必要ですか? → 網羅的な組み合わせではなく、焦点を絞った 3~10 ケースにします。
ユーザーへの説明
テストを推奨する際は、内容を明確に伝えます。
- 追加:「
chart-formatters.tsをテストします。純粋で、リグレッションを検出する価値が高いためです。」 - 省略:「memo の分割に対するコンポーネントテストは省略します。出力に変化はなく、ビルドとチャートのドキュメントの手動確認で十分です。」
- CI: テストを追加または変更する場合は、PR のテスト計画に
pnpm testを記載します。
アンチパターン
- チームの合意なしに、単発の対応のために Jest/Vitest/Testing Library を追加する
useMemoの呼び出し回数を検証するために、チャートのコンテキスト全体をモックする- 実装の詳細(フックの順序、内部コンポーネント名)をテストする
- 型チェッカーの処理を重複させる(
expect(typeof x).toBe('function')) - タイムゾーン/ロケールをハードコードした文字列により、ローカル環境でしか通らないテストをコミットする