codeceptjs-fundamentals について
CodeceptJS 4 プロジェクト向けのテスト作成スキルです。設定の確認、シナリオ構成、ロケーター、プラグインを扱い、ユーザー視点の読みやすいテストを重視します。
主な機能
- 01CodeceptJS 4 設定の確認
- 02ユーザーシナリオに沿ったテスト構成
- 03セマンティックロケーターの利用
- 04Actor、ページオブジェクト、Helper の整理
- 05プラグイン、アサーション、並列実行の設定
活用シーン
- 01既存プロジェクトのブラウザーテスト作成
- 02再利用可能なページ操作の整理
- 03任意の UI 手順と再試行への対応
- 04失敗テストの診断情報の収集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ codeceptjs/ skills --skill codeceptjs-fundamentalsインストール後、Claude Code で/codeceptjs-fundamentalsを入力して読み込まれたか確認します。
詳細
CodeceptJS の基本
順番に 2 つの作業を行います。まず以下のルールを確認し、次にこのプロジェクトでどのような設定がされているかを調べます。
条件
- CodeceptJS 4 は ESM/TypeScript のみに対応しています。テスト、設定ファイル、ページオブジェクト、ヘルパーでは
import/exportを使用します。 - package.json に
"type": "module"がない場合は、何よりも先に追加します。 - TypeScript の場合:設定ファイルは
codecept.conf.ts、require: [...]に TS ローダーのエントリを指定します。 - プロジェクトが 3.x または CommonJS(
require()、削除済みのautoLoginなどのプラグイン、Nightmareヘルパー)を使用している場合は、そこで作業を止め、migrate-codeceptjs-4を推奨します。ファイルを個別に修正してはいけません。プロジェクト全体の移行が必要です。
基本ルール
- テストはユーザーの視点で記述します。文章のように読みやすい、一連のアクションで構成します。
- 良い例:
I.click('Login')、I.fillField('Email', ...)、I.see('Welcome')
- 良い例:
- テストは宣言的に、ヘルパーは命令的に記述します。推奨されるレイヤー構成:
- シナリオには
I.*を使ってユーザーが 何をするか を記述し、実装の詳細は下位レイヤーに置きます - シナリオ内での低レベルアクセス(
this.helpers['Playwright'].page、fetch、ファイルシステム)は問題ありませんが、ヘルパーに移し、I.*アクションとして公開することを推奨します
- シナリオには
- テストは短く保ちます。繰り返しの処理は、アクターメソッド、ページオブジェクト、またはステップオブジェクトにまとめます。
- マークアップが変更されてもテストが壊れないよう、セレクターよりセマンティックロケーターを優先します。
配置場所(推奨)
- サイト全体で使うアクション(
login、ドロップダウン、リッチテキストエディター)→ アクターファイル(カスタムステップ) - ページ/画面のアクションとロケーター → ページオブジェクト。SPA の画面ごとに 1 つのページオブジェクト
- サイト全体で使うウィジェット(ナビゲーション、モーダル、日付選択)→ ページフラグメント/コンポーネントオブジェクト
- 低レベルのドライバーアクセス(DB 接続、メール、ファイルシステム、複雑なマウス操作)→ ヘルパー
- API を使ったデータの作成/クリーンアップ → データオブジェクト(REST/GraphQL ヘルパー+
_after()によるクリーンアップ)、またはApiDataFactory(I.have(...)) - 過度に設計しないでください。テスト間で抽象化が再利用されるまでは、ページオブジェクトを作成しないでください。
近道
- ログインが必要 → テストごとにインラインで手順を書くのではなく、
autoLoginプラグインまたはアクターメソッドを使います - テストデータ → UI からではなく、テストの前に API 経由で作成します
- 長いテスト → 複数に分割します。長いテストは壊れやすく、追いにくくなります
- UI 要素が任意、または条件付きのフロー →
if (await I.grab...)ではなくawait tryTo(...)を使います。シナリオを直線的に保てます
アーキテクチャ
- 設定:リポジトリのルートにある
codecept.conf.{js,ts,mjs,cjs。複数のファイルを使う場合は--config <file>で選択します。 - ヘルパーが実行し、
Iが委譲します。 すべてのI.<method>は、それを実装するアクティブなヘルパー(Playwright、WebDriver、Puppeteer、Appium は共通の API を提供します)にルーティングされます。アクティブなヘルパーはhelpersのキーで指定します。テストはエンジンではなく、アクターを呼び出します。バックエンドは差し替え可能な状態を保ちます。 - DI コンテナ — その役割:
- 共有するすべての要素(アクター、ヘルパー、ページオブジェクト、サポートオブジェクト)は 1 つのコンテナに登録されます。
includeで名前をモジュールに対応付けます - クラスはコンテナによって自動的にインスタンス化されます。
newや手動での配線は不要です inject()は遅延プロキシを返します。モジュールのトップレベルで分割代入しても、解決は呼び出し時に行われるため、通常のimportではundefinedになる循環ページオブジェクト参照も機能します- アクセス方法:Scenario のシグネチャで分割代入します(
Scenario('...', ({ I, loginPage }) => ...))。または、ファイルごとに 1 回const { I } = inject()を呼び出します
- 共有するすべての要素(アクター、ヘルパー、ページオブジェクト、サポートオブジェクト)は 1 つのコンテナに登録されます。
- カスタムヘルパーは
Helperを継承し、helpersに登録して、新しいI.*メソッドを追加します。- ヘルパー内に
Iは存在しません。this.helpers['<HelperName>']を使って組み合わせます(例:this.helpers['Playwright'].page、this.helpers['REST'].sendGetRequest(...))。
- ヘルパー内に
- プラグインは、ライフサイクルイベント(
suite.*、test.*、step.*、hook.*、multiple.*)のイベントリスナーです。一覧はnode_modules/codeceptjs/lib/event.jsを参照してください。pluginsにenabled: trueを設定して登録します。
設定変更の落とし穴
@codeceptjs/configureは、読み込み時に解決済みの設定を変更します(setHeadlessWhen、setBrowserなど)。静的な値は実態と異なる場合があります。show:/browser:フィールドを信頼する前に、インポート箇所を grep してください。setCommonPlugins():retryFailedStepとscreenshotを有効化し、pause、browser、aiTrace、healを(-pが指定されるまでオフの状態で)登録します。
知っておくと便利なプラグイン
retryFailedStep— 一時的なステップの失敗を再試行しますscreenshot— 失敗時にスクリーンショットを撮影します。slides: trueを指定すると、スライドショーoutput/records.htmlを生成しますpageInfo— 失敗時に URL/HTML/コンソールを出力しますauth— ログイン用にセッションを再利用します(codeceptjs-authスキルを参照)aiTrace— AI によるデバッグ用に、ステップごとのスクリーンショット/HTML/ARIA/コンソールを記録しますpause— 対話形式で一時停止しますheal— 壊れたステップに対する AI の修正案を提示します(--debugではオフ)screencast— 実行中の動画を記録しますcustomLocator—$nameプレフィックスをチームのテスト属性(data-testid、data-qa)にマッピングしますbrowser— ブラウザーヘルパー設定を CLI からのみ上書きします(下記を参照)
注:tryTo、retryTo、eachElement は 4.x ではプラグインではありません。codeceptjs/effects からインポートしてください。
CLI からのプラグイン指定
任意のプラグインを -p <plugin> で実行ごとに有効化/再設定できます。引数は : で連結します。
npx codeceptjs run -p aiTrace # enable for this run
npx codeceptjs run -p screenshot:on=step # reconfigure inline
npx codeceptjs run -p pause:on=file:path=tests/login_test.js;line=43
screenshot、pause、aiTrace、healはon=トリガーを共有します:fail(aiTrace 以外のデフォルト) |step|test|file:path=...;line=N|url:pattern=<glob>browserプラグインは設定ファイルに触れずに上書きします。CI マトリックスの各実行環境や、一時的な環境のバリエーションに使用できます。-p browser:hide/-p browser:show/-p browser:browser=firefox/-p browser:windowSize=1280x800@codeceptjs/configureが必要です
エフェクト(codeceptjs/effects)
codeceptjs/effects からインポートするフロー制御関数です。4.x ではプラグイン/グローバルではなくなりました。
tryTo(() => ...)— テストを停止させずに、失敗する可能性のあるステップを実行します。booleanを返します。ifよりtryToを優先してください: シナリオは直線的に保つ必要があります。UI の状態が存在するかどうかを取得した値に基づいて分岐するのではなく、任意のステップを試行し、結果の真偽値で分岐してください。const banner = await tryTo(() => { I.see('Cookie banner'); I.click('Accept cookies') }) if (!banner) I.say('No cookie banner')tryToブロック内では自動再試行は無効になります。
retryTo(() => ..., maxTries, pollInterval = 200)— ステップのブロックが成功するまで再試行します(不安定な要素、アニメーションなど)。コールバックには現在の試行回数が渡されます。hopeThat(() => ...)— ソフトアサーションです(アサーションを参照)。最後にhopeThat.noErrors()を呼び出してください。within(locator | { frame }, fn)— サブツリーまたは iframe の範囲内に解決対象を限定します。値を返すこともできます(awaitを使用)。可能な場合は、個々のアクションのコンテキストパラメーター(I.click('Save', '.toolbar'))を優先してください。withinは、本当に範囲を限定する必要があるブロックに使用します。
すべてのエフェクトは Promise を返します。await を付けてください。
要素ベースの API(codeceptjs/els)
ハイブリッドなスタイルで、I.* と要素への直接アクセスを組み合わせます。{ element, eachElement, expectElement, expectAnyElement, expectAllElements } from 'codeceptjs/els' をインポートしてください。
element(locator, async el => { ... })— 1 つの要素にスコープを限定してアクセスします。el.$(locator)を連結すると、再検索せずに子要素を指定できますeachElement(locator, async (el, index) => ...)— 要素のコレクションを反復処理しますexpectElement/expectAnyElement/expectAllElements(locator, fn)— 独自の条件を指定します- 要素は
WebElementラッパーです。すべてのヘルパーで同じ API を使用できます:getText()、getAttribute()、isVisible()、isEnabled()、getBoundingBox()、exists()、$$() - 用途を示す文字列を任意で指定すると、デバッグログが分かりやすくなります:
element('verify discount applied', '.price', ...) - 組み込み機能では対応できない場合に使用します:コレクション、レイアウトチェック(
getBoundingBox)、要素ごとのループ、1 つの要素に対する操作の連結。それ以外は読みやすさを優先し、I.*を使用してください。
テストの作成
- 構成:1 ファイルにつき
Feature(...)は 1 つ、その中にScenario(...)を 1 つ以上記述します。ネストしたスイートや、1 ファイル内の複数の Feature は使用しません。 - フック:
Before、After、BeforeSuite、AfterSuite、Fail(...)。 - ページオブジェクトのライフサイクルフック:
_before()(遅延実行、テストごとに 1 回、初回使用時)、_after()(未使用の場合はスキップ)、_beforeSuite()、_afterSuite()。 awaitが必要な対象:grab*メソッド、インポートした関数、非同期処理を含むページオブジェクトのメソッド(それ以外では未処理の拒否が発生します)。通常のアクションステップには不要です。レコーダーがチェーン処理します。- シークレット:
I.fillField('Password', secret(process.env.PASSWORD))を使用すると、ログ、トレース、AI プロンプトで値がマスクされます。codeceptjsからインポートしてください。 - セッション:
session(name, fn)は、複数ユーザーの Scenario(チャット、マルチテナントなど)向けの並列ブラウザーコンテキストです。
ロケーター
- ARIA ロケーターが最も強力です。CSS のリファクタリングにも強く、ユーザーに見える内容を表現できます。
I.click({ role: 'button', name: 'Save' })
- アクションには、通常の文字列(表示テキスト、ラベル、プレースホルダー、
name、aria-label)またはオブジェクト({ css }、{ xpath }、{ id })を指定できます。 - 通常の文字列はすでに
aria-labelにも一致するため、'aria-label=...'というプレフィックスは不要です。 - コンテキストは最後の引数として渡します。スコープを指定したセマンティックロケーターは、スコープなしの長いロケーターよりも適切です。
I.click('#toolbar .btn-save')ではなく、I.click('Save', '.toolbar')を使用します。
- スタイルに基づくクラス名(
.bg-green)は避け、セマンティックなもの(.btn-save)を優先します。 data-testid/data-qaを使うアプリでは、customLocatorを有効にして$nameを記述します。- 適切なセマンティック名がない場合は、
locate(...)ビルダー(.withClass、.withText、.inside、.and)を使用します:locate('.button').withText('Click me')。
待機
- アクションステップは、要素の存在と操作可能性を自動で待機します。条件が操作に結びつかない場合(ネットワーク呼び出し後のモーダル表示、スピナーの非表示など)のみ、明示的な
waitFor*を追加します。 I.wait(N)は避けてください。最後の手段としてのみ使用します。
アサーション
まず、組み込みのブラウザーアサーションを使用します:I.see、I.seeTextEquals、I.seeElement、I.seeInField、I.seeNumberOfElements、I.seeInCurrentUrl(および対応する dontSee*)。失敗内容が明確で、レコーダーと統合されています。see は表示されているテキストに一致します。非表示の DOM コンテンツには seeInSource/seeElementInDOM が必要です。
組み込み機能で対応できない場合は、次の優先順位で使用します。
- ヘルパー内の再利用可能なカスタムアサーション —
I.seeTableIsOrdered('Price', 'desc')。肯定形にはsee*、否定形にはdontSee*という名前を付けます。内部ではcodeceptjs/assertionsを使用し、throw new Error()を直接使わないでください。 - ExpectHelper(
@codeceptjs/expect-helper)—Iで Chai マッチャーを使用できます:I.expectEqual、I.expectDeepEqualExcluding、I.expectMatchesPattern、I.expectJsonSchema。ほかのステップと同様に、ステップログに表示されます。 codeceptjs/assertionsを直接使用 — 依存関係のないファクトリーです:equals(subject).assert(actual, expected)/.negate(...)。失敗メッセージはI.seeと同じ形式です。- 取得したデータに任意のライブラリを使用(
grab*では常にawaitが必要です)— Chai、Jest、node:assertなど。テストは失敗しますが、ステップとしては表示されません。
ソフトアサーション:codeceptjs/effects の hopeThat(() => I.see(...)) を使用すると、失敗をそれぞれ記録しながら処理を続行できます。最後に hopeThat.noErrors() を実行すると、記録された失敗がある場合にテストを失敗させます。
並列実行
run-workers <N>— Scenario をワーカースレッドに分割します。run-multiple <profile>— 設定のmultipleブロックで定義したプロファイル(ブラウザー、ビューポート)を使用します。
設定の整理(推奨)
- 環境ごとに複数の設定ファイル(
codecept.conf.js、codecept.ci.conf.jsなど)を用意し、config/ディレクトリ内のモジュールで共通部分を共有します。 - シークレットや環境固有の値には、
.envファイルとdotenvを使用します。 - エクスポートされたマップを
includeに展開して、ページオブジェクト/コンポーネントを一括登録します。 codeceptjs.container.append({ testUser })を使って、設定/ブートストラップからテストにデータを渡します。名前で注入できます。
このプロジェクトを調べる
以下の順番で進めてください。手順を飛ばすと、誤った推測につながります。
- セットアップが読み込まれることを確認する:
npx codeceptjs check -c <config>— すべてを検証します。出力はインベントリも兼ねています。続行する前に失敗を修正してください。 - 有効な設定を読む:ヘルパー(ブラウザー/baseURL/ビューポート/環境変数に依存する値を含む)、プラグイン(
setCommonPlugins()が追加するものも含む)、AI プロバイダーと必須の環境変数、環境の選択方法、includeによるページオブジェクト、カスタムヘルパー。 - アクションを一覧表示する:
npx codeceptjs list -c <config>(--docsで JSDoc を追加、--action <name>で 1 つのアクションを指定)。カスタムヘルパーがある場合、実際に使えるI.*の範囲は組み込みのものとは異なります。メソッドを提案する前に、必ず確認してください。 - テストを一覧表示する:
npx codeceptjs dry-run -c <config>—--stepsでキューに追加されたアクションを表示し、--grepで絞り込み、--numbersで MCP のpauseAtに対応するテストごとのステップ番号を表示します。- ⚠
dry-run --grepとrun --grepでは、選択されるテストが同じではありません(4.1.0):run --grepはFeatureとScenarioに一致しますが、dry-run --grepはScenarioのタイトルのみに一致します。dry-run --grep 'Dialogs'ではテストが 0 件表示される一方、run --grep 'Dialogs'では 11 件すべてが実行されます。dry-run の grep 結果から実行件数を見積もらないでください。選択対象を正確にする必要がある場合は、ファイルパスで Feature 全体を指定してください(run tests/foo_test.ts)。
- ⚠
Gherkin プロジェクトの場合:npx codeceptjs gherkin:steps -c <config>。
リファレンスドキュメントは node_modules/codeceptjs/docs/ にあります。API を推測するのではなく、そちらを読んでください。
レポート
簡潔な文章で概要をまとめてください。以下を必ず含めてください。
- 環境変数に依存する値は、環境変数に依存することが分かるように記載する(
process.env.BROWSER || 'chromium'とし、'chromium'だけにしない) - 設定の競合を指摘する(静的な
show: trueとsetHeadlessWhen(CI)、authが設定されているが認証情報の環境変数がない場合) - ルートに設定がなく、
--configも指定されていない場合は、npx codeceptjs init .を推奨して終了する - 3.x/CommonJS が検出された場合は、
migrate-codeceptjs-4を推奨して終了する