以下のNode.jsおよびBashスクリプトの例をmablレポーティングAPIのバッチ結果エンドポイントと組み合わせて使用すると、一連のテスト実行結果をプログラムで取得し、CSV形式に変換できます。
その他のCSVエクスポート方法
mablのテスト結果をCSVとしてエクスポートする別の方法をお探しの場合は、以下のいずれかをお試しください。
- UIから - テスト結果 > テスト別ページ、または特定のプランのプラン詳細ページから、最近の結果のCSVをダウンロードします。
- Google Sheets - カスタム連携を設定して、実行のたびにmablのテスト結果をGoogleスプレッドシートに追記します。
セットアップ
スクリプトを実装する前に、適切なセットアップが完了していることを確認してください。
このスクリプト例を実行するには、Node.jsをインストールする必要があります。Node.jsはこちらからすべての主要なプラットフォーム向けに入手できます。
Node.jsをインストールしたら、mablレポーティングAPIなどのAPIと通信するためにaxiosライブラリもインストールする必要があります。コマンドラインで、このスクリプトを作成したいディレクトリに移動し、Node.jsに付属しているnpmを使用してaxiosライブラリをインストールします。
npm install axios@1.3.3 --save
スクリプト例を実行するには、bashスクリプトを実行できるコマンドラインと、いくつかの一般的なユーティリティがインストールされている必要があります。
- curl
- jq: さまざまなプラットフォーム向けにこちらから入手できます
結果を取得する
以下のスクリプトを、axiosをインストールしたディレクトリにindex.jsという名前で保存します。CSV出力にすべてのフィールドが必要ない場合やフィールドの順序を変更したい場合は、スクリプト内のTEST_RUN_FIELDSリストを編集できます。test_labelsやplan_labelsのように値がリストになるフィールドを追加する場合は、生の配列は有効なCSVではないため、先に文字列へ結合してください(例: value.join('|'))。
const axios = require('axios');
const process = require('process');
const fs = require('fs');
// Check correct number of arguments and provide usage help
if (process.argv.length < 5 || process.argv.length > 6) {
console.error('Usage: node index.js WORKSPACE_ID MABL_API_KEY OUTPUT_FILE [API_QUERY_PARAMS]');
process.exit(1);
}
const WORKSPACE_ID = process.argv[2];
const MABL_API_KEY = process.argv[3];
const OUTPUT_FILE = process.argv[4];
const QUERY_PARAMS = process.argv[5];
let MABL_ENDPOINT_URL = `https://api.mabl.com/results/workspace/${WORKSPACE_ID}/testRuns?${QUERY_PARAMS || ''}`;
// Ordered fields to extract from each test run
const TEST_RUN_FIELDS = [
'application_id',
'application_name',
'environment_id',
'environment_name',
'initial_url',
'scenario_name',
'browser',
'browser_version',
'execution_runner_type',
'plan_id',
'plan_name',
'plan_run_id',
'test_id',
'test_version',
'test_name',
'test_type',
'branch',
'test_run_id',
'test_run_app_url',
'is_ad_hoc_run',
'failure_category',
'start_time',
'end_time',
'run_time',
'status',
'success',
'trigger_type',
'triggering_deployment_event_id',
'emulation_mode',
'metrics.cumulative_speed_index',
'metrics.cumulative_api_response_time',
'metrics.accessibility_rule_violations.critical',
'metrics.accessibility_rule_violations.serious',
'metrics.accessibility_rule_violations.moderate',
'metrics.accessibility_rule_violations.minor',
'outcome',
'failure_summary.step_number',
'failure_summary.flow_name',
'failure_summary.error',
'failure_summary.image_artifact_url',
'failure_analysis.headline',
];
function getField(object, field) {
return field
.split('.')
.reduce((currentObject, currentField) => currentObject === undefined || currentObject === null ? undefined : currentObject[currentField], object);
}
async function getRunResults(cursor) {
let url = MABL_ENDPOINT_URL;
if (cursor !== undefined) {
url += `&cursor=${cursor}`;
}
console.log(cursor === undefined ? 'Fetching first page of results...' : `Fetching results with cursor=${cursor}`);
const response = await axios.get(url, {
auth: {
username: 'key',
password: MABL_API_KEY,
}
});
if (!response.data) {
console.error(`No data returned from mabl API; full response: ${JSON.stringify(response)}`);
}
return response.data;
}
function getResultFields(results) {
return results.map(result => {
return TEST_RUN_FIELDS
.map(field => escapeValue(getField(result, field)));
});
}
function escapeValue(value) {
if (value === undefined || value === null) {
return '';
}
// RFC 4180: quote any field that contains a comma, double-quote, or newline,
// and escape embedded double-quotes by doubling them.
const stringValue = String(value);
if (/[",\r\n]/.test(stringValue)) {
return '"' + stringValue.replace(/"/g, '""') + '"';
}
return stringValue;
}
function resultRowsToCsv(results) {
return results
.map(row => row.join(','))
.join('\n') + '\n';
}
async function getAllRunResults() {
let cursor;
const outStream = fs.createWriteStream(OUTPUT_FILE);
outStream.write(resultRowsToCsv([TEST_RUN_FIELDS]));
do {
const data = await getRunResults(cursor);
if (data) {
cursor = data.cursor;
const results = getResultFields(data.test_results || []);
outStream.write(resultRowsToCsv(results));
} else {
break;
}
} while (cursor !== undefined);
outStream.end();
}
getAllRunResults().catch(console.error);
このスクリプトは、結果のすべてのページを自動的にページネーションします。結果セットが大きい場合は、複数のリクエストが発生します。ページごとにログ行が出力されます。
スクリプトを実行する
コマンドラインからindex.jsスクリプトを呼び出すと、mablレポーティングAPIから結果を取得してCSVファイルに保存できます。
node index.js WORKSPACE_ID API_KEY OUT_FILE QUERY_PARAMETER_STRING
このindex.jsスクリプトでは、次の引数を使用します。
-
WORKSPACE_ID:WORKSPACE_IDをワークスペースIDに置き換える -
API_KEY: ワークスペースの所有者にmabl Viewer APIキーを作成してもらうか、既存のmabl Viewer APIキーを使用して、API_KEYをキーシークレットに置き換える -
OUT_FILE:OUT_FILEを出力ファイル名(results.csvなど)に置き換える -
QUERY_PARAMETER_STRING: このオプション引数を使用して結果をフィルタリングする
利用可能なクエリパラメーターを確認し、QUERY_PARAMETER_STRINGを置き換える適切なクエリパラメーター文字列を作成するには、バッチ実行結果エンドポイントのAPIドキュメントを参照してください。たとえば、一定の時間範囲内のすべての実行を指定するには、https://www.epochconverter.com/を使用して目的の開始タイムスタンプと終了タイムスタンプをミリ秒単位で取得し、次のようにクエリパラメーター文字列で使用します。earliest_run_start_time=1677506400000&latest_run_start_time=1677592800000
以下のbashスクリプトをmabl_results_to_csv.shという名前で保存します。このスクリプトは、mablバッチ結果エンドポイントのJSON結果をCSV形式に変換します。留意すべき点は以下のとおりです。
- すべてのフィールドが必要ない場合やフィールドの順序を変更したい場合は、
jqフィルターの先頭にあるフィールドのリストを編集します。各エントリはフィールドへのパスです。 - ネストされた値の場合は、各キーを順番に列挙します。たとえば、
["metrics","cumulative_speed_index"]のようにします。 -
test_labelsやplan_labelsのような配列値のフィールドは、jqの@csvが配列を受け付けないため、このリストではそのままではサポートされていません。含めるには、まずカスタムのjq式で文字列に結合してください。
#!/bin/bash
# Transform mabl batch results JSON (provided on STDIN) into CSV.
# Pass -p to include the header row.
# Uses jq's built-in @csv, which is RFC 4180 compliant: it quotes any field
# containing a comma, double-quote, or newline and escapes embedded quotes.
if [[ "$1" == "-h" || "$1" == "-help" || "$1" == "--help" || "$1" == "help" ]]; then
echo "Transform mabl batch results JSON (provided on STDIN) into a CSV format with an optional header row (included if -p is provided as an argument)"
echo "Example usage: cat results.json | $0 -p > results.csv"
exit 0
fi
print_header=false
[ "$1" == "-p" ] && print_header=true
jq -r --argjson print_header "$print_header" '
# Each entry is the path (as an array) to a field in a test result.
[
["application_id"],
["application_name"],
["environment_id"],
["environment_name"],
["initial_url"],
["scenario_name"],
["browser"],
["browser_version"],
["execution_runner_type"],
["plan_id"],
["plan_name"],
["plan_run_id"],
["test_id"],
["test_version"],
["test_name"],
["test_type"],
["branch"],
["test_run_id"],
["test_run_app_url"],
["is_ad_hoc_run"],
["failure_category"],
["start_time"],
["end_time"],
["run_time"],
["status"],
["success"],
["trigger_type"],
["triggering_deployment_event_id"],
["emulation_mode"],
["metrics","cumulative_speed_index"],
["metrics","cumulative_api_response_time"],
["metrics","accessibility_rule_violations","critical"],
["metrics","accessibility_rule_violations","serious"],
["metrics","accessibility_rule_violations","moderate"],
["metrics","accessibility_rule_violations","minor"],
["outcome"],
["failure_summary","step_number"],
["failure_summary","flow_name"],
["failure_summary","error"],
["failure_summary","image_artifact_url"],
["failure_analysis","headline"]
] as $fields
| (if $print_header then [$fields[] | join(".")] | @csv else empty end),
(.test_results[] | [ $fields[] as $p | getpath($p) ] | @csv)
'
スクリプトを保存したら、bashコマンドプロンプトで次のコマンドを使用して実行可能にできます。chmod +x mabl_results_to_csv.sh
bashコマンドラインからスクリプトを呼び出して、mablレポーティングAPIの結果を処理し、CSVに保存します。WORKSPACE_IDをワークスペースIDに置き換え、API_KEYをmabl Viewer APIキーに置き換えます。
curl "https://api.mabl.com/results/workspace/WORKSPACE_ID/testRuns?advanced_metrics=true" \
-u "key:API_KEY" \
| ./mabl_results_to_csv.sh -p \
> results.csv
追加の結果を取得する
mablのテスト結果はページネーションされています。最新のページより多くの実行を取得するには、エンドポイントを繰り返し呼び出し、結果の各ページを順に進める必要があります。最初のスクリプトを呼び出してこのページングを処理する2つ目のbashスクリプトをmabl_get_batch_results.shとして作成できます。
#!/bin/bash
# Check number of arguments and provide help with usage example if incorrect
if [[ $# -lt 3 || $# -gt 4 ]]; then
echo "Usage: $0 WORKSPACE_ID API_KEY OUTPUT_FILENAME [query parameter string]"
echo "Example: $0 'MY-WORKSPACE-ID-w' 'API-KEY' 'results.csv' 'test_id=MY-TEST-ID-j&earliest_run_start_time=1677587852400'"
exit 1
fi
workspace_id=$1
api_key=$2
output_file=$3
endpoint="https://api.mabl.com/results/workspace/$workspace_id/testRuns?"
# Add given query parameters to API endpoint URL
if [ "$4" ]; then
endpoint+="$4"
fi
# Set initial cursor value to null
cursor="null"
# Add header row to output file
echo '{"test_results":[]}' | ./mabl_results_to_csv.sh -p >> $output_file
# Loop until there is no more data to retrieve
while : ; do
echo "Getting batch of results with cursor = $cursor"
# Make API call with current cursor value
if [[ $cursor != "null" ]]; then
response=$(curl -s "$endpoint&cursor=$cursor" -u "key:$api_key")
else
response=$(curl -s "$endpoint" -u "key:$api_key")
fi
# Extract cursor value from API response
cursor=$(echo $response | jq -r '.cursor')
# Process data from API response
echo "Processing batch of results with cursor = $cursor"
echo "$response" | ./mabl_results_to_csv.sh >> $output_file
echo "Finished processing batch of results with cursor = $cursor"
[[ $cursor != "null" ]] || break
done
スクリプトを保存したら、bashコマンドプロンプトで次のコマンドを使用して実行可能にします。
chmod +x mabl_get_batch_results.sh
コマンドラインからスクリプトを呼び出すと、mablレポーティングAPIから複数ページの結果を取得してCSVファイルに保存できます。
./mabl_get_batch_results.sh WORKSPACE_ID API_KEY OUT_FILE 'QUERY_PARAMETER_STRING'
このスクリプトでは、次の引数を使用します。
-
WORKSPACE_ID:WORKSPACE_IDをワークスペースIDに置き換える -
API_KEY: ワークスペースの所有者にmabl Viewer APIキーを作成してもらうか、既存のmabl Viewer APIキーを使用して、API_KEYをキーシークレットに置き換える -
OUT_FILE:OUT_FILEを出力ファイル名(results.csvなど)に置き換える -
QUERY_PARAMETER_STRING: このオプション引数を使用して結果をフィルタリングする
利用可能なクエリパラメーターを確認し、QUERY_PARAMETER_STRINGを置き換える適切なクエリパラメーター文字列を作成するには、バッチ実行結果エンドポイントのAPIドキュメントを参照してください。たとえば、一定の時間範囲内のすべての実行を指定するには、https://www.epochconverter.com/を使用して目的の開始タイムスタンプと終了タイムスタンプをミリ秒単位で取得し、次のようにクエリパラメーター文字列で使用します。earliest_run_start_time=1677506400000&latest_run_start_time=1677592800000