Testlink の DB に記録されたテスト実施データからグラフを生成する手順について解説します。
Testlink DB のアクセス
まず Testlink DB に接続する必要があります。
Testlink Root の config_db.inc に Testlink Database への接続情報が記載されています。
<?php
// Automatically Generated by TestLink Installer - Mon, 08 Dec 14 07:12:47 +0100
define('DB_TYPE', 'mysql');
define('DB_USER', 'root');
define('DB_PASS', 'root_pass');
define('DB_HOST', 'localhost:3306');
define('DB_NAME', 'testlink');
define('DB_TABLE_PREFIX', '');
?>
グラフ化手順
テストの実行結果は Testlink DB の executions table にテスト計画毎に、実施したテストケースのID、実施日時、結果のステータスが記録されます。
executions table を検索し、開始日から終了日までの実行結果を、テスト計画に対し実施日毎に集計すれば、これを元にグラフを描画することができます。
executions table の詳細:
field | 用途 | 参照先 |
---|---|---|
id | 実行のID | |
build_id | ビルドのID | builds > id |
tester_id | テスターのID | |
execution_ts | テストを実施した日時 | |
status | 実行結果(p/b/f…) | |
testplan_id | テスト計画のID | testplans > id |
tcversion_id | テストケースのID | tcversions > id |
tcversion_number | テストケースのバージョン | tcversions > Version |
platform_id | プラットフォームのID | platforms > id |
execution_type | 実行タイプ | |
execution_duration | 実行にかかった時間(分) | |
notes | テストの備考 |
必要なのは execution_ts / status / testplan_id / tcversion_id です。
手順概要
1. プロジェクトを選択する > testproject_id
2. 選択したプロジェクトに属するテスト計画を選択 > testplan_id
3. executions/testplan_id=id に記録されている初日と最終日を得る
4. Loop: {初日 → 最終実施日
5. execution table からテスト計画毎に初日→翌日++の実施数を得る(テストケース毎に最新の結果を得る)
6. 結果を1日毎の配列に入れていく(ステータス毎)
7. Loop:}
8. 結果の配列を csv 化
9. グラフ描画パッケージ(pchart/highcharts等)にCSVのデータ列を渡す
プロジェクト選択
プロジェクトを選択する php のサンプル
- プロジェクトIDは testprojects table から得ます。
- プロジェクト名は nodes_hierarchy table に入っています。
- DB_ACCESS は PDO で MySQL DB に接続する Object 。
- executeSQL は prepare と execute をまとめて実施するメソッドです。
$db = new DB_ACCESS('testlink');
$dbh = $db->connect();
$actfile = getplan.php;
$sql = 'select tp.id as id, nh.name as name from testprojects tp, nodes_hierarchy nh
where tp.id = nh.id order by tp.id desc;';
$res = $db->executeSQL($dbh,$sql,null);
?>
<form method="get" action="<?php echo $actfile; ?>">
<select name="proj" id="proj">
<?php
While ($proj = $res -> fetch(PDO::FETCH_ASSOC)){
print('<option value="'. $proj['id'].'">' . $proj['name'] . '</option>');
}
// $dbh = null;
?>
</select>
<input type="submit" value="選択" />
</form>
nodes_hierarchy table の構造
- nodes_hierarchy は Testlink のプロジェクト・テスト計画・テストスイート・テストケース等の階層構造を定義しているテーブルです。
nodes_hierarchy | 用途 | 参照先 |
---|---|---|
id | ノードのID | |
name | ノードの名前(プロジェクト名等) | |
parent_id | 親ノードのID | |
node_type_id | ノードのタイプ | node_types > id |
node_order | ツリーの階層の中での表示位置 |
node_type
ID | Type |
---|---|
1 | testproject |
2 | testsuite |
3 | testcase |
4 | testcase_version |
5 | testplan |
6 | requirement_spec |
7 | requirement |
8 | requirement_version |
9 | testcase_step |
10 | requirement_revision |
11 | requirement_spec_revision |
12 | build |
13 | platform |
14 | user |
テスト計画の選択
テスト計画を選択する php のサンプル
- テスト計画ID は testplans table から得ます。
- テスト計画名は同様に nodes_hierarchy table に入っています。
$pjid = $_GET['proj'];
$_SESSION['projectID'] = $proid; // プロジェクトIDはセッション変数に入れる
$db = new DB_ACCESS('testlink');
$dbh = $db->connect();
$actfile = planProgress.php;
$sql = "select pl.id as id, nh.name as name from testplans pl, nodes_hierarchy nh
where pl.id = nh.id and nh.node_type_id=5 and pl.testproject_id=:pjid and pl.active = 1 order by name";
$res = $db->executeSQL($dbh,$sql,array(':pjid'=>$proid));
<font color="<?php echo 'midnightblue';?>"><br>テスト計画を選択</font><br>
<form method="get" action=<?php echo $actfile; ?>>
<select name="plan" id="plan">
<?php
while($plan = $res -> fetch(PDO::FETCH_ASSOC)) {
print('<option value="' . $plan['id']. '">' . $plan['name'] . '</option>');
}
?>
</select>
<input type="submit" value="選択" />
executions からテスト計画の初日と最終日を得る
$plid = $_GET['plan'];
$sqlD1 = "SELECT cast(substring(min(`execution_ts`),1,10) as date) Sdate FROM `executions`
WHERE `testplan_id` = ? ;";
$sqlD2 = "SELECT cast(substring(max(`execution_ts`),1,10) as date) Edate FROM `executions`
WHERE `testplan_id` = ? ;";
$stmtd1 = $db->executeSQL($dbh,$sqlD1,array($plid));
$resultd1 = $stmtd1->fetch(PDO::FETCH_ASSOC);
$stmtd2 = $db->executeSQL($dbh,$sqlD2,array($plid));
$resultd2 = $stmtd2->fetch(PDO::FETCH_ASSOC);
$startDay = $resultd1['Sdate'];
$endDay = $resultd2['Edate'];
集計用 SQL
SQL の例です。function にしています。
一つのテストケースについて最新の状態を得るため subquery を使います。
パラメータとして、テスト計画ID、開始日、ターゲット日を受け取ります。
標準以外のステータスを使ってる場合、[status = 'p'] の 'p' を標準外のステータスコードにすることで対応できます。
<?php
// トータルケース
function sql_execCount(){
//
$sql="SELECT count(distinct(tcversion_id)) as eCase
FROM `executions` e
WHERE `testplan_id`=:plid and e.execution_ts >=:s_date and
e.execution_ts <=:e_date and
e.execution_ts = (SELECT MAX(x.execution_ts)
FROM executions AS x WHERE e.tcversion_id= x.tcversion_id and x.testplan_id=:plid);";
return $sql;
}
// 成功ケース
function sql_successCount(){
//
$sql="SELECT count(distinct(tcversion_id)) as pCase
FROM `executions` e
WHERE `testplan_id`=:plid and e.execution_ts >=:s_date and
e.execution_ts <=:e_date and (status = 'p') and
e.execution_ts = (SELECT MAX(x.execution_ts)
FROM executions AS x WHERE e.tcversion_id = x.tcversion_id and x.testplan_id=:plid);";
return $sql;
}
// ブロックケース
function sql_blockCount(){
//
$sql="SELECT count(distinct(tcversion_id)) as bCase
FROM `executions` e
WHERE `testplan_id`=:plid and e.execution_ts >=:s_date and
e.execution_ts <=:e_date and (status = 'b') and
e.execution_ts = (SELECT MAX(x.execution_ts)
FROM executions AS x WHERE e.tcversion_id= x.tcversion_id and x.testplan_id=:plid);";
return $sql;
}
// 失敗ケース
function sql_failCount(){
//
$sql="SELECT count(distinct(tcversion_id)) as fCase
FROM `executions` e
WHERE `testplan_id`=:plid and e.execution_ts >=:s_date and
e.execution_ts <=:e_date and status = 'f' and
e.execution_ts = (SELECT MAX(x.execution_ts)
FROM executions AS x WHERE e.tcversion_id= x.tcversion_id and x.testplan_id=:plid);";
return $sql;
?>
配列・SQLの準備など
<?php
//HIGHCHARTSに渡す配列
$aPass = array();
$aBlock = array();
$aNG = array();
// SQL をセット
$sql_Total = sql_execCount(); //トータル実施数
$sql_OK = sql_successCount(); // OKケース
$sql_Block = sql_blockCount(); // Blockケース
$sql_NG = sql_failCount(); // NGケース
//最初の日
$d1 = $startDay;
//次の日
$d2 = date("Y-m-d",strtotime("+1 day",strtotime($d1)));
$d3 = $startDay;
?>
SQL を実行して日毎の結果を得る
1日ごとのデータ得て配列に入れていきます。
LOOP毎に翌日をセットし、最終日まで繰り返します。
<?php
while( $d2 <= $endDay ){
// 取得日 $d3 の次の日
$dd = date("Y-m-d",strtotime("+1 day",strtotime($d3))) . " ";
//配列にDBからの日付を入れる
$aDates[] = substr($d3,05);
//Total
$stmt_Total = $db->executeSQL($dbh,$sql_Total,array(':plid'=>$plid,':s_date'=>$d1,':e_date'=>$dd));
$result_Total = $stmt_Total->fetch(PDO::FETCH_ASSOC);
//OK
$stmt_OK = $db->executeSQL($dbh,$sql_OK,array(':plid'=>$plid,':s_date'=>$d1,':e_date'=>$dd));
$result_OK = $stmt_OK->fetch(PDO::FETCH_ASSOC);
//Block
$stmt_Block = $db->executeSQL($dbh,$sql_Block,array(':plid'=>$plid,':s_date'=>$d1,':e_date'=>$dd));
$result_Block = $stmt_Block->fetch(PDO::FETCH_ASSOC);
//NG
$stmt_NG = $db->executeSQL($dbh,$sql_NG,array(':plid'=>$plid,':s_date'=>$d1,':e_date'=>$dd));
$result_NG = $stmt_NG->fetch(PDO::FETCH_ASSOC);
$tExec = $result_Total['eCase']; //Total Count
$tPass = $result_OK['pCase']; // OK
$tBlock = $result_Block['bCase']; // Block
$tNG = $result_NG['fCase']; // NG
// 配列にデータを格納していく
$aPass[] = $tPass;
$aBlock[] = $tBlock;
$aNG[] = $tNG;
//$d3 を翌日
//$d2 を翌々日にセット
$d3 = $d2;
$d2 = strtotime($d2);
$d2 = date("Y-m-d",strtotime("+1 day",$d2));
}
?>
グラフ化(HighChartsでの例)
端折ってるのでこのままでは動作しないかも…
<?php
// Hichart に渡すデータの作成 : 配列を CSV 化
$chart_pass = implode(",", $aPass);
$chart_block = implode(",", $aBlock);
$chart_NG = implode(",", $aNG);
$chart_dates = "'" . implode("','", $aDates) . "'";
$wd = $conf['gp']['width']; //グラフの幅 pix
$hi = $conf['gp']['height']; //グラフの高さ
highchart_graphHeader($wd,$hi,"Testlinkテスト進捗");
drawGraph($chart_dates,$chart_NG,$chart_block,$chart_pass);
?>
<?php
function drawGraph($chart_dates,$chart_NG,$chart_block,$chart_pass){
?>
<script type="text/javascript">
var chart;
function draw() {
// グラフオプションを指定
var options = {
// 出力先を指定
chart :{renderTo : "container",
backgroundColor: 'wheat',
plotBackgroundColor: 'lightyellow',
borderWidth: 1
},
// タイトルを指定
title : {text: "テスト進捗"},
// x軸のラベルを指定
xAxis : {title: {text: "Day"},
categories: [<?php echo $chart_dates;?>]
},
// y軸のラベルを指定
yAxis : {title: {text: "テストケース"},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
plotOptions: {
area: {
stacking: 'normal',
dataLabels: {
disabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
// データ系列を作成
// データ系列を作成
series: [
{type: 'column', name: "NG", data: [<?php echo $chart_NG;?>],color: 'red'},
{type: 'column', name: "Block", data: [<?php echo $chart_block;?>],color: 'lime'},
{type: 'column', name: "OK", data: [<?php echo $chart_pass;?>],color: 'dodgerblue'}
]
}
// グラフを作成
chart = new Highcharts.Chart(options);
}
// ページがロードされた後に、グラフを出力する
document.body.onload = draw();
</script>
<?php
}
?>
参考:Table構造
testprojects
testprojects | 用途 | 参照先 |
---|---|---|
id | テスㇳプロジェクトのID | nodes_hierarchy > id |
notes | テストプロジェクトの説明 | |
active | 有効 | |
color | プロジェクトの背景色(無効) | htmlカラーコード |
option_reqs | 要件管理 | |
option_priority | テスト優先度 | |
option_automation | 自動テスト | |
options | 拡張機能 | |
prefix | テストプロジェクトの Prefix | |
tc_counter | テストケースの外部IDの最大値 (テストケース数ではない) |
|
is_public | 公開 | |
issue_tracker_enabled | バグトラッカー有効 | |
reqmgr_integration_enabled | ||
api_key |
testplans
testplanss | 用途 | 参照先 |
---|---|---|
id | テスト計画のID | executions > testplan_id |
testptoject_id | テスト計画が属するテストプロジェクトのID | testprojects > id |
notes | テスト計画の説明 | |
active | 有効 | |
is_open | ||
is_public | 公開 | |
api_key |