はじめに
CodeceptJS では Vitest や Playwright のように特定のテストケースやスイートのみを実行したり、一時的にスキップしたりするための簡単な記法が用意されています。
公式ドキュメントに基づいてテストのフィルタリング方法を整理します。
また、フィルタリングした内容が誤って残ってしまうのを防ぐため、ESLint のカスタムルールを適用する方法を紹介します。
※カスタムルールの詳細な仕様や、Linter を開発フローにどう組み込むかの運用のお話はしませんので、ご了承ください。
注意事項
記事掲載時点、CodeceptJS は ESModules にまだ対応していないようです。
Migrate CodeceptJS to ESM (Top-level await) · Issue #4185 · codeceptjs/CodeceptJS
そのため、本記事内のコードでは基本 ESModules の記法に統一していますが、
import
→ require
など、適宜プロジェクトの状況によって読み替えてください。
環境情報
OS: Windows 11
Visual Studio Code: 1.100.2
CodeceptJS: 3.7.3
ESLint: v9.27.0
CodeceptJS のテストフィルタリング
.only
:特定のテストだけを実行
Scenario.only
を使うと、そのテストだけが実行対象になります。
Feature("ログイン機能");
Scenario.only("正しい認証情報でログインできること", ({ I }) => {
I.amOnPage("/login");
I.fillField("ユーザー名","user1");
I.fillField("パスワード","password");
I.click("ログイン");
I.see("ようこそ");
});
この例では、他の Scenario は無視され、このテストだけが実行されます。
特に修正した部分のみを実行して確認するのに有用です。
.skip
:特定のテストをスキップ
Scenario.skip
(xScenario
) や Feature.skip
(xFeature
) を使うと、一時的にそのテストを無効化できます。
Feature("ログイン機能");
Scenario.skip("ログイン失敗時のエラーメッセージ", ({ I }) => {
// 現在修正中なのでスキップ
});
.skip
を使うと、コメントアウトよりも意図が明確になり、元に戻しやすくなります。
※Feature.skip
(xFeature
)は CodeceptJS の v2.6.6 から
その他:grep によるフィルタリング(コマンドライン)
CodeceptJS のコマンドには --grep
オプションがあり、シナリオ名にマッチするものだけを実行できます。
npx codeceptjs run --grep "ログイン"
Feature
, Scenario
両方とも検索にヒットします。
正規表現も使えるため、柔軟にフィルタリングが可能です。
※特に正規表現で指定しない場合は部分一致になるようなので注意が必要です。
"ログインの機能" で検索した場合、"ログインの機能1"、"ログインの機能2" のいずれもヒットします。
ESLint カスタムルール
以下を目標として作成していきます。
-
Scenario.skip()
とScenario.only()
の使用を検出して警告する - ESLint の自動修正機能でこれらを通常の
Scenario()
に変換する - プラグインとしては公開しない(ローカルでルールを適用するのに留める)
1. カスタムルールファイルを作成する
まず、ESLint のカスタムルールを格納するディレクトリとルールファイルを作成します。
./eslint-rules/no-scenario-skip-or-only.js
2. ルールのロジックを実装する
以下のコードを記述します。
export default {
meta: {
type: 'suggestion',
docs: {
description: 'disallow Scenario.skip and Scenario.only in CodeceptJS tests',
recommended: true,
url: null
},
fixable: 'code',
schema: [],
messages: {
noScenarioSkip: "Unexpected 'Scenario.skip()'. Remove '.skip' to run all tests.",
noScenarioOnly: "Unexpected 'Scenario.only()'. Remove '.only' to run all tests."
}
},
create(context) {
return {
MemberExpression(node) {
if (
node.object.name === 'Scenario' &&
(node.property.name === 'skip' || node.property.name === 'only')
) {
context.report({
node,
messageId: node.property.name === 'skip' ? 'noScenarioSkip' : 'noScenarioOnly',
fix(fixer) {
// '.skip' または '.only' 部分を削除
return fixer.removeRange([node.object.range[1], node.range[1]]);
}
});
}
}
};
}
};
補足として、Scenario.skip
の部分は、AST(抽象構文木) 上では MemberExpression
として表現されます。
-
Scenario
が「オブジェクト」 -
skip
が「プロパティ」
ノードタイプやセレクタについて詳しくは公式ドキュメントを参照ください。
3. カスタムルールのテストを書く
カスタムルールのテストファイルを作成し、有効なテストケースと無効なテストケースに対してテストします。
import { RuleTester } from 'eslint';
import rule from '../no-scenario-skip-or-only.js';
const ruleTester = new RuleTester();
ruleTester.run('no-scenario-skip-or-only', rule, {
valid: ['Scenario("xxx", () => {} )'],
invalid: [
{
code: 'Scenario.skip("xxx", () => {} )',
errors: [{ messageId: 'noScenarioSkip' }],
output: 'Scenario("xxx", () => {} )'
},
{
code: 'Scenario.only("xxx", () => {} )',
errors: [{ messageId: 'noScenarioOnly' }],
output: 'Scenario("xxx", () => {} )'
}
]
});
console.log('All tests passed!');
node eslint-rules/no-scenario-skip-or-only.test.js
で実行します。
テストに合格するとコンソールに All tests passed!
が出力されます。
4. ESLint 設定ファイルにカスタムルールを追加する
eslint.config.js
ファイルを以下のように更新します(Flat Config 使用時)。
// ...
// カスタムルールを読み込み
import noScenarioSkipOrOnlyRule from './eslint-rules/no-scenario-skip-or-only.js';
// カスタムプラグインの定義
const codeceptRules = {
plugins: {
codecept: {
rules: {
'no-scenario-skip-or-only': noScenarioSkipOrOnlyRule
}
}
}
};
export default [
// ...
codeceptRules, // カスタムプラグイン設定を追加
{
rules: {
// カスタムルールを適用
'codecept/no-scenario-skip-or-only': 'error'
}
},
];
※「カスタムプラグインの定義」の部分に関しては別途プラグイン用のファイルを作成することでルールを npm パッケージで共有し、他のプロジェクトで使用できるようになります。
今回はローカルでの使用にとどめます。
5. ESLint を実際に実行して確認する
以下のような簡易的な CodeceptJS 用のテストファイルを作成します。
./sample.test.js
※意図的に Scenario.skip
と Scenario.only
を含めてルールが動作するか確認します。
Feature('My First Test');
Scenario('test something', ({ I }) => {
I.amOnPage('https://github.com');
I.see('GitHub');
});
Scenario.skip('skip', () => {}); // 検出される
Scenario.only('only', () => {}); // 検出される
次のコマンドを実行してルールが機能するか確認します。
npx eslint sample.test.js
エラーメッセージが表示されれば、ルールが正常に機能しています。
sample.test.js:8:1: Unexpected 'Scenario.skip()'. Remove '.skip' to run all tests. codecept/no-scenario-skip-or-only
sample.test.js:10:1: Unexpected 'Scenario.only()'. Remove '.only' to run all tests. codecept/no-scenario-skip-or-only
6. 自動修正を試す
--fix
オプションを付けて ESLint を実行すると、.skip
と .only
が自動的に削除されます。
npx eslint sample.test.js --fix
自動修正後、テストファイルは以下のように変わります。
Feature('My First Test');
Scenario('test something', ({ I }) => {
I.amOnPage('https://github.com');
I.see('GitHub');
});
- Scenario.skip('skip', () => {});
+ Scenario('skip', () => {});
- Scenario.only('only', () => {});
+ Scenario('only', () => {});
まとめ
.only
、.skip
を活用することで、テストの作成や確認を効率化できます。
また、カスタムルールをプロジェクトに追加することで、開発者が誤って Scenario.skip
や Scenario.only
を残してしまうミスを防止できます。※
※コミット時は Husky と lint-staged を、PRマージ時であれば CI/CD パイプラインに組み込むなど。
参考リンク
CodeceptJS公式ドキュメント:Skipping
Custom Rule Tutorial - ESLint - Pluggable JavaScript Linter