Slide 1

Slide 1 text

#jjug_ccc_ab #jjug_ccc
 仕様がそのままテストになる! Javaで始める振る舞い駆動開発 
 JJUG CCC 2025 Fall
 うーたん


Slide 2

Slide 2 text

#jjug_ccc_ab #jjug_ccc
 自己紹介
 ● うーたん
 ○ 𝕏:@uutan1108
 ● 株式会社ゆめみ 
 ● バックエンドエンジニア 
 ● JJUG CCC は初登壇
 ● 明日は技術同人誌を頒布 
 2


Slide 3

Slide 3 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発とは 
 3


Slide 4

Slide 4 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発とは 
 テスト駆動開発 で記述されるテストケースは、作成したプロ グラムの動作が正しいかどうかを検証するために行う「テス ト」である。
 テストであるという点は同一であるが、加えて、これから作成 しようとするプログラムに期待される 「振る舞い」 や「制約条 件」、つまり「要求仕様」 に近い形で、 自然言語を併記しな がらテストコードを記述する。 
 引用元:https://ja.wikipedia.org/wiki/ビヘイビア駆動開発
 4


Slide 5

Slide 5 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発とは 
 テスト駆動開発 で記述されるテストケースは、作成したプロ グラムの動作が正しいかどうかを検証するために行う「テス ト」である。
 テストであるという点は同一であるが、加えて、これから作成 しようとするプログラムに期待される 「振る舞い」 や「制約条 件」、つまり「要求仕様」 に近い形で、 自然言語を併記しな がらテストコードを記述する。 
 引用元:https://ja.wikipedia.org/wiki/ビヘイビア駆動開発
 5


Slide 6

Slide 6 text

#jjug_ccc_ab #jjug_ccc
 テストとは 
 6


Slide 7

Slide 7 text

#jjug_ccc_ab #jjug_ccc
 テストとは 
 ソフトウェアテストとは、開発したソフトウェアが想定どおりに 動作するかを評価・検証 することです。開発したソフトウェア が、仕様書で求められている仕様どおりに機能するかどうかを チェックします。
 引用:ソフトウェアテストとは?種類や目的、重要な 7原則を紹介 | ソフ トウェアテストのSHIFT
 https://service.shiftinc.jp/column/3621/
 7


Slide 8

Slide 8 text

#jjug_ccc_ab #jjug_ccc
 銀行口座にお金を預けて、残高が正しく増えているか 
 テストの例 (単体テスト) 
 8


Slide 9

Slide 9 text

#jjug_ccc_ab #jjug_ccc
 JavaなのでJUnitを使ってみる 
 9


Slide 10

Slide 10 text

#jjug_ccc_ab #jjug_ccc
 JUnitとは
 10


Slide 11

Slide 11 text

#jjug_ccc_ab #jjug_ccc
 JUnitとは
 JUnitとはJavaで開発されたプログラムにおいてユニットテ スト(単体テスト)の自動化 を行うためのフレームワークであ る。
 引用:JUnit - Wikipedia
 https://ja.wikipedia.org/wiki/JUnit
 11


Slide 12

Slide 12 text

#jjug_ccc_ab #jjug_ccc
 テストを書いてみる 
 12


Slide 13

Slide 13 text

#jjug_ccc_ab #jjug_ccc
 package com.example.bdd; public class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance = initialBalance; } public void deposit(double amount) { balance += amount; } public double getBalance() { return balance; } } 実装
 13


Slide 14

Slide 14 text

#jjug_ccc_ab #jjug_ccc
 package com.example.bdd; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class BankAccountTest { @Test public void 預金すると残高が増える() { BankAccount account = new BankAccount(1000); account.deposit(500); assertEquals(1500, account.getBalance()); } } テストコード 
 14


Slide 15

Slide 15 text

#jjug_ccc_ab #jjug_ccc
 テストが成功することを確認することで、 
 想定どおりに動作するか確認できる 
 15


Slide 16

Slide 16 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発とは 
 テスト駆動開発 で記述されるテストケースは、作成したプロ グラムの動作が正しいかどうかを検証するために行う「テス ト」である。
 テストであるという点は同一であるが、加えて、これから作成 しようとするプログラムに期待される 「振る舞い」 や「制約条 件」、つまり「要求仕様」 に近い形で、 自然言語を併記しな がらテストコードを記述する。 
 引用元:https://ja.wikipedia.org/wiki/ビヘイビア駆動開発
 再 掲
 16


Slide 17

Slide 17 text

#jjug_ccc_ab #jjug_ccc
 テスト駆動開発とは 
 17


Slide 18

Slide 18 text

#jjug_ccc_ab #jjug_ccc
 テスト駆動開発 
 テスト駆動開発 とは、プログラム開発手法の一種で、プログラム に必要な各機能について、最初にテストを書き(これをテスト ファーストと言う)、そのテストが動作する必要最低限な実装を とりあえず行なった後、コードを洗練させる 、という短い工程を繰 り返すスタイルである。
 多くのアジャイルソフトウェア開発手法、例えば
 エクストリーム・プログラミングにおいて強く推奨されている。近年 はビヘイビア駆動開発 (振る舞い駆動開発 )へと発展を遂げてい る。
 参考:テスト駆動開発 - Wikipedia
 https://ja.wikipedia.org/wiki/テスト駆動開発
 
 18


Slide 19

Slide 19 text

#jjug_ccc_ab #jjug_ccc
 テスト駆動開発のサイクル 
 ● 最初にテストを書き
 ● そのテストが動作する必要最低限な実装をとりあえず行 なった後
 ● コードを洗練させる
 という短い工程を繰り返す
 画像引用元:https://service.shiftinc.jp/column/4654/
 
 19


Slide 20

Slide 20 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発 も
 
 
 
 
 
 のサイクルで開発する 
 画像引用元:https://service.shiftinc.jp/column/4654/
 
 20


Slide 21

Slide 21 text

#jjug_ccc_ab #jjug_ccc
 振る舞いとは 
 21


Slide 22

Slide 22 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発とは 
 テスト駆動開発 で記述されるテストケースは、作成したプロ グラムの動作が正しいかどうかを検証するために行う「テス ト」である。
 テストであるという点は同一であるが、加えて、これから作成 しようとするプログラムに期待される 「振る舞い」 や「制約条 件」、つまり「要求仕様」 に近い形で、 自然言語を併記しな がらテストコードを記述する。 
 引用元:https://ja.wikipedia.org/wiki/ビヘイビア駆動開発
 再 掲
 22


Slide 23

Slide 23 text

#jjug_ccc_ab #jjug_ccc
 要求仕様とは 
 23


Slide 24

Slide 24 text

#jjug_ccc_ab #jjug_ccc
 要求仕様書 
 要求仕様書は、システム開発やソフトウェアプロジェクトにお いて、顧客やユーザーのニーズや期待を具体的に文書化 するための重要なドキュメントです。
 その目的は、開発会社と発注顧客間での認識合わせを図 り、プロジェクトの進行中に生じうる誤解やミスコミュニケー ションを防ぐ ことです。
 引用元:要求仕様書とは? RFP・要件定義書との違いを解説 | 情シスBlog
 https://biz.techvan.co.jp/tech-is/blog/infra/001258.html
 24


Slide 25

Slide 25 text

#jjug_ccc_ab #jjug_ccc
 要件定義と要求定義 
 25


Slide 26

Slide 26 text

#jjug_ccc_ab #jjug_ccc
 プロジェクトには多くの人が関わる 
 26


Slide 27

Slide 27 text

#jjug_ccc_ab #jjug_ccc
 ● 発注顧客 / ビジネスオーナー
 ● プロダクトオーナー / ビジネスアナリスト
 ● 開発者 / プログラマー
 ● テスター / QAエンジニア
 ● スクラムマスター / プロジェクトマネージャー
 ● など...
 プロジェクトの進行中に生じうる誤解や 
 ミスコミュニケーションを防ぐ必要がある 
 プロジェクトには多くの人が関わる 
 27


Slide 28

Slide 28 text

#jjug_ccc_ab #jjug_ccc
 振る舞い駆動開発では、 
 要求仕様を自然言語でテストコード 
 として表現し、 開発関係者全員がビジネス 
 要件について議論 することが求められる 
 28


Slide 29

Slide 29 text

#jjug_ccc_ab #jjug_ccc
 要求仕様を自然言語でテストコード 
 として表現してみる 
 29


Slide 30

Slide 30 text

#jjug_ccc_ab #jjug_ccc
 package com.example.bdd; public class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance = initialBalance; } public void deposit(double amount) { balance += amount; } public double getBalance() { return balance; } } Javaの実装
 テストする対象 
 30


Slide 31

Slide 31 text

#jjug_ccc_ab #jjug_ccc
 銀行口座にお金を預けて、残高が正しく増えているか 
 テストの例 
 31


Slide 32

Slide 32 text

#jjug_ccc_ab #jjug_ccc
 CucumberでGherkin記法を使って 
   (自然言語ベースの記法 )
 書いてみる 
 32


Slide 33

Slide 33 text

#jjug_ccc_ab #jjug_ccc
 Cucumberとは
 Cucumberは、平易な言葉 で書かれた受け入れテストを実行 するためのツールです。 
 平易な言葉で書かれているため、チームの誰でも読めるよう になり、コミュニケーション、協力、信頼が向上します。
 原文:
 Cucumber is a tool for running automated acceptance tests, written in plain language. Because they're written in plain language, they can be read by anyone on your team, improving communication, collaboration and trust.
 原文の引用:Cucumber
 https://cucumber.io/
 33


Slide 34

Slide 34 text

#jjug_ccc_ab #jjug_ccc
 使っているもの 
 34


Slide 35

Slide 35 text

#jjug_ccc_ab #jjug_ccc
 使っているもの 
 ● JUnit
 ● Cucumber
 35


Slide 36

Slide 36 text

#jjug_ccc_ab #jjug_ccc
 自然言語のテストコード 
 36


Slide 37

Slide 37 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 37


Slide 38

Slide 38 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 Feature(機能):テストする機能全体を定義 
 38


Slide 39

Slide 39 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 As a / I can / so that(ユーザーストーリー) 
 As a: 誰がこの機能を使うか(ユーザーの役割) 
 I can: 何ができるか(実行可能なアクション) 
 so that: なぜその機能が必要か(ビジネス価値・目的) 
 39


Slide 40

Slide 40 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 Scenario(シナリオ):具体的なテストケースを定義 
 40


Slide 41

Slide 41 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 Given (前提条件):操作を実行する前の状態 
 41


Slide 42

Slide 42 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 When(実行アクション):テスト対象となる具体的なアクショ ン
 42


Slide 43

Slide 43 text

#jjug_ccc_ab #jjug_ccc
 Feature: 預金 As a 銀行の顧客 I can 口座にお金を預金する so that 残高を増やして保管できる Scenario: 預金すると残高が増える Given 初期残高が 1000.0 円の口座がある When 500.0 円を預金する Then 残高が 1500.0 円になっている 自然言語の 
 テストコード 
 Then(期待結果):期待される結果を検証 
 43


Slide 44

Slide 44 text

#jjug_ccc_ab #jjug_ccc
 Javaのテストコード 
 44


Slide 45

Slide 45 text

#jjug_ccc_ab #jjug_ccc
 public class BankAccountSteps { private BankAccount account; @Given("初期残高が {double} 円の口座がある") public void 初期残高がの口座がある(double initialBalance) { account = new BankAccount(initialBalance); } @When("{double} 円を預金する") public void 円を預金する(double amount) { account.deposit(amount); } @Then("残高が {double} 円になっている") public void 残高がになっている(double expectedBalance) { assertEquals(expectedBalance, account.getBalance()); } } package com.example.bdd; import io.cucumber.java.Before; import io.cucumber.java.en.Given; import io.cucumber.java.en.When; import io.cucumber.java.en.Then; import static org.junit.jupiter.api.Assertions.assertEqu als; 自然言語のテスト コードから呼ばれる 
 Javaのテストコード 
 
 45


Slide 46

Slide 46 text

#jjug_ccc_ab #jjug_ccc
 public class BankAccountSteps { private BankAccount account; @Given("初期残高が {double} 円の口座がある") public void 初期残高がの口座がある(double initialBalance) { account = new BankAccount(initialBalance); } @When("{double} 円を預金する") public void 円を預金する(double amount) { account.deposit(amount); } @Then("残高が {double} 円になっている") public void 残高がになっている(double expectedBalance) { assertEquals(expectedBalance, account.getBalance()); } } package com.example.bdd; import io.cucumber.java.Before; import io.cucumber.java.en.Given; import io.cucumber.java.en.When; import io.cucumber.java.en.Then; import static org.junit.jupiter.api.Assertions.assertEqu als; 自然言語のテスト コードから呼ばれる 
 Javaのテストコード 
 
 46


Slide 47

Slide 47 text

#jjug_ccc_ab #jjug_ccc
 GitHubでサンプルを公開しています 
 
 OHMORIYUSUKE/java-bdd-sample
 https://github.com/OHMORIYUSUKE/java-bdd-sample
 
 47


Slide 48

Slide 48 text

#jjug_ccc_ab #jjug_ccc
 全体の流れ 
 48


Slide 49

Slide 49 text

#jjug_ccc_ab #jjug_ccc
 全体の流れ 
 1. JUnitが起動 
 2. Cucumberを起動 
 3. 自然言語のテストコードを読み込む 
 a. Given / When / Then のステップを探す 
 4. Javaのテストコードとマッチング 
 5. システムの実装コードを実行 
 6. 結果をJUnitに返す
 49


Slide 50

Slide 50 text

#jjug_ccc_ab #jjug_ccc
 自然言語でテストを書き 
 実行までできるようになった 🙌
 50


Slide 51

Slide 51 text

#jjug_ccc_ab #jjug_ccc
 「振る舞い」を意識して「 振る舞い駆動開発 」
 をするために意識したいこと 
 51


Slide 52

Slide 52 text

#jjug_ccc_ab #jjug_ccc
 マーティン・ファウラー (英: Martin Fowler)氏の
 記事「Business Facing Test」を参考にしています。 
 52


Slide 53

Slide 53 text

#jjug_ccc_ab #jjug_ccc
 マーティン・ファウラー 
 マーティン・ファウラー (英: Martin Fowler、1963年 - ) は、アメリ カ合衆国で活動しているソフトウェア技術者である。 ソフトウェア アーキテクチャについての、いくつかの本の著者、および講演者と して、広く知られている。 とりわけオブジェクト指向分析とオブジェ クト指向設計、統一モデリング言語 (UML) 、アナリシスパターンを はじめとしたソフトウェアパターン、エクストリーム・プログラミング (XP) を含むアジャイルソフトウェア開発方法論の、各分野におい て、活発に活動している。
 引用元:https://ja.wikipedia.org/wiki/マーティン・ファウラー
 53


Slide 54

Slide 54 text

#jjug_ccc_ab #jjug_ccc
 Business Facing Test
 54


Slide 55

Slide 55 text

#jjug_ccc_ab #jjug_ccc
 Business Facing Test
 ビジネス向けテストとは、顧客、ユーザー、ビジネスアナリストな ど、開発チーム内のプログラミングに携わらないメンバーとのコ ミュニケーションを支援 するためのテストです。自動化されている 場合、システム自体のコンポーネントアーキテクチャを無視し、ド メイン指向の用語でシステムを記述 します。ビジネス向けテスト は受け入れ基準として使用されることが多く、このようなテストに 合格することは、システムが顧客が期待する機能を提供してい ることを示します。
 参考: Martin Fowler. "BusinessFacingTest". Retrieved from https://martinfowler.com/bliki/BusinessFacingTest.html
 55


Slide 56

Slide 56 text

#jjug_ccc_ab #jjug_ccc
 Business Facing Test
 自動化されたビジネス向けテストは、多くの場合、何らかのド メイン特化言語 (Domain Specific Language)で表現され ます 。
 CucumberやTwistのようなツールは、このようなDSLを設計 するのを助け、さらにそれをテスト対象のシステムに結びつ ける仕組みを提供します。
 参考: Martin Fowler. "BusinessFacingTest". Retrieved from https://martinfowler.com/bliki/BusinessFacingTest.html
 56


Slide 57

Slide 57 text

#jjug_ccc_ab #jjug_ccc
 Business Facing Test
 ビジネス向けテストは、 ユーザー指向の表現からテスト対象 システムをブラックボックスとして扱うことが示唆されるため、 BroadStackTests(システム全体をまとめてテスト )として実 装されるのが一般的 です。
 しかし、ビジネス向けテストを ComponentTests(システムを 構成するコンポーネント単位でテスト )として実装することに は大きなメリット があり、メンテナンスが容易になり、実行速 度も速くなることがよくあります。
 参考: Martin Fowler. "BusinessFacingTest". Retrieved from https://martinfowler.com/bliki/BusinessFacingTest.html
 57


Slide 58

Slide 58 text

#jjug_ccc_ab #jjug_ccc
 Business Facing Test
 私は自動テストの大ファンですが、ビジネス関連のテストに おいては手動テストが重要な役割を果たすことを認識 する ことが重要です。
 探索的テストやユーザビリティテストといった手法は本質的 に手作業であり、バランスの取れたテストポートフォリオの不 可欠な要素です。
 参考: Martin Fowler. "BusinessFacingTest". Retrieved from https://martinfowler.com/bliki/BusinessFacingTest.html
 58


Slide 59

Slide 59 text

#jjug_ccc_ab #jjug_ccc
 まとめ
 ● 振る舞いをテストとは、顧客が期待する機能 を提供できて いるかテストすること。
 ● 単体テストでも振る舞いを意識して自然言語で表現 するこ とができる。UIを直接テストすることも大切 。
 ● 顧客、ユーザー、ビジネスアナリストなど、開発チーム内の プログラミングに携わらないメンバーとの 
 コミュニケーション をする。
 参考: Martin Fowler. "BusinessFacingTest". Retrieved from https://martinfowler.com/bliki/BusinessFacingTest.html
 59


Slide 60

Slide 60 text

#jjug_ccc_ab #jjug_ccc
 「振る舞い」を意識して「振る舞い駆動開発」 
 をするために意識したいこと 
 
 まとめ
 60


Slide 61

Slide 61 text

#jjug_ccc_ab #jjug_ccc
 終わりに
 61


Slide 62

Slide 62 text

#jjug_ccc_ab #jjug_ccc
 BDD フレームワークを使うのが BDD ではない。 
 「振る舞い」を考え、開発チームで共有し、 
 テストに落とし込むこと。 
 62


Slide 63

Slide 63 text

#jjug_ccc_ab #jjug_ccc
 BDD フレームワークを使うのが BDD ではない。 
 「振る舞い」を考え、開発チームで共有し、 
 テストに落とし込むこと。 
 ご清聴ありがとうございました 
 63


Slide 64

Slide 64 text

#jjug_ccc_ab #jjug_ccc
 64
 全体アンケート 
 セッションアンケート