Recommended
PDF
PDF
perfを使ったPostgreSQLの解析(前編)
PPTX
PDF
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
PDF
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
PDF
PDF
PDF
PDF
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
PDF
PDF
PDF
Elasticsearch勉強会#44 20210624
PDF
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
PDF
PPTX
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
PDF
PDF
NeurIPS2021論文読み会 (parameter prediction for unseen deep architecture)
PDF
PDF
Cache-Oblivious データ構造入門 @DSIRNLP#5
PPTX
DeNA_Techcon2017_DeNAでのチート・脆弱性診断への取り組み
PPTX
PPTX
PDF
PostgreSQL Unconference #5 ICU Collation
PPTX
PDF
PPTX
GitLab から GitLab に移行したときの思い出
PDF
PDF
Groovyしたり RPしなかったり あとは時々布教活動したり
PDF
More Related Content
PDF
PDF
perfを使ったPostgreSQLの解析(前編)
PPTX
PDF
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
PDF
コレクションフレームワーク関連セッション(JavaOne & Devoxx報告会 2022 発表資料)
PDF
PDF
PDF
What's hot
PDF
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
PDF
PDF
PDF
Elasticsearch勉強会#44 20210624
PDF
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
PDF
PPTX
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
PDF
PDF
NeurIPS2021論文読み会 (parameter prediction for unseen deep architecture)
PDF
PDF
Cache-Oblivious データ構造入門 @DSIRNLP#5
PPTX
DeNA_Techcon2017_DeNAでのチート・脆弱性診断への取り組み
PPTX
PPTX
PDF
PostgreSQL Unconference #5 ICU Collation
PPTX
PDF
PPTX
GitLab から GitLab に移行したときの思い出
PDF
Viewers also liked
PDF
Groovyしたり RPしなかったり あとは時々布教活動したり
PDF
PDF
PDF
Closures and methodMissing are real
PDF
PDF
PDF
Similar to Introduction to Spock
PDF
PDF
PPTX
PDF
テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第33回】
PDF
PDF
PDF
PDF
PDF
PDF
PDF
Kink: invokedynamic on a prototype-based language
PDF
C# から java へのプログラム移植で体験したtddの効果は?
PPTX
PDF
オブジェクト指向開発におけるObject-Functional Programming
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PPTX
PDF
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
KEY
PDF
Object-Funcational Analysis and design
PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Recently uploaded
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):エヌビディア合同会社 テーマ1「NVIDIA 最新発表製品等のご案内」
PDF
ニューラルプロセッサによるAI処理の高速化と、未知の可能性を切り拓く未来の人工知能
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):Pacific Teck Japan テーマ3「『TrinityX』 AI時代のクラスターマネジメ...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):コアマイクロシステムズ株式会社 テーマ 「AI HPC時代のトータルソリューションプロバイダ」
PPTX
ChatGPTのコネクタ開発から学ぶ、外部サービスをつなぐMCPサーバーの仕組み
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):日本ヒューレット・パッカード合同会社 テーマ1「大規模AIの能力を最大限に活用するHPE Comp...
PDF
論文紹介:HiLoRA: Adaptive Hierarchical LoRA Routing for Training-Free Domain Gene...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):日本ヒューレット・パッカード合同会社 テーマ3「IT運用とデータサイエンティストを強力に支援するH...
PDF
論文紹介:MotionMatcher: Cinematic Motion Customizationof Text-to-Video Diffusion ...
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):富士通株式会社 テーマ1「HPC&AI: Accelerating material develo...
PDF
論文紹介:DiffusionRet: Generative Text-Video Retrieval with Diffusion Model
PDF
AI開発の最前線を変えるニューラルネットワークプロセッサと、未来社会における応用可能性
PDF
PCCC25(設立25年記念PCクラスタシンポジウム):Pacific Teck Japan テーマ2「『Slinky』 SlurmとクラウドのKuber...
PDF
膨大なデータ時代を制する鍵、セグメンテーションAIが切り拓く解析精度と効率の革新
PPTX
2025年11月24日情報ネットワーク法学会大井哲也発表「API利用のシステム情報」
Introduction to Spock 1. 2. お前誰よ
• 名前:杉浦孝博
• twitter : @touchez_du_bois
• 昼のお仕事:
Grailsアプリ、C#アプリ、VB.NETアプリの保守
とあるサイトの運用、保守
時々開発
3. 4. 5. 6. 本日の内容
• 入門編
• Spockとは
• Spockの利点
• 構造
• Power Assert
• データ駆動テスト
• 相互作用中心のテスト
7. 本日の内容
• その他
• Spockの拡張機能
• Spockのモジュール
• Spockと一緒に
• まとめ
8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Specification
• 対象クラスのテスト内容・仕様を記述。
• spock.lang.Specificationクラスを継
承。
import spock.lang.*
!
class TargetClassSpec extends Specification {
// Fields
// Fixture Methods
// Feature Methods
// Helper Methods
}
18. Fields
• テストで使用するオブジェクトを宣言。
• Featureメソッド実行ごとに初期化され
るため、基本的に、インスタンス変数は
Featureメソッド間で共有できない。
• 共有したい場合、@Sharedを付ける。
@Shared
def stack = new Stack()
19. Fixture Methods
• テストの準備(setup)、後始末(cleanup)
を行う。
def setup() {} // 各Featureメソッドの実行前に実行
def cleanup() {} // 各Featureメソッドの実行後に実行
def setupSpec() {} // 最初のFeatureメソッドの実行前に実行
def cleanupSpec() {} // 最後のFeatureメソッドの実行後に実行
20. Feature Methods
• テストの内容、仕様の内容を記述。
• 4つのフェーズからなり、それぞれBlock
を記述。
• Setup(前処理、前提条件)
• Stimulus(実行)
• Response(検証)
• Cleanup(後処理)
21. 22. BlockとPhase
Block Phase
setup: / given: Setup
when: Stimulus
then: Response
expect: Stimulus + Response
cleanup: cleanup
where: -
and: -
23. 24. 25. Helper Methods
• Featureメソッドが大きくなった場合
に、意味がある内容をメソッド化する。
• setupやcleanupも処理が大きくなった
場合に、メソッド化する。
26. 27. 28. Power Assert
• テスト・仕様の内容を満たさない場合、
各部分式の値を表示する。
• SpockからGroovy本体に取り込まれ
た。
⇒ どこが違うか、どこから違うか、
ということが、比較的わかりやすい。
29. Power Assert
def "maximum of two numbers"() {
setup:
def a = 2
def b = 1
def c = 1
expect:
Math.max(a, b) == c
}
30. 31. Power Assert
@Unroll
def "str1 == str2"() {
setup:
def str1 = "abcdefghijklmnopqrstuvwxyz"
def str2 = "abcdefghijk1mnopqrstuvwxyz"
expect:
str1 == str2
}
32. Power Assert
str1 == str2
| | |
| | abcdefghijk1mnopqrstuvwxyz
| false
| 1 difference (96% similarity)
| abcdefghijk(l)mnopqrstuvwxyz
| abcdefghijk(1)mnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
33. 34. 35. 36. 37. データテーブル
• コードとデータを分離。
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a | b | c // データ変数
1 | 3 | 3 // データ行
7 | 4 | 7 // 〃
0 | 0 | 0 // 〃
}
// Math.max(1, 3) == 3
// Math.max(7, 4) == 7
// Math.max(0, 0) == 0
// の3イテレーション実施。
38. データテーブル
• 入力値と期待値を(多少)わかりやすく。
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a | b || c // データ変数
1 | 3 || 3 // データ行
7 | 4 || 7 // 〃
0 | 0 || 0 // 〃
}
39. どこが失敗?
• 何回目のイテレーションで失敗したか
わからない。
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a | b || c
1 | 3 || 3
7 | 4 || 4
0 | 0 || 0
}
maximum of two numbers FAILED
!
Condition not satisfied:
!
Math.max(a, b) == c
| | | | |
7 7 4 | 4
false
40. @Unroll
• @Unrollを付けたメソッドまたはクラス
は、イテレーション毎にレポートされる。
@Unroll
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a | b || c
1 | 3 || 3
7 | 4 || 4
0 | 0 || 0
}
maximum of two numbers[0] PASSED
maximum of two numbers[1] FAILED
!
Math.max(a, b) == c
| | | | |
7 7 4 | 4
false
!
maximum of two numbers[2] FAILED
41. もう少しわかりやすく
• メソッド名にプレースホルダを使うこと
で、レポート結果がわかりやすく。
@Unroll
def "maximum of #a and #b is #c"() {
expect:
Math.max(a, b) == c
where:
a | b || c
1 | 3 || 3
7 | 4 || 4
0 | 0 || 0
}
maximum of 1 and 3 is 3 PASSED
maximum of 7 and 4 is 4 FAILED
!
Math.max(a, b) == c
| | | | |
7 7 4 | 4
false
!
maximum of 0 and 0 is 0 FAILED
42. データパイプ
• データ変数ごとにデータプロバイダを用
意し、<<演算子で接続する。
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a << [ 1, 7, 0 ]
b << [ 3, 4, 0 ]
c << [ 3, 7, 0 ]
}
// Collectionだけでなく、テキストファイルやデータベースなど、
// 外部リソースから取得することも可能。
43. データパイプで複数の値
• データプロバイダが複数の値を返す場合、
複数のデータ変数に同時に接続可能。
@Shared sql = Sql.newInstance("jdbc:h2:mem:", "org.h2.Driver")
!
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
[a, b, c] << sql.rows("select a, b, c from maxdata")
}
44. データ変数へ代入
• データ変数に直接値を代入することも可
能。
def "maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a = 3
b = Math.random() * 100
c = a > b ? a : b
}
45. 46. 47. 相互作用中心のテスト
• Publish - Subscribeのように、
オブジェクト同士の振る舞いをテスト・
仕様化したい場合。
• 相互作用相手について、
本物のオブジェクトを使うこともあるが、
モックオブジェクトを使うこともある。
48. 49. 50. プログラム例
class Publisher {
List<Subscriber> subscribers = []
void send(String message) {
subscribers.each {
it.receive(message)
}
}
void send(Event event) {
subscribers.each {
it.receive(event)
}
}
}
!
interface Subscriber {
void receive(String message)
void receive(Event event)
}
51. モックオブジェクトの作成
• Mockメソッドで作成
// モックオブジェクトのインタフェース(クラス)を指定して作成
def subscriber = Mock(Subscriber)
!
// 変数の型からモックオブジェクトのインタフェース(クラス)の
// 型を推論
Subscriber subscriber = Mock()
52. モックオブジェクトの準備
• 例えば、こんな感じで。
class PublisherSpec extends Specification {
Publisher publisher = new Publisher()
Subscriber subscriber1 = Mock()
Subscriber subscriber2 = Mock()
!
def setup() {
publisher.subscribers << subscriber1
publisher.subscribers << subscriber2
}
}
53. モッキング
• テスト/仕様対象のオブジェクトと、相互
作用するオブジェクトの間の、インタラ
クション(相互作用)を宣言すること。
def "should send messages to all subscribers"() {
when:
publisher.send("hello")
!
then:
1 * subscriber1.receive("hello")
1 * subscriber2.receive("hello")
}
54. インタラクション
• 多重度(cardinality)、対象制約(target
constraint)、メソッド制約(method
constraint)、引数制約(argument
constraint)からなる。
1 * subscriber.receive("hello")
| | | |
| | | argument constraint
| | method constraint
| target constraint
cardinality
55. 多重度
• 何回メソッド呼び出しが行われるかを指
定する。
• 固定の数値や範囲を指定可能。
1 * subscriber.receive("hello") // 1回
0 * subscriber.receive("hello") // 0回
(1..3) * subscriber.receive("hello") // 1〜~3回
(1.._) * subscriber.receive("hello") // 1回以上
(_..3) * subscriber.receive("hello") // 3回以下
_ * subscriber.receive("hello") // 0回以上
56. 対象制約
• どのオブジェクト(モックオブジェクト)
を対象にするかを指定する。
1 * subscriber1.receive("hello") // subscriber1に対して
1 * _.receive("hello") // 任意のモックオブジェクト
57. メソッド制約
• どのメソッド呼び出しを対象にするかを
指定する。
1 * subscriber.receive("hello") // receiveメソッド
1 * subscriber._("hello") // 任意のメソッド
1 * subscriber./r.*e/("hello") // rで始まりeで終わるメソッド
58. 引数制約
• どんな引数を期待するかを指定する。
// 引数が"hello"という文字列
1 * subscriber.receive("hello")
// 引数が"hello"という文字列ではない
1 * subscriber.receive(!"hello")
// 引数なし
1 * subscriber.receive()
// 1引数(nullも含む)
1 * subscriber.receive(_)
// 任意の引数
1 * subscriber.receive(*_)
// nullではない
1 * subscriber.receive(!null)
// String型の引数(nullは含まれない)
1 * subscriber.receive(_ as String)
// 指定された条件を満たす引数
1 * subscriber.receive({ it.size() > 3 })
59. 60. スタビング
• モッキングに比べ、多重度の指定がない
代わりに、レスポンスジェネレータ
(Response Generator)を指定する。
subscriber1.receive(_) >> "ok"
| | | |
| | | response generator
| | argument constraint
| method constraint
target constraint
61. スタビングの例
interface Subscriber {
def setup() {
publisher.subscribers << subscriber1
publisher.subscribers << subscriber2
!
// receiveメソッドの戻り値は常に"ok"とする
subscriber1.receive(_) >> "ok"
subscriber2.receive(_) >> "ok"
}
// String型の値を返すように変更
String receive(String message)
String receive(Event message)
}
62. 一連の値を返す
• >>>演算子の後に、リストなどイテレー
ティブな値を指定する。
// 1回目: "ok"
// 2回目: "error"
// 3回目: "error"
// 4回目以降: "ok"
subscriber1.receive(_) >>> ["ok", "error", "error", "ok"]
63. 64. 副作用の実行
• >>演算子の後のクロージャ中に、副作用
としての処理を記述する。
subscriber1.receive(_) >> { String message ->
println message
throw new InvalidArgumentException()
}
65. 66. スタブオブジェクトの作成
• Stubメソッドで作成する。
• Mockメソッドで作成した場合、モッキ
ングもスタビングもできるが、Stubメ
ソッドで作成した場合はスタビングのみ。
// スタブオブジェクトのインタフェース(クラス)を指定して作成
def subscriber = Stub(Subscriber)
!
// 変数の型からスタブオブジェクトのインタフェース(クラス)の
// 型を推論
Subscriber subscriber = Stub()
67. 68. 69. スパイでのスタビング
• スパイで普通にスタビングを行うと、本
物のメソッドが呼ばれなくなる。
// スパイ対象のクラスを指定して作成
def subscriber =
Spy(SubscriberImpl, constructorArgs: ["Fred"])
!
// スタビング。本物のreceiveメソッドは呼ばれない。
subscriber.receive(_) >> "ok"
70. スタビング+本物のメソッド
• callRealMethodメソッド、あるいは
callRealMethodWithArgsメソッドを使
うことで、任意のコードの実行と、本物
のメソッドへの委譲が行われる。
// 本物のreceiveメソッドが呼ばれた後、
// 戻り値を動的に変更
subscriber.receive(_) >> { String message ->
callRealMethod()
message.size() > 3 ? "ok" : "fail"
}
71. スタビング+本物のメソッド
• callRealMethodメソッドと
callRealMethodWithArgsメソッドの違
いは、後者は呼び出し時の引数を差し替
えたい場合に使用する。
// 本物のreceiveメソッドを、違う引数で実行し、
// 戻り値を動的に変更
subscriber.receive(_) >> { String message ->
callRealMethodWithArgs("Changed message")
message.size() > 3 ? "ok" : "fail"
}
72. 73. 74. 75. 76. 77. 78. 79. 純正なもの
• spock-unitils
• Unitilsというテスト用ユーティリ
ティをSpockと統合したもの。
• spock-spring, spock-boot
• それぞれ、Spring TestContext
やSpring Bootと統合したもの。
80. 純正でないもの
• Spock Report Extension
• 実行結果のレポートを作成するた
めのグローバル拡張機能。
• https://github.com/
renatoathaydes/spock-reports
81. 82. 83. Geb + Spock
• Gebとは、Webブラウザを使うWeb
アプリケーションの操作を自動化・
自動実行するためのソフトウェア。
• Geb用のSpecificationクラスを提供。
84. Arquillian + Spock
• Arquillianとは、自動テストでJavaEE
コンテナを利用可能にするためのソ
フトウェア。
• ArquillianをSpockと組み合わせて使
えるように、アノテーションなど機
能拡張を提供。
85. 86. 87. 88. 参考URL
• 本家
• https://code.google.com/p/spock/
• ソースコード
• https://github.com/spockframework/spock
• リファレンスドキュメント(英語版)
• http://spock-framework.readthedocs.org/en/latest/
• リファレンスドキュメント(日本語版)
• http://spock-framework-reference-documentation-ja.readthedocs.org/ja/latest/
• G*ワークショップZ May 2013 - Spockハンズオンの資料
• https://github.com/spockframework/spock
89. 参考URL
• Geb
• http://www.gebish.org/
• Arquillian
• http://arquillian.org/
• Arquillian TestRunner Spock
• http://arquillian.org/modules/spock-test-runner/
• RoboSpock
• http://robospock.org/
90.