Karmaはプラグインによって拡張できます。プラグインには、_フレームワーク_、_レポーター_、_ランチャー_、_プリプロセッサ_、_ミドルウェア_の5種類があります。それぞれのタイプは、Karmaの動作のある側面を変更することを可能にします。
Karmaは_依存性注入_を使用して組み立てられています。プラグインを開発するためには、この概念を理解することが重要です。
非常に高いレベルでは、Karmaを、各キー(_DIトークン_)が特定のKarmaオブジェクト(_サービス_)にマッピングされたオブジェクトと考えることができます。たとえば、`config` DIトークンは、現在のKarma設定を保持する`Config`インスタンスにマッピングされます。プラグインは、対応するDIトークンを指定することで、さまざまなKarmaオブジェクトを要求(または_注入_)できます。注入されると、プラグインは注入されたサービスと対話して機能を実装できます。
利用可能なすべてのサービスとそのDIトークンの網羅的なリストはありませんが、Karmaまたは他のプラグインのソースコードを読むことで、それらを発見できます。
各プラグインは、本質的に、関連付けられたDIトークンを持つサービスです。ユーザーが設定でプラグインをアクティブ化すると、Karmaは対応するDIトークンを探し、このDIトークンにリンクされたサービスをインスタンス化します。
プラグインを宣言するには、プラグインのDIトークンを定義し、Karmaにそれをインスタンス化する方法を説明する必要があります。DIトークンは、プラグインタイプとプラグインの一意の名前の2つの部分で構成されます。前者は、プラグインが何をすることができるか、サービスのAPIへの要件、いつインスタンス化されるかを定義します。後者は一意の名前であり、プラグインユーザーはプラグインをアクティブ化するために使用します。
プラグインが複数のサービスを定義することは完全に有効です。これは、プラグインによってエクスポートされたオブジェクトにキーを追加することによって行うことができます。この一般的な例は、通常一緒に提供される`framework` + `reporter`プラグインです。
インスタンス化されたときに「Hello, world!」を出力する非常に単純なプラグインを作成してみましょう。Karmaライフサイクルの初期にインスタンス化され、APIに何の要件もないため、`framework`タイプを使用します。プラグインを「hello」と呼ぶことにしましょう。そうすると、一意の名前は`hello`になります。これら2つの部分を結合すると、プラグイン`framework:hello`のDIトークンが得られます。それを宣言しましょう。
// hello-plugin.js
// A factory function for our plugin, it will be called, when Karma needs to
// instantiate a plugin. Normally it should return an instance of the service
// conforming to the API requirements of the plugin type (more on that below),
// but for our simple example we don't need any service and just print
// a message when function is called.
function helloFrameworkFactory() {
console.log('Hello, world!')
}
module.exports = {
// Declare the plugin, so Karma knows that it exists.
// 'factory' tells Karma that it should call `helloFrameworkFactory`
// function and use whatever it returns as a service for the DI token
// `framework:hello`.
'framework:hello': ['factory', helloFrameworkFactory]
};
// karma.conf.js
module.exports = (config) => {
config.set({
plugins: [
require('./hello-plugin')
],
// Activate our plugin by specifying its unique name in the
// corresponding configuration key.
frameworks: ['hello']
})
}
「依存性注入」セクションでは、任意のKarmaサービスをプラグインに注入して対話できることを説明しました。これは、プラグインのファクトリ関数で`$inject`プロパティを、プラグインが対話したいDIトークンの配列に設定することによって行うことができます。Karmaはこのプロパティを取得し、要求されたサービスをパラメータとしてファクトリ関数に渡します。
`hello`フレームワークをもう少し便利にして、`hello.js`ファイルを`files`配列に追加してみましょう。こうすることで、プラグインのユーザーは、たとえば、テストから`hello.js`で定義された関数にアクセスできます。
// hello-plugin.js
// Add parameters to the function to receive requested services.
function helloFrameworkFactory(config) {
config.files.unshift({
pattern: __dirname + '/hello.js',
included: true,
served: true,
watched: false
})
}
// Declare DI tokens plugin wants to inject.
helloFrameworkFactory.$inject = ['config']
module.exports = {
'framework:hello': ['factory', helloFrameworkFactory]
};
Karmaの設定は変更されておらず、簡潔にするために省略されています。プラグインの使用法については、上記の例を参照してください。
このセクションでは、さまざまなプラグインタイプのAPI要件と規則について概説します。インスピレーションを得るために使用できるいくつかのプラグインへのリンクもあります。
フレームワークは、既存のテストライブラリをKarmaのAPIに接続するため、その結果をブラウザに表示してサーバーに送り返すことができます。
Karmaフレームワークは、Karmaがテスト実行を開始するために呼び出す`window.__karma__.start`メソッドを_実装する必要があります_。この関数は、結果をkarmaに送り返すためのメソッドを持つオブジェクトを使用して呼び出されます
最も一般的には、`result`メソッドを使用して、個々のテストの成功または失敗のステータスを送信します。メソッドは次の形式のオブジェクトを取ります
{
// test id
id: String,
// test description
description: String,
// the suite to which this test belongs. potentially nested.
suite: Array[String],
// an array of string error messages that might explain a failure.
// this is required if success is false.
log: Array[String],
success: Boolean, // pass / fail
skipped: Boolean // skipped / ran
}
プリプロセッサは、3つの引数(`content`、`file`、`next`)を受け取り、何らかの方法でコンテンツを変更し、次のプリプロセッサに渡す関数です。
Karmaは依存性注入によって組み立てられるため、プラグインはほぼすべてのKarmaコンポーネントを要求して対話できます。このような、より興味深い処理を行うプラグインがいくつかあります。karma-closure、karma-intellijを確認してください。