japa について
AdonisJS プロジェクト向けの Japa テストスキルです。ユニット、ブラウザー、API、コンソールのテスト設定に加え、データベースの後処理やテストダブルの指針を扱います。
主な機能
- 01ユニット・ブラウザースイートの設定
- 02スイート・ファイル・テストの指定実行
- 03認証とテスト環境の設定
- 04テスト間のデータベース状態管理
- 05API・ブラウザー・コンソールテストの案内
- 06テストダブルと後処理の運用
活用シーン
- 01AdonisJS プロジェクトのテスト設定
- 02対象を絞ったテストの実行
- 03テスト間のデータベース状態の分離
- 04API またはブラウザーテストの作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ lncitador/ adonisjs-maestro --skill japaインストール後、Claude Code で/japaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/api-tests.mdbrowser-tests.mdconsole-tests.mdtest-doubles.mdrunbooks/resource-tests.md詳細
Japa テストスキル
AdonisJS では、AdonisJS チームが開発・保守するバックエンドテストフレームワーク、Japa を使用します。Jest/Vitest とは異なり、Japa はトランスパイラーなしで Node.js 上でネイティブに実行でき、バックエンドテスト専用に設計されたプラグインを備えています。
スイートと構成
tests/
├── bootstrap.ts # plugins, hooks, suite config
├── unit/ # fast in-process tests
└── browser/ # end-to-end with Playwright
adonisrc.ts で定義するスイート:
tests: {
suites: [
{ files: ['tests/unit/**/*.spec.ts'], name: 'unit', timeout: 2000 },
{ files: ['tests/browser/**/*.spec.ts'], name: 'browser', timeout: 300000 },
],
forceExit: false,
}
bootstrap.ts
Hypermedia/Inertia スターターキット(ブラウザー+ユニットスイート):
import { assert } from '@japa/assert'
import app from '@adonisjs/core/services/app'
import type { Config } from '@japa/runner/types'
import { pluginAdonisJS } from '@japa/plugin-adonisjs'
import testUtils from '@adonisjs/core/services/test_utils'
import { browserClient } from '@japa/browser-client'
import { authBrowserClient } from '@adonisjs/auth/plugins/browser_client'
import { sessionBrowserClient } from '@adonisjs/session/plugins/browser_client'
export const plugins: Config['plugins'] = [
assert(),
pluginAdonisJS(app),
browserClient({ runInSuites: ['browser'] }),
sessionBrowserClient(app),
authBrowserClient(app),
]
export const runnerHooks: Required<Pick<Config, 'setup' | 'teardown'>> = {
setup: [() => testUtils.db().migrate()],
teardown: [],
}
export const configureSuite: Config['configureSuite'] = (suite) => {
if (['browser', 'functional', 'e2e'].includes(suite.name)) {
return suite.setup(() => testUtils.httpServer().start())
}
}
API スターターキット(apiClient プラグインを追加):
import { apiClient } from '@japa/api-client'
import { authApiClient } from '@adonisjs/auth/plugins/api_client'
import { sessionApiClient } from '@adonisjs/session/plugins/api_client'
import type { Registry } from '../.adonisjs/client/registry/schema.d.ts'
declare module '@japa/api-client/types' {
interface RoutesRegistry extends Registry {}
}
export const plugins: Config['plugins'] = [
assert(),
pluginAdonisJS(app),
apiClient(),
sessionApiClient(app),
authApiClient(app),
]
.env.test — テストでの認証には常に必要です:
SESSION_DRIVER=memory
テストの実行
node ace test # all suites
node ace test unit # specific suite
node ace test browser
node ace test --files="posts/index" # specific file
node ace test --files="posts/*" # folder wildcard
node ace test --tests="can list posts" # exact test title
node ace test --groups="Posts index" # group name
node ace test --watch # re-run on change
node ace test --bail # stop on first failure
node ace test --failed # re-run only failed tests
データベースの状態 — テストごと
グループごとに、いずれかの方法を選択します:
// Global transactions (faster — rolls back, nothing persisted)
group.each.setup(() => testUtils.db().withGlobalTransaction())
// Truncation (actual delete — slower but more compatible)
group.each.setup(() => testUtils.db().truncate())
bootstrap.ts ですべてのテストの前に一度だけマイグレーションを実行します:
runnerHooks.setup = [
() => testUtils.db().migrate(),
() => testUtils.db().seed(), // optional
]
複数の接続:
() => testUtils.db().migrate()
() => testUtils.db('tenant').migrate()
参考資料
| トピック | ファイル |
|---|---|
| API テスト — client.visit()、アサーション、認証 | references/api-tests.md |
| ブラウザーテスト — Playwright、フォーム、loginAs、Cookie | references/browser-tests.md |
| コンソールテスト — Ace コマンド、raw モード、プロンプト | references/console-tests.md |
| テストダブル — フェイク、スワップ、時刻、sinon | references/test-doubles.md |
ランブック
| 機能 | ファイル |
|---|---|
| CRUD リソースのテストスイート全体 | runbooks/resource-tests.md |
アンチパターン
| 誤り | 正しい方法 |
|---|---|
| テスト間で DB をクリーンアップしない | group.each.setup で withGlobalTransaction() または truncate() を使用する |
SESSION_DRIVER を memory に設定していない | loginAs を機能させるには .env.test で必須です |
using または .restore() を使わずにフェイクを使用する | 自動復元には using fake = mail.fake() を使用する |
group.each.setup で sinon.restore() を呼び出す | group.each.teardown で sinon.restore() を呼び出す |
group.each.setup で redis.flushdb() を呼び出す | group.each.teardown で実行する(実行前ではなく後にクリアする) |
| DB クエリをモックする | 実際のテスト DB にアクセスする — モックでは制約エラーを検出できません |
コミット済みのテストで record() を使う | コード生成にのみ使用し、visit() に置き換える |
| タイトルを正確に一致させずにプロンプトを設定する | タイトルでは大文字と小文字が区別されます — コマンドから正確にコピーしてください |
コメント
Markdown 対応