C#のテキストテンプレートを使ってみた(2)
ランタイムテキストテンプレートを使ってgoogletestのレポートをHTML形式に変換してみた
どもです。
前回は、C#のランタイムテキストテンプレートを使用してHTMLのtableタグを生成しました。
今回のエントリでは、これを少し発展させて、実際にHTML形式のファイルを生成してみます。
1.背景と目的
今回のエントリの背景と内容を、簡単ですが書きます。
1.1.背景
最近、C/C++(VC++)のコードの単体テストを真面目に実施しています。
単体テストのフレームワークは、googletestを使用しています。
この単体テストに対して、実施した単体テストの件数を知りたくなりました。
1つ1つ数えても良いのですが、それはメンドクサイ大変なので、自動で計算できる仕組みがほしくなりました。
また結果(OK/NG)についても、同時に知りたくなりました。
1.2.内容
今回のエントリでは、googletestの実行結果(XML)をC#のランタイムテキストテンプレートを用いてHTML形式に変換する方法、コードについて書きます。
2.開発環境
今回の開発環境は、以下の通りです。
OS | Windows10 Pro ver.1903 |
---|---|
CPU | i7-8700 |
IDE | VisualStudioCommunity2019 ver.16.5.1 |
.Net Framework | 4.7 |
アプリケーションの種類 | コンソールアプリケーション |
googletest | 1.10.0 |
googleテストのダウンロードやビルドについては、以下のリンク先を参照してください。
- VisualStudioとCMakeでGoogle testをビルドする(1)
- VisualStudioとCMakeでGoogle testをビルドする(2)
ビルドしたGoogle testをVisualStudioで使ってみる - googletest github
3.googletestのレポート
まず、googletestのレポート生成です。
googletestでは、以下のコマンドでXML形式のレポートが生成できます。
(googletestの実行ファイル) --gtest_output=xml:(xmlファイルの出力先)
これにより、実行結果がXML形式で出力されます。
4.HTML形式の変換
次は、XMLを読み込んでHTML形式のレポートに変換する処理です。
C#では、以下の順番で処理を実行します。
- XMLを読み込んで、オブジェクトに変換する。
- ランタイムテキストテンプレートを用いて、HTML形式に変換する。
この2つの手順を、それぞれ実現していきます。
4.1.XMLを読み込んでオブジェクトに変換する
まず、XMLファイルを読み込んで、C#でのオブジェクトに変換します。
C#では、XMLファイルの読み込みに対応した「XmlSerializer」クラスが標準で用意されています。
具体的なコードは、以下!
using (var xmlReader = new StreamReader(fileInfo.FullName, Encoding.GetEncoding("UTF-8")))
{
var serializer = new XmlSerializer(typeof(TestSuites));
var testSuites = (TestSuites)serializer.Deserialize(xmlReader);
}
ここで「TestSuites」クラスは、googletestのXML形式のレポートの内容を保持するモデルクラスです。
具体的には、以下のような構成になっています。
この図に従って、かつXMLの各要素/タグに対応づけながらモデルクラスを実装したのが以下!
<code>[XmlRoot("testsuites")]
public class TestSuites
{
[XmlAttribute("tests")]
public int Tests { get; set; }
[XmlAttribute("failures")]
public int Failures { get; set; }
[XmlAttribute("disabled")]
public int Disabled { get; set; }
[XmlAttribute("errors")]
public int Errors { get; set; }
[XmlAttribute("time")]
public float Time { get; set; }
[XmlAttribute("timestamp")]
public DateTime TimeStamp { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
[XmlElement("testsuite")]
public List<TestSuite> TestItems { get; set; }
public string TestName { get; set; }
public string HtmlFileName {
get
{
return this.TestName + ".html";
}
}
}
[XmlRoot("testsuite")]
public class TestSuite
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("tests")]
public int Tests { get; set; }
[XmlAttribute("failures")]
public int Failures { get; set; }
[XmlAttribute("disabled")]
public int Disabled { get; set; }
[XmlAttribute("errors")]
public int Errors { get; set; }
[XmlAttribute("time")]
public float Time { get; set; }
[XmlAttribute("timestamp")]
public DateTime TimeStamp { get; set; }
[XmlElement("testcase")]
public List<TestCase> TestCases { get; set; }
}
[XmlRoot("testcase")]
public class TestCase
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("status")]
public string Status { get; set; }
[XmlAttribute("result")]
public string Result { get; set; }
[XmlAttribute("time")]
public float Time { get; set; }
[XmlAttribute("timestamp")]
public DateTime Timestamp { get; set; }
[XmlAttribute("classname")]
public string ClassName { get; set; }
[XmlElement("failure")]
public Failure Failure { get; set; }
public string Judge
{
get
{
if (null == this.Failure)
{
return "OK";
}
else
{
return "NG";
}
}
}
}
[XmlRoot("failure")]
public class Failure
{
[XmlAttribute("message")]
public string Message { get; set; }
}
なお、各プロパティに対して、「XmlElement」属性を設定しています。
これにより、Deserializeにより、各プロパティに対応するXML要素の値が格納されます。
属性の使い方については、属性を使用した XML シリアル化の制御が参考になるかと思います。
4.2.ランタイムテキストテンプレートを用いてHTML形式に変換する
XMLの内容の取得ができたので、実際にHTML形式に変換します。
4.2.1.ページの構成
今回生成されるHTML形式のレポートは、以下のページ構成にします。
4.2.2.index.htmlのテンプレート
トップページになるindex.htmlのテンプレートは、以下にします。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
<title>Test report - overview and content</title>
<link rel="stylesheet" type="text/css" href="report.css" />
</head>
<body>
<div>
<h1>Test report</h1>
</div>
<div>
<table>
<caption>Overview</caption>
<tbody>
<tr>
<th>Tests</th>
<th>Failures</th>
<th>Disables</th>
<th>Errors</th>
<th>Time</th>
</tr>
<tr>
<td><#= TestNum #></td>
<td><#= FailureNum #></td>
<td><#= DisableNum #></td>
<td><#= ErrorNum #></td>
<td><#= TimeNum #></td>
</tr>
</tbody>
</table>
</div>
<div>
<table>
<caption>Content</caption>
<tbody>
<tr>
<th>テスト名</th>
<th>Tests</th>
<th>Failure</th>
<th>Disables</th>
<th>Errors</th>
<th>Time</th>
<th>Timestamp
</tr>
<# foreach (var testSuiteItem in TestSuitesList) { #>
<tr>
<td><a href="<#= testSuiteItem.HtmlFileName #>"><#= testSuiteItem.TestName #></td>
<td><#= testSuiteItem.Tests #></td>
<td><#= testSuiteItem.Failures #></td>
<td><#= testSuiteItem.Disabled #></td>
<td><#= testSuiteItem.Errors #></td>
<td><#= testSuiteItem.Time #></td>
<td><#= testSuiteItem.TimeStamp #></td>
</tr>
<# } #>
</tbody>
</table>
</div>
</body>
</html>
前半部分、「Overview」テーブルで、実行したテストの合計情報を表示します。
次の「Content」テーブルで、テスト毎の合計情報を表示します。
更に「Content」テーブルの名前から各テストの詳細ページに移動できるよう、リンクを設定しています。
4.2.3.test_suite_name.htmlのテンプレート
次に、各テストケースのページのテンプレートは、以下にします。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
<title>Test report<#= TestSuites.Name #></title>
<link rel="stylesheet" type="text/css" href="report.css" />
</head>
<body>
<div>
<div>
<h1>Test report - detail</h1>
</div>
<div>
<a href="index.html">TOP</a>
</div>
<div>
<# foreach (var testSuite in TestSuites.TestItems) { #>
<table>
<caption><#= testSuite.Name #></caption>
<tbody>
<tr>
<th>test name</th>
<th>State</th>
<th>Result</th>
<th>Judge</th>
<th>Timestamp</th>
<th>Time</th>
</tr>
<# foreach (var testCase in testSuite.TestCases) { #>
<tr>
<td><#= testCase.Name #></td>
<td><#= testCase.Status #></td>
<td><#= testCase.Result #></td>
<td><#= testCase.Judge #></td>
<td><#= testCase.Timestamp #></td>
<td><#= testCase.Time #></td>
</tr>
<# } #>
</tbody>
</table>
<# } #>
</div>
</div>
</body>
</html>
このページは、ひたすらテストの結果の出力を繰り返すだけです。
以上で、HTML形式の変換は完了です。
5.出力結果
これまで紹介したコードを実装、実行した結果を示します。
まずはトップ画面!
次に、各テストケースに詳細画面!
今回示した例ではNGの項目のエラー情報へのリンクは設定できていませんが、最も基本的な内容である実行件数とOK/NGの結果は確認できます。
また、CSSは一切設定していないので、ホントに文字だけの画面になってします。
画面のデザインは、index.htmlと同じフォルダに「report.css」という名前のCSSファイルを読み込むようになっています。
なので、各々の環境に合せて設定してください。
6.まとめ
今回は、ランタイムテキストテンプレートを使用して、googletestのXML形式のレポートをHTML形式に変換する内容について書きました。
googletestの内容を、特に加工何もせずにそのまま出力するだけですが、簡単にできました。
ランタイムテキストテンプレートを少し変更することで、情報を絞ったり、もっと見易い表示にできるのではないかと思います。
ではっ!
ex.公開しています
今回紹介したツールの全コードを、GitHubで公開しています。
エントリ中では紹介しきれなかった内容は、コチラを参照してください。
さらに言えば、使てみていただけると幸いです。
ディスカッション
コメント一覧
まだ、コメントがありません