欠陥:欠陥プラグインのカスタマイズ

欠陥:欠陥プラグインのカスタマイズ

TestRail には、Jira、FogBugz、Bugzilla などの一般的なバグ トラッカーに対応したすぐに使える欠陥プラグインが付属しています。バグ追跡ツールがカスタマイズされている場合 (カスタム フィールドの追加など)、または欠陥プラグインに機能を追加したい場合は、ニーズに合わせてビルトインの欠陥プラグインをカスタマイズできます。TestRail にはデフォルトの欠陥プラグインの完全なソース コードが含まれており、このセクションではそれらをカスタマイズする例をいくつか示します。

本セクションでは、JIRA Server 3.x または 4.x 用 のビルトイン欠陥プラグインをカスタマイズする例を示します。

提供されている欠陥プラグインの 1 つをカスタマイズする前に、欠陥プラグインの内部動作に関する重要な背景情報が多く記載されている「カスタム欠陥プラグインの作成」セクションを読むことをお勧めします。[欠陥のプッシュ] ダイアログにフィールドを追加する方法とユーザー マッピングを実装する方法の例については、以下を参照してください。

  • カスタム フィールドの追加
  • ビルトイン フィールドの追加
  • ユーザー マッピングの実装
  • その他のユーザーマッピングの方法

注意:欠陥プラグインのカスタマイズについては、作成されたスクリプトに関するエラーの調査や解決をサポートすることはできません。PHPスクリプトの実装経験のある方の支援をお願いしてください。

カスタム フィールドの追加

デフォルトの欠陥プラグインでサポートされていない追加の必須カスタム フィールドを使用している場合、[欠陥のプッシュ] ダイアログに新しい項目を追加すると便利です。[アサイン] などのフィールドをダイアログに追加することもできます。このセクションでは、その方法について説明します。この例では Jira 欠陥プラグインを使用しますが、他の欠陥プラグインでも同様のカスタマイズが可能です。Jira の欠陥プラグインをカスタマイズする前に、まずプラグインをコピーして名前を変更します。Jira.php プラグイン ファイルを TestRail のアプリケーション ディレクトリからカスタム ディレクトリにコピーします。

Original: <TestRail>/app/plugins/defects/Jira.php
Copy To: <TestRail>/custom/defects/Jira_custom.php

ファイルの名前が Jira_custom.php に変更されていることに注目してください 。TestRail の管理エリアで、標準の Jira プラグインとカスタマイズされたバージョンのどちらでも任意に選択できるようにするために、これは重要な処理です。ファイルをコピーしたら、クラス名を変更する必要があります。それには、テキスト エディターで Jira_custom.php ファイルを開き、ファイルの先頭にあるクラス名を次のように変更します。


class Jira_custom_defect_plugin extends Defect_plugin
{

この例では、問題またはバグが発生したテスト マシンのハードウェアやソフトウェアの構成をテスターが指定できるよう、[欠陥のプッシュ] ダイアログに新しいフィールドを追加します。Jira の対応するフィールドは Text Field タイプのカスタム フィールドで、Config という名前です。このフィールドはすべての課題タイプに有効であり、必須ではありません。

最初に変更しなければならないのは prepare_push メソッドのフォーム スキーマです (まだ読んでいない場合は参照記事を必ずお読みください)。ユーザーがバグ レポートにシステム構成を入力できるよう、ダイアログに新しい文字列フィールドを追加します。フィールド名を config とし、 description フィールドの直前に追加します。


public function prepare_push($context)
{
	// Return a form with the following fields/properties
	return array(
		'fields' => array(
			'summary' => array(
				'type' => 'string',
				'label' => 'Summary',
				'required' => true,
				'size' => 'full'
			),
			'type' => array(
				'type' => 'dropdown',
				'label' => 'Issue Type',
				'required' => true,
				'remember' => true,
				'size' => 'compact'
			),
			'project' => array(
				'type' => 'dropdown',
				'label' => 'Project',
				'required' => true,
				'remember' => true,
				'cascading' => true,
				'size' => 'compact'
			),
			'component' => array(
				'type' => 'dropdown',
				'label' => 'Component',
				'required' => true,
				'remember' => true,
				'depends_on' => 'project',
				'size' => 'compact'
			),
			'config' => array(
				'type' => 'string',
				'label' => 'Configuration',
				'remember' => true,
				'size' => 'full'
			),
			'description' => array(
				'type' => 'text',
				'label' => 'Description'
			)
		)
	);
}

フィールドをフォーム スキーマに追加したら、prepare_field メソッドに config フィールドを追加します。これは、ユーザーが以前にダイアログに入力した記憶済みの値を復元するためです。こうすると、ユーザーは送信するすべてのバグ レポートで設定を再入力する必要がありません。新しい config フィールドで利用するために、設定処理コードをメソッドの先頭に移動したことに注目してください。


public function prepare_field($context, $input, $field)
{
	$data = array();
 
	// Take into account the preferences of the user, but only
	// for the initial form rendering (not for dynamic loads).
	if ($context['event'] == 'prepare')
	{
		$prefs = arr::get($context, 'preferences');
	}
	else
	{
		$prefs = null;
	}
 
	// Process those fields that do not need a connection to the
	// Jira installation.		
	if ($field == 'summary' || $field == 'description' || $field == 'config')
	{
		switch ($field)
		{
			case 'summary':
				$data['default'] = $this->_get_summary_default(
					$context);
				break;
 
			case 'description':
				$data['default'] = $this->_get_description_default(
					$context);
				break;
 
			case 'config':
				$data['default'] = arr::get($prefs, 'config');
				break;
		}
 
		return $data;
	}
 
	// [ .. ]
}

これでスクリプトは以前に入力された設定を復元するようになりました。最後のステップは、(課題を作成するために) Jira に送信する API リクエストに新しいカスタム フィールドを追加することです。それには、push メソッドを次のように変更します。


public function push($context, $input)
{
	$api = $this->_get_api();
 
	$data = array();
	$data['summary'] = $input['summary'];
	$data['type'] = $input['type'];
	$data['project'] = $input['project'];
	$data['component'] = $input['component'];
	$data['description'] = $input['description'];
	$data['customFieldValues'] = array(
		array(
			'customfieldId' => 'customfield_10000',
			'values' => array($input['config'])
		)
	);
 
	return $api->add_issue($data);
}

customfield_10000 の名前を変更して、送信するカスタム フィールドの実際の ID を使用する必要があります。カスタム欠陥プラグインに新しいフィールドを追加したので、更新された [欠陥のプッシュ] ダイアログを使用して課題と共に設定の詳細を送信できます (新しいフィールドを表示するには、[管理] > [統合] で新しい Jira_custom プラグインが選択されていることを確認してください)。

完全なサンプルのファイルはこちらからダウンロードできます。jira_custom.zip

ビルトイン フィールドの追加

TestRail の [欠陥のプッシュ] ダイアログにバグ トラッカーの組み込みフィールドを追加することは、上で説明したバグ トラッカーのカスタム フィールドの追加と大した違いはありません。ただし、これは非常に一般的な作業であり、一部のバグ トラッカーの API は特定のフィールドに対して特別な規則を必要とするため、このセクションでは欠陥プラグインにバグ トラッカーのビルトインフィールドを追加する方法について説明します。

具体的には、このセクションでは Jira の Affects Version フィールドを追加する方法について説明しますが、他のバグ トラッカーにも同様のフィールドと規則があるでしょう。Affects Version フィールドは、新しいバグを報告するバージョンを選択するドロップダウン フィールドとして実装されています。まず標準の Jira 欠陥プラグインをカスタム ディレクトリにコピーして名前を変更します。

Original: <TestRail>/app/plugins/defects/Jira.php
Copy To: <TestRail>/custom/defects/Jira_versions.php

また、ファイル先頭のクラス名を変更する必要があります。


class Jira_versions_defect_plugin extends Defect_plugin
{

最初に行う実質的なコードの変更は、フォーム スキーマに新しいフィールドを追加することです。このフィールドを affects_version という名前にします。


public function prepare_push($context)
{
	// Return a form with the following fields/properties
	return array(
		'fields' => array(
			'summary' => array(
				'type' => 'string',
				'label' => 'Summary',
				'required' => true,
				'size' => 'full'
			),
			'type' => array(
				'type' => 'dropdown',
				'label' => 'Issue Type',
				'required' => true,
				'remember' => true,
				'size' => 'compact'
			),
			'project' => array(
				'type' => 'dropdown',
				'label' => 'Project',
				'required' => true,
				'remember' => true,
				'cascading' => true,
				'size' => 'compact'
			),
			'component' => array(
				'type' => 'dropdown',
				'label' => 'Component',
				'required' => true,
				'remember' => true,
				'depends_on' => 'project',
				'size' => 'compact'
			),
			'affects_version' => array(
				'type' => 'dropdown',
				'label' => 'Affects Version',
				'required' => false,
				'remember' => true,
				'depends_on' => 'project',
				'size' => 'compact'
			),
			'description' => array(
				'type' => 'text',
				'label' => 'Description'
			)
		)
	);
}

Jira に利用可能なプロジェクトのバージョンを問い合わせるために、Jira_api クラスに新しい get_versions メソッドを追加します。


/**
 * Get Versions
 *
 * Returns a list of versions for a Jira project. The versions
 * are returned as array of objects, each with its ID and name.
 */	
public function get_versions($project_id)
{
	$data = array($project_id);
	$response = $this->_send_command('getVersions', $data);
 
	if (!$response)
	{
		return array();
	}
 
	$result = array();
	foreach ($response as $version)
	{
		$c = obj::create();
		$c->id = (string) $version->id;
		$c->name = (string) $version->name;
		$result[] = $c;
	}
 
	return $result;
}

また、Jira から取得した利用可能なバージョンをドロップダウン フィールドに 設定する必要があるため、prepare_field メソッドを更新し、2 番目の switch ステートメントに次のコードを追加します。


case 'affects_version':
	if (isset($input['project']))
	{
		$data['default'] = arr::get($prefs, 'affects_version');
		$data['options'] = $this->_to_id_name_lookup(
			$api->get_versions($input['project'])
		);
	}
	break;

最後に重要な点として、ユーザーがバグ レポートを送信したとき、version フィールドを実際に Jira にプッシュする必要があります。Jira は1つの課題に対して複数のバージョンの指定をサポートしているため、このフィールドを配列として送信する必要があります。それには、add_issue メソッドに次のコードを追加します。


if (isset($options['affects_version']))
{
	$version = array(
		'id' => $options['affects_version'],
		'archived' => false,
		'released' => false
	);
	$options['affectsVersions'] = array(
		$version
	);
}

[管理] > [統合] タブで新しい Jira_version 欠陥プラグインを選択すると、 [欠陥のプッシュ] ダイアログは次のようになります。

完全なサンプルのファイルはこちらからダウンロードできます。jira_versions.zip

ユーザー マッピングの実装

注意:現在は、TestRail とバグ追跡ツールの間でコードを変更することなくユーザーをマッピングするためのより簡単な方法があります。これについては、ユーザー変数で詳しく知ることができます。

TestRail に付属の欠陥プラグインは、単一のユーザー アカウントを使用してサードパーティ システムにバグ レポートを送信します。これは多くの状況に対応できる仕組みであり、このためにバグ トラッカーに特別な testrail ユーザーまたは類似のユーザーを追加することをお勧めします。

しかし、バグ レポートをプッシュしたユーザーに対応するバグ トラッカーのユーザー アカウントを使用したい場合は、欠陥プラグインにユーザー マッピングを追加することで実現できます。これを具体的に示すために、Jira.php プラグインをもう一度コピーして名前を変更します。

Original: <TestRail>/app/plugins/defects/Jira.php
Copy To: <TestRail>/custom/defects/Jira_users.php

そしてまた欠陥プラグインのクラス名を更新します。


class Jira_users_defect_plugin extends Defect_plugin
{

スクリプトにユーザー マッピング機能を追加するために、設定に新しく [users] セクションを追加します。これにより、管理者は TestRail ユーザー (ユーザーの電子メール アドレスで識別される) と欠陥追跡ツールのログイン認証情報のマッピングを設定できるようになります。たとえば、管理エリアの設定は次のようになります。

; Please configure your Jira connection below
[connection]
address=http://jira/
user=testrail
password=secret

[users]
bob@example.com=bob:secret
jim@example.com=jim:secret
jane@example.com=jane:secret

Bob がバグ レポートを送信すると、更新された欠陥スクリプトは、Bob の Jira 認証情報を使用してバグを送信します。認証情報が設定されていないユーザーがバグ レポートを送信しようとすると、スクリプトはグローバルに設定されたログイン ([connection] セクションで指定) にフォールバックします。新しい設定オプションを表示するために、get_meta メソッドを更新します。


private static $_meta = array(
	'author' => 'Gurock Software',
	'version' => '1.0',
	'description' => 'Jira defect plugin for TestRail',
	'can_push' => true,
	'can_lookup' => true,
	'default_config' => 
		'; Please configure your Jira connection below
[connection]
address=http://<your-server>/
user=testrail
password=secret
 
[users]
user@example.com=user:secret'
);

また、configure メソッドを更新し、[users] セクションを内部フィールドに割り当てるようにしました。


public function configure($config)
{
	$ini = ini::parse($config);
	$this->_address = str::slash($ini['connection']['address']);
	$this->_user = $ini['connection']['user'];
	$this->_password = $ini['connection']['password'];
 
	if (isset($ini['users']))
	{
		$this->_users = $ini['users'];
	}
	else
	{
		$this->_users = array();
	}
}

次に変更しなければならないのは、Jira の API 認証です。それには、 次のように、_get_api メソッドにユーザー マッピン グコードを追加する必要があります。


private function _get_api($context = null)
{
	if ($this->_api)
	{
		return $this->_api;
	}
 
	$user = $this->_user;
	$password = $this->_password;
 
	// Find the appropriate Jira user for the bug reporter
	// (by mapping the current TestRail user to her Jira
	// account).
	if ($context && $this->_users)
	{
		$credentials = arr::get(
			$this->_users,
			str::to_lower($context['user']->email)
		);
 
		if ($credentials)
		{
			if (preg_match('/([^:]+):(.+)/', $credentials, $matches))
			{
				$user = $matches[1];
				$password = $matches[2];
			}
		}
	}
 
	$this->_api = new Jira_api($this->_address);
	$this->_api->login($user, $password);
	return $this->_api;
}

このメソッドは、設定内で現在のユーザーに対応するユーザー認証情報を見つけようとします。認証情報が見つからない場合は、グローバルに設定された認証情報をフォールバックとして使用します。_get_api メソッドに $context 引数が追加されたことに注意してください。この引数は、現在の TestRail ユーザーの電子メール アドレスを取得するために必要です。

あとは、prepare_field および push メソッドから次のように $context 変数を渡すだけです (lookup メソッドには コンテキスト情報がないため、$context 引数を追加するべきではないことに注意してください)。


$api = $this->_get_api($context);

これで終わりです。_get_api メソッドにユーザー マッピングを追加し、このメソッドにコンテキスト情報を渡したので、あとは [管理] > [統合] で新しい欠陥プラグインを選択してユーザー アカウントを設定するだけです。

その他のユーザーマッピングの方法

注意:現在は、TestRail とバグ追跡ツールの間でコードを変更することなくユーザーをマッピングするためのより簡単な方法があります。これについては、ユーザー変数で詳しく知ることができます。

一部の課題および欠陥追跡システムでは、API を介してレポーター ユーザーを設定できます。この場合、必ずしもログインによる完全なユーザー マッピングを実装する必要はありません。課題を報告するユーザーのユーザー名を指定するだけで済みます。

たとえば、組織の電子メール アドレスとそれに対応する JIRA ユーザー名が次のようになっているとしましょう。

bob@example.com -> bob
jan@example.com -> jan
sue@example.com -> sue

この場合、現在のユーザーの電子メールアドレスから JIRA ユーザー名を作成し、push メソッドで reporter フィールドに次のように指定するだけです。


public function push($context, $input)
{
	if (isset($context['user']->email))
	{
		$email = $context['user']->email;
		$pos = str::pos($email, '@');
		if  ($pos !== false)
		{
			$input['reporter'] = str::sub($email, 0, $pos);
		}
	}
 
	$api = $this->_get_api();
	return $api->add_issue($input);
}

こうすると、JIRA ユーザーのユーザー名とパスワードを TestRail に保存しておかなくても、課題を報告したユーザーが正しく JIRA に送信されます。提供されている API 機能によっては、他の課題および欠陥追跡ツールもこれをサポートしている可能性があります。