refactoring-codeceptjs-tests について
CodeceptJS 4のテストを、動作を変えずにリファクタリングするスキルです。重複するUIフロー、ロケーター、ブラウザー処理を適切なページオブジェクト、アクターステップ、カスタムヘルパーへ移し、提案と検証を段階的に行います。
主な機能
- 01重複フローと長いロケーターの検出
- 02フローをページオブジェクトやアクターステップへ移動
- 03生のブラウザー処理をカスタムヘルパーへ抽出
- 04適用前にファイル単位で変更を提案
- 05各バッチ後に対象Scenarioを再実行
活用シーン
- 01重複するUIテスト手順の整理
- 02テスト間でのロケーター重複の削減
- 03ブラウザー処理やデータ準備をScenarioから分離
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ codeceptjs/ skills --skill refactoring-codeceptjs-testsインストール後、Claude Code で/refactoring-codeceptjs-testsを入力して読み込まれたか確認します。
詳細
CodeceptJS 4 テストのリファクタリング
テストスイートが劣化する原因は、主に予測可能な3つです。ファイル間でコピー&ペーストされた重複する UI フロー、あちこちで繰り返される肥大化したロケーター、Scenario に入り込む生の JS です。それぞれの解決策は、動作を変えずにパターンを適切な場所へ移すことです。
対象を絞った(ユーザーが指定したファイルまたは Scenario)場合と、全体(設定済みの tests glob 全体)のいずれにも対応します。どちらの場合も、まず提案し、承認後にレビューしやすい単位で適用します。
ワークフロー
- 基礎情報 —
codeceptjs-fundamentalsを実行します。include配下のページオブジェクト、アクターファイル、カスタムヘルパー、認証ロールが必要です。これらが分からないと、抽出先を判断できません。 - スコープを決める:
- 対象を絞る — 一度読み、提案し、適用します。
- 全体 — 複数のパスでサイクルを回します:棚卸し → グループ化して提案 → 承認 → バッチを適用 → 影響を受ける Scenario を再実行 → 次のバッチ。決して一度に大規模な編集を行いません。
- 棚卸し — 次を確認します:
- 2つ以上の Scenario にまたがって繰り返される
I.*のシーケンス - 2か所以上で使われるロケーター、複数行の XPath/深くネストした CSS
- 領域を内包するスコープのないロケーター(
'.sidebar nav a.settings')、'aria-label=X'形式の指定、呼び出し箇所に直接書かれた生の[data-testid=...] - 複数の文からなる
I.executeScript、ビジネス処理を行うusePlaywrightTo/usePuppeteerTo/useWebDriverTo - ハードコードされた認証情報、URL、マジックストリング
I.wait(N)と、通常のアクションに対する不要なawait— 見つけたらその場で修正します
- 2つ以上の Scenario にまたがって繰り返される
- 重複するフロー → ページオブジェクトのメソッド — ユーザーの意図に沿った名前を付けます(
loginPage.signIn(email, pass)、cartPage.removeItem(name))。3回のルール:2回目に出現した時点で抽出します。1回だけのコードはそのままにします。 - 肥大化したロケーター — ビルダーを使う前に分割します。構造を示す部分はコンテキスト引数にし、残りは意味のある文字列として残します。
I.click('.sidebar nav a.settings')→I.click('Settings', '.sidebar')I.click({ css: '[aria-label="Save"]' })→I.click('Save', '.toolbar')I.click({ css: '[data-qa=submit]' })→customLocatorを使ってI.click('$submit', '.checkout')分割後に残った部分だけでlocate()が必要です。1回だけ使う場合は呼び出し箇所に直接記述し、2回以上使う場合は.as('description')を付けた名前付き PO フィールドにして、失敗時に意味のある名前が表示されるようにします。
- 生の JS → カスタムヘルパー —
I.executeScriptのブロック、DOM をたどる処理やビジネスロジックを行うusePlaywrightTo、Scenario 内で手書きした fetch 処理が対象です。基礎情報のルールを忘れないでください:ヘルパー内にIは存在しません —this.helpers['<Name>']を使って組み合わせます。テストでは引き続きI.*の語彙を使います。 - ログインの重複 —
loginPage.signInメソッドは作らないでください。codeceptjs-authに任せます。それがauthプラグインの役割です。セッションを再利用できる場合、ログイン用 PO は設計上の問題を示す兆候です。 - サイト全体のアクション(
I.acceptCookies()、I.goToBilling())— 個々のページの PO ではなく、アクターファイル(custom_steps.js)に置きます。特定のページがアクションを単独で所有しない場合に適切な場所です。
判断基準
| パターン | 配置先 |
|---|---|
| 1つのページ内の UI フロー | そのページの PO のメソッド |
| ページをまたぐ、サイト全体の UI フロー | アクター(custom_steps.js) |
| ログイン | auth プラグイン(codeceptjs-auth を参照) |
| 領域を内包する長いロケーター | 短く意味のあるロケーター + コンテキスト引数 |
| 1回だけ使う長いロケーター | インラインの locate() |
| 2回以上使う長いロケーター | PO フィールドに保存した locate() |
| 生のブラウザー API/ファイルシステム/DB/メール | カスタムヘルパー |
| API を呼び出すテストデータのセットアップ | REST ヘルパー + データオブジェクト |
先に提案し、その後に適用
提案は配置先のファイルごとにグループ化します(pages/loginPage.js、helpers/DbHelper.js、tests/checkout_test.js)。編集前に一覧を提示します。全体モードでは、明示的な承認を得て、3~5ファイルずつバッチ処理し、各バッチの後に再実行します:
npx codeceptjs run --grep '<scenario or feature>' --steps
結果を codeceptjs-run-analysis に渡し、影響を受けるすべての Scenario が引き続き成功し、失敗が新しいステップに移っていないことを確認します。実行しないリファクタリングはリファクタリングではありません。
避けること
- リファクタリング後に、影響を受けたシナリオを再実行しないこと。
- 1 回しか使われないフローを抽出しないこと。2 回目の出現を待ちます。
- 呼び出し元をすべて grep せずに PO のメソッドやフィールドを改名しないこと。
- ページオブジェクトで対応できるのに、カスタムヘルパーを作成すること。
- 異なるフローを 1 つのメソッドにまとめること(
loginPage.do(thing)は要注意です)。 - シナリオ名やタグに手を加えること。CI と
--grepが参照しています。 - バッチ処理や再実行をせずに、グローバルモードで一括適用すること。
関連スキル
codeceptjs-fundamentals— 主なルール、各要素の配置場所、アーキテクチャ(Iに到達できないルール)codeceptjs-auth— ログイン処理の重複排除codeceptjs-run-analysis— リファクタリング後の検証
コメント
Markdown 対応