うさぎ組

ソフトウェア開発、チームによる製品開発、アジャイル、ソフトウェアテスト

Spockのレポート生成はHTML, Markdown, Asciidocできるし、カスタムも出来るんだぜ

GroovyのテスティングフレームワークであるSpockは標準ではレポート生成機能はありません。 多くはGradleでビルドしたときのxmlやhtmlを利用していると思います。

Spockにはspock-reportという拡張ライブラリがあり、これを依存関係に追加するだけでテスト結果のレポートを独自に追加で生成できます。 しかもなんと、HTMLだけではなくMarkdownやAsciidocとして生成することもできます。 また、最新のspock-reportではテストコードからレポートに文章を追加することも出来るようになりました。

今回はそんなspock-reportの便利機能をいくつか紹介します。

github.com

本ブログで説明しているサンプルコード全部入りのspockおよびspock-reportのプロジェクトテンプレートはこちら。

github.com

本記事はG* Advent Calendar 2017の16日目になります。

G* Advent Calendar 2017 - Qiita

最低限の使い方

最低限のHTMLレポートを生成するだけであれば、Spockでテストコードを利用しているプロジェクトに依存関係を追加するだけになります。(テストコードディレクトリが src/test/groovy 配下であればこれだけ。という感じです。前提などは後述します)

// make sure to enable jcenter() or mavenCentral()
repositories {
  jcenter()
}

dependencies {
    testCompile( 'com.athaydes:spock-reports:1.4.0' ) {
        transitive = false // this avoids affecting your version of Groovy/Spock
    }
    // if you don't already have slf4j-api and an implementation of it in the classpath, add this!
    testCompile 'org.slf4j:slf4j-api:1.7.13'
    testCompile 'org.slf4j:slf4j-simple:1.7.13'
}

もしslf4jなどのログライブラリがすでに指定されているなら最後の2行は不要です。 これで gradle build とすると build/spock-report/index.html としてレポートファイルが生成されます。なので、Gradleが生成する build/reports/tests/test/index.html とは別に生成される形になります。

見た目はこれです。クラシカルですが見やすいかなぁとは思います。

f:id:kyon_mm:20171216075806p:plain

f:id:kyon_mm:20171216075834p:plain

レポートをMarkdown/Asciidocとして生成する

デフォルトのレポートはHTMLを生成しますが、デフォルトでMarkdownの生成にも対応しています。 また、テンプレートファイルを2つ用意することでAsciidocでの出力にも対応しています。

使い方は src/test/resources/META-INF/services/com.athaydes.spockframework.report.IReportCreator.properties というファイルをプロジェクトに追加して、設定を記述していく形になります。

Markdownで生成するためにはこのファイルを作成して1行追加するだけです。

com.athaydes.spockframework.report.IReportCreator=com.athaydes.spockframework.report.template.TemplateReportCreator

生成されるMarkdownは次のようになります。

# Specification run results

## Specifications summary

<small>Created on Sat Dec 16 08:00:48 JST 2017 by k.kobayashi</small>

| Total          | Passed          | Failed          | Feature failures | Feature errors   | Success rate        | Total time (ms) |
|----------------|-----------------|-----------------|------------------|------------------|---------------------|-----------------|
| 2 | 1 | 1 | 3  | 0 | 0.5| 108.0   |

## Specifications


|Name  | Features | Failed | Errors | Skipped | Success rate | Time |
|------|----------|--------|--------|---------|--------------|------|
| com.example.WhenReportingSpockTest | 7 | 3 | 0 | 0 | 0.5714285714285714 | 106 |
| com.example.WhenUsingRawHtmlHeader | 1 | 0 | 0 | 0 | 1.0 | 2 |


<small>Generated by <a href="https://github.com/renatoathaydes/spock-reports">Athaydes Spock Reports</a></small>

このTemplateReportCreatorクラスはテンプレートのファイルさえ渡せば基本的には動作します。デフォルトではMarkdownしかありませんが、自分で例えばAsciidocのテンプレートを用意すれば生成することができます。

先のファイルに次を追記し、テンプレートファイルを src/test/resources/ 配下に用意しましょう。

# markdown or asciidoc
com.athaydes.spockframework.report.IReportCreator=com.athaydes.spockframework.report.template.TemplateReportCreator

# asciidoc
com.athaydes.spockframework.report.template.TemplateReportCreator.specTemplateFile=/spec-template.ad
com.athaydes.spockframework.report.template.TemplateReportCreator.reportFileExtension=ad
com.athaydes.spockframework.report.template.TemplateReportCreator.summaryTemplateFile=/summary-template.ad
com.athaydes.spockframework.report.template.TemplateReportCreator.summaryFileName=summary.ad
com.athaydes.spockframework.report.template.TemplateReportCreator.enabled=true

ここでは src/test/resources/ 配下に summary-template.adspec-template.ad というファイル名で用意しました。 レポートのトップページが summaryTemplateFile で各テストクラス(Specification) のページが specTemplateFile になります。

実際に使ったasciidocファイルはリポジトリにあります。 見た目はこうなります。

= Spock Test Results
// toc-title definition MUST follow document title without blank line!
:toc-title: Table of Contents

// numbering from here on
:numbered:

== Specification run results

=== Specifications summary

[small]#created on Sat Dec 16 08:03:19 JST 2017 by k.kobayashi#

.summary
[options="header"]
|==================================================================================================================================
| Total          | Passed          | Failed          | Feature failures | Feature errors   | Success rate        | Total time (ms)
| 2 | 1 | 1 | 3  | 0 | 0.5| 111.0
|==================================================================================================================================

=== Specifications

[options="header"]
|===================================================================
|Name  | Features | Failed | Errors | Skipped | Success rate | Time
| com.example.WhenReportingSpockTest | null | null | null | null | null | null
| com.example.WhenUsingRawHtmlHeader | null | null | null | null | null | null

|===================================================================



<<<<

include::com.example.WhenReportingSpockTest.ad[]

<<<<

include::com.example.WhenUsingRawHtmlHeader.ad[]


[small]#generated by https://github.com/renatoathaydes/spock-reports[Athaydes Spock Reports]#

Asciidocすばらしす。includeできているところとかいいですよね!

Markdownのときに利用されているテンプレートファイルは次になります。Markdownのテンプレートを変更したいときにはここのファイルをコピペしてきて改変するといいでしょう。

spock-reports/src/main/resources/templateReportCreator at master · renatoathaydes/spock-reports · GitHub

テストコードから説明を追加する

spock-reportでSpecificationやFeature毎に説明を追加する方法は今まではSpockの機能を使うしかありませんでした。

  1. @Narrative で Specificationの説明
  2. @Ignoreなどで無視されていることを表明
  3. given, when, then, whereなどのラベルによるステップの説明

spock-reportのバージョン1.4.0からは次が使えるようになりました。

  1. reportHeaderメソッドによるSpecification毎の説明を追加
  2. reportInfoメソッドによるfeature毎の説明を追加

これらはSpecification内で実行することを想定していて、reportHeaderメソッドは setupSpec メソッド内で実行、 reportInfo メソッドはfeature内で実行することを想定しています。

例えば次のようになります。

  def setupSpec() {
    reportHeader """setupSpecでreportHeaderメソッドを呼び出しておくことで、
                   |SpecificationのHeaderとして文章を記述できます。@Narrativeで十分な気もしますが。""".stripMargin("|")
  }

  def "My feature"() {
    expect:
    reportInfo "フィーチャ毎のメモだよ"
    reportInfo "2行目も書けるよ"
  }

これで生成したレポートは次のようになります。

HTML版において、 h2 タグを使いたいなぁとかあればそのまま記述する形になります。

  def setupSpec() {
    reportHeader "<h2> h2をうめこんで追加することもできます </h2>"
  }

もちろん「MarkdownやAsciidocでしか見ないんだぜ!」っていう場合には ## で表現したいでしょうから、それに沿うようなテンプレートを用意すれば期待した生成結果になります。(デフォルトのMarkdownでは <h2> と指定されることを想定しているので、html埋め込み記述になっている部分を外せばいいだけです)

Groovy in Action

Groovy in Action

  • 作者: Dierk Konig,Paul King,Guillaume Laforge,Hamlet D'arcy,Cedric Champeau
  • 出版社/メーカー: Manning Pubns Co
  • 発売日: 2015/06/27
  • メディア: ペーパーバック
  • この商品を含むブログを見る