テスト
2024年3⽉14⽇
浅海智晴
クラウドアプリケーションのための
オブジェクト指向分析設計講座
第33回
作業分野
SimpleModeling2021
• オブジェクト指向分析設計での共通範囲
• UML/UP
• 本講座で使⽤するUMLプロファイル
• プロファイル:SimpleModeling2021 (SM2021)
• オブジェクト指向分析設計の基本からの拡張部を明確化
• アジャイル開発
• Communication
• Embrace Change
• Travel Light
• Scaling
• Component-Based Development
• クラウド・アプリケーション
• モデル駆動開発
SM2021
Travel Light
Embrace Change
Cloud
Model-Driven
Scaling
CBD
Testability
Serviceability
• ⾮機能要件
• Testability
• Serviceability
第1部 基本編の構成(1)
• 概論 [第1回]
• 開発プロセス [第2回]
• 基本モデル [第3回]
• 静的モデル(1) [第4回]
• 静的モデル(2) [第5回]
• 動的モデル [第6回]
• 協調モデル [第7回]
• 関数モデル [第8回]
• 物理モデル [第9回]
• 作業分野 [第10回]
• ビジネス・モデリング [第11回]
• 要求 [第12回]
• 要求/ユースケース [第13回]
• 要求/シナリオ [第14回]
• 分析 [第15回]
• 分析/コンポーネント分析 [第16回]
• 分析/イベント駆動 [第17回]
• 作業分野
• 設計 [第18回]
• 設計/アーキテクチャ設計 [第19回]
• 設計/コンポーネント設計(1) [第20回]
• 設計/コンポーネント設計(2) [第21回]
• 設計/コンポーネント設計(3) [第22回]
• 設計/ドメイン設計(1) [第23回]
• 設計/ドメイン設計(2) [第24回]
• 設計/ドメイン設計(3) [第25回]
• 設計/ドメイン設計(4) [第26回]
• 設計/ドメイン設計(5) [第27回]
• 設計/原理 [第28回]
• 設計/ UX/UI設計 [第29回]
• 実装(1) [第30回]
• 実装(2) [第31回]
• 実装(3) [第32回]
• テスト [第33回]
第1部 基本編の構成(2)
• アプリケーション・アーキテクチャ [第32回]
• ドメイン・モデル [第33回]
• アプリケーション・モデル [第34回]
• プレゼンテーション・モデル [第35回]
• ケーススタディ[第36回]
• 要求モデル [第37回]
• 分析モデル [第38回]
• 設計モデル [第39回]
• 実装 [第40回]
• テスト [第41回]
本講座のアプローチ
• オブジェクト指向分析設計の基本を確認
• UML + UP(Unified Process)
• CBD (Component-Based Development)
• 最新技術でアップデート
• クラウド・コンピューティング
• イベント駆動、分散・並列
• ビッグデータ、AI、IoT
• コンテナ
• 関数型
• OFP(Object-Functional Programming), Reactive Streams
• ルール, AI
• DevOps
• アジャイル開発
• DX (Digital Transformation)
第25回 アプリケーション・アーキテクチャ
第2回 開発プロセス
第9回 物理モデル
第11回 ビジネス・モデリング
第2部 クラウド・アプリケーション編
第21回 設計/ドメイン設計
第20回 設計/コンポーネント設計
第2部 クラウド・アプリケーション編
原理 (Principle)
• Agile Software Development [ASD]
• SRP (The Single Responsibility Principle)
• OCP (The Open-Close Principle)
• LSP (The Liskov Substitution Principle)
• …
• GRASP (General Responsibility Assignment Software Patterns or principles)
• Low Coupling
• High Cohesion
• …
• Writing Effective Use Cases [WEUC]
• Scope
• …
パターン (Pattern)
• Design Patterns [DP]
• Observer, Strategy, …
• Domain Driven Design [DDD]
• Ubiquitous Language, Intention-
Revealing Interfaces, …
• Analysis Patterns [AP]
• Party, Quantity, …
• Pattern-Oriented Software
Architecture [POSA]
• Layers, Pipes and Filters, …
• Patterns of Enterprise
Application Architecture [PEAA]
• Unit of Work, Data Transfer Object,
…
• Enterprise Integration Patterns
[EIP]
• Message Bus, Aggregator, …
• Patterns for Effective Use
Cases [PEUC]
• CompleteSingleGoal,
VerbPhraseName, …
• AntiPatterns [AnP]
• Stovepipe System, Analysis
Paralysis, …
内容
• テストの位置づけ
• テストの枠組み
• TDD
• BDD
• テスタブル設計
テストの位置づけ
第10回 作業分野
作業分野とモデルの関係 第10回 作業分野
ユースケース駆動開発
テストの位置つけ
• QA (Quality Assurance)
• ソフトウェア・システムの品質を確保
• テスト計画・テスト実⾏
• 伝統的な枠組み
• 動く仕様書
• 「テスト」の位置つけを変える技術⾰新
• TDD/BDD
• CI/CDパイプライン
• オブジェクト指向技術
• CBD
• シナリオ分析
• Scala DSL(Domain Specific Language)でさらに使いやすくなった
Travel Light
Embrace Change
テストの枠組み
テストの枠組み
• ソフトウェア開発でのテストの分類
• 開発者テスト
• QAテスト
• ユーザー・テスト
• テストの基本的な考え⽅・技法など
開発組織とロール(例)
開発者テスト
• 開発者によるテスト
• ホワイトボックス・テスト
• ユニット・テストが中⼼
• ユニット・テストを⽤いた結合テストまで
QAテスト
• QAチームによるテスト
• 機能テスト
• ブラックボックス・テストが中⼼
• システム・テスト
• 負荷・連続運転テスト
• 環境テスト
• 評価テスト
ユーザー・テスト
• リリース可能かの最終確認
• ブラックボックス・テスト
• ビジネス側の観点で確認を⾏う
• 受託開発の場合は納品条件
• テスト
• 受⼊れテスト
• 運⽤テスト
• アルファ・テスト
• ベータ・テスト
IEEE 829
• テスト⽂書の国際規格
• 1998
• テスト計画
• テスト設計
• テスト・ケース
• テスト⼿順
• 2008
• アジャイル開発への対応
IEEE 29119
• IEEE 829を統合
• ソフトウェアとシステムのテストに関するIEEEの標準規格
• テストプロセスの⼀貫性、再現性、品質の向上
• 内容
• テスト・プロセスの概念と定義
• テスト・プロセスのモデル
• テスト・ドキュメントの標準
• テスト技法
• キーワード駆動テストの標準
ISO/IEC 25010 (製品品質モデル)
• 機能適合性
• 性能効率性
• 互換性
• 使⽤性
• 信頼性
• セキュリティ
• 保守性
• 移植性
静的テスト
• レビュー
• 静的検査
• コンパイル
• 関数型⾔語の場合は直観主義命題論理のスコープでのプログラムの動作証明
• リント (lint)
• プログラムのバグや冗⻑を調べる
• リンター (linter) : リントを⾏うプログラム
テストの技法
• 同値分割テスト
• 同値パーティション(同じ動作をする条件の集まり)ごとにテストを⾏う
• 境界値テスト
• 仕様条件の境界値とその隣接値に対しテストを⾏う
• デシジョン・テーブル・テスト
• 複数のテスト項⽬を表にしたデシジョン・テーブルを⽤いてテストを⾏う
• 状態遷移テスト
• 状態遷移図/状態遷移表を⽤いてテストを⾏う
• 組合せテスト
• 複数の条件を組合せてテストを⾏う
関数型のテスト技法
• プロパティ・ベース・テスト
• プロパティを起点としたテスト
• プロパティ群の値域の組合せに対して網羅的にテストを⾏う
• 型クラスのルール・テスト
• 型クラス実現時にインタフェースに適合するかコンパイル・チェック
• コンパイル・チェックに加えてルール・テストが⾃動化できる
Monoidの例 : Counter
再掲 第8回 関数モデル
case class Counter(c: Int) extends AnyVal:
def +(rhs: Counter): Counter = Counter(c + rhs.c)
object Counter:
val empty = Counter(0)
implicit object CounterEq extends Eq[Counter]:
def eqv(x: Counter, y: Counter) = x == y
implicit object CounterMonoid extends Monoid[Counter]:
def empty: Counter = Counter.empty
def combine(x: Counter, y: Counter): Counter = x + y
Counterの定義
CounterのMonoid型クラスの定義 emptyメソッド(単位元) を定義
Semigroup由来のcombineメソッド(結合法則を満たした⼆項演算)を定義
再掲 第8回 関数モデル
class CounterPropertySpec extends AnyWordSpec with should.Matchers with
ScalaCheckDrivenPropertyChecks:
"Counter" should {
val nonNegativeInts = Gen.listOf(Gen.choose(0, 10000))
"Property-Based TestingでCounterのfoldMap動作をテストする" in
forAll(nonNegativeInts) { (xs: List[Int]) =>
val c: Counter = xs.foldMap(Counter.apply)
c.c should be(xs.sum)
}
}
Property-basedテスティングによるテスト
テストデータの特性を定義
Property−basedテスティングの実⾏
BDD (Behavior-Driven Development)スタイルのテスト
Travel Light
第16回 テスト
再掲 第8回 関数モデル
class CounterLawSpec extends AnyFunSuite with FunSuiteDiscipline with Configuration:
lazy val counterGen: Gen[Counter] = Gen.choose(0, 10000).map(Counter.apply)
implicit lazy val counterArbitrary: Arbitrary[Counter] = Arbitrary(counterGen)
checkAll("Counter", MonoidTests[Counter].monoid)
Monoid法則のテスト
Monoid法則のテストを⼀括して⾏う
型クラスの規則のテスト⽤トレイト
再掲 第8回 関数モデル
sbt:Scala 3 Cats> test
[info] compiling 1 Scala source to /Users/asami/src/workspace2021/scala3cats/target/scala-3.1.0/classes ...
[info] done compiling
[info] CounterLawSpec:
[info] - Counter.monoid.associative
[info] - Counter.monoid.collect0
[info] - Counter.monoid.combine all
[info] - Counter.monoid.combineAllOption
[info] - Counter.monoid.intercalateCombineAllOption
[info] - Counter.monoid.intercalateIntercalates
[info] - Counter.monoid.intercalateRepeat1
[info] - Counter.monoid.intercalateRepeat2
[info] - Counter.monoid.is id
[info] - Counter.monoid.left identity
[info] - Counter.monoid.repeat0
[info] - Counter.monoid.repeat1
[info] - Counter.monoid.repeat2
[info] - Counter.monoid.reverseCombineAllOption
[info] - Counter.monoid.reverseRepeat1
[info] - Counter.monoid.reverseRepeat2
[info] - Counter.monoid.reverseReverses
[info] - Counter.monoid.right identity
[info] CounterPropertySpec:
[info] Counter
[info] - should Property-Based TestingでCounterのfoldMap動作をテストする
[info] ScalaTest
[info] Run completed in 443 milliseconds.
[info] Total number of tests run: 19
[info] Suites: completed 2, aborted 0
[info] Tests: succeeded 19, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 20, Failed 0, Errors 0, Passed 20
[success] Total time: 1 s, completed 2021/11/07 5:54:50
CounterLawSpecによるMonoid法則テスト
CounterPropertySpecによるBDDテスト
再掲 第8回 関数モデル
Verification & Validation
• Verification
• 検証
• 仕様通りにシステムが動作するか確認
• Validation
• 妥当性確認
• ユーザーの要求通りにシステムが動作するか確認
仕様とテストの関係
TDD
TDD (Test-Driven Development)
• テストをプログラミングの前に書く開発⼿法
• CI/CDパイプラインに⾃動テストとして組み込むことで常に⾃
動テストによって品質が保持される
• テストを動く仕様書とする
• Specification as a Code
• プログラミングの前にテストケースを整備することで、テスト
ケースの作成⼯数を確保できる
再掲 第30回 設計/実装(1)
TDDの⼿順
1. テストを作成
1. テストから呼ばれるインタフェースを作成
2. インタフェースのスタブを作成してコンパイル
3. テストを実⾏してエラーになることを確認
2. プログラムを実装
3. テストが成功することを確認
テストから動く仕様書へ
• テストを先に書く
• 仕様を決めるということ
• テストが仕様書の役割を果たす
• テスト・ケースを仕様書として活⽤するための可読性を向上さ
せたい
• 専⽤のテスティング・フレームワーク
• 本講座ではScalaTestを使⽤
• BDDでさらに重要な展開へ
仕様書とプログラム
仕様とテストとTDDの関係
⾃動テスト
• 考慮点
• テスト時間
• テスト環境構築の難易度
• タイミング
• 常時(夜間)
• 開発時
• CI時
• CD時
• テストの⽅式
• スタブを使ってコンポーネントの単体テスト
• Dockerを使って結合テスト
BDD
BDD (Behavior-Driven Development)
• 振る舞いモデルを起点に開発を進める開発⼿法
• 要求仕様となる振る舞いモデルには「シナリオの実⾏例」を使⽤す
る
• 「シナリオの具体例」からテストケースを作成
• 要求仕様とテストケースが直結
• 受け⼊れテスト(Acceptance test)と呼んでいる。ユーザーテストの受け⼊れ
テストとの混同に注意。
• 開発者、QA担当、顧客代表が「シナリオの具体例」で記述された要
求仕様を共有
• Validation : 要求仕様と実装のずれを防ぐ
• テスト・レポートは最新の要求仕様のドキュメント
• ⽣きた⽂書 (living document)
BDDの応⽤
• BDDの技法をユニット・テスト(TDD)に適⽤する
• コンポーネントの使⽤⽅法をシナリオで記述
• シナリオからユニット・テストを作成
• CI/CDパイプラインに⾃動テストとして組み込むことで常に⾃
動テストによって要求仕様品質が保持される
仕様とテストとBDDの関係
ユースケースとBDD
Find out what time the next trains for my destination station leave
Narrative:
In order to plan my trips more effectively
As a commuter
I want to know the next trains going to my destinations
Scenario: Find the optimal itinerary between stations on the name line
Given Western line trains from Emu Plains leave Parramatta for Town Hall at 7:58, 8:00, 8:02,
8:11, 8:14, 0:21
When I want to travel from Parramatta to Town Hall at 8:00
Then I should be told about the trans at: 8:02, 8:11, 8:14
BDDシナリオ
出典:BDD in Action
class ReservationServiceSpec extends AnyFreeSpec
with Matchers
with GivenWhenThen
with ReservationMatchers {
"ReservationService" - {
"reserveメソッド" - {
"予約の追加" - {
"現在時刻より後ろの有効な予約時間を予約" in {
Given("テスト⽤に作成したReservationServiceを使⽤")
val service = ReservationService.createForTest()
When("運⽤時間内の時間")
val dt = "2024-01-15T10:00:00+JST"
Then("テスト対象時刻で実⾏コンテキストを⽤意")
given ExecutionContext = ExecutionContext.createWithCurrentDateTime(dt)
And("現在時刻より後ろの有効な予約時間で予約")
ReservationServiceSpec.sbt (1/2) 再掲 第31回 設計/実装(2)
val rid = ResourceId("id1234")
val uid = UserId("user789")
val start = LocalDateTime.of(2024, 1, 15, 11, 00)
val end = LocalDateTime.of(2024, 1, 15, 12, 00)
val interval = Interval.openUpper(start, end)
val cmd = ReserveCommand(rid, uid, interval)
service.reserve(cmd) should successReserve(cmd)
}
}
}
}
}
ReservationServiceSpec.sbt (2/2) 再掲 第31回 設計/実装(2)
sbt:reservation> test
[info] compiling 2 Scala sources to
/Users/asami/src/Project2023/ofad/domain/target/scala-3.1.1/test-classes ...
[info] done compiling
[info] ReservationServiceSpec:
[info] ReservationService
[info] reserveメソッド
[info] 予約の追加
[info] - 現在時刻より後ろの有効な予約時間を予約
[info] + Given テスト⽤に作成したReservationServiceを使⽤
[info] + When 運⽤時間内の時間
[info] + Then テスト対象時刻で実⾏コンテキストを⽤意
[info] + And 現在時刻より後ろの有効な予約時間で予約
[info] Run completed in 270 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 1 s, completed 2024/01/16 16:00:27
テストを実⾏ 再掲 第31回 設計/実装(2)
BDDによる要求仕様 Travel Light
Embrace Change
テスタブル設計
テスタブル設計
• ソフトウェア・システムの性質
• テスト可能 (testable)
• 配備可能 (deployable)
• リリース可能 (releasable)
• テスト可能なシステムにするための設計技法
テスト容易性 (Testability)
• コンポーネントのテストのしやすさ
• 他のコンポーネントとの依存性をできるだけ排除する
• インタフェース(提供、要求)を通してアクセス
• コンポーネントの作成はDI(Dependency Injection)を可能にす
る
• クライアントの実⾏⽂脈は実⾏コンテキスト経由で取得するよ
うにする
• 認証情報、時間
• コンポーネントの内部情報がテスト・プログラムから取得でき
るようにする
再掲 第21回 設計/コンポーネント設計 (2)
再掲 第32回 設計/実装(3)
三層アーキテクチャ
受け⼊れテスト
ユニット・テスト
まとめ
• テストの位置つけ
• QA (Quality Assurance)
• 動く仕様書
• TDD (Test-Driven Development)
• 動く仕様書でテスト
• CI/CDパイプライン上で⾃動テスト
• BDD (Behavior-Driven Development)
• 要求仕様を動く仕様書にする
• テスタブル設計
• TDD/BDDを可能にする設計⽅式
参考⽂献
• The Unified Modeling Language Reference Manual,
2nd (Rumbaugh他, 2004)
• The Unified Modeling Language User Guide, 2nd
(Booch他, 2004)
• The Unified Software Development Process
(Jacobson他, 1999)
• The Object Constraint Language, 2nd (Warmer他,
2003)
• UML 2 and the Unified Process: Practical Object-
Oriented Analysis and Design (Arlow他, 2005)
• OMG Unified Modeling Language Version 2.5
(OMG, 2015)
• 上流⼯程UMLモデリング (浅海, 2008)
• ソフトウェア・テストの技法 第2版 (マイ
ヤーズ他, 2006)
• 【この1冊でよくわかる】ソフトウェアテスト
の教科書 [増補改訂 第2版](布施 他, 2021)
• 知識ゼロから学ぶソフトウェアテスト 第3版
アジャイル・AI時代の必携教科書 (⾼橋, 2023)
• ソフトウェア品質を⾼める開発者テスト 改訂
版 アジャイル時代の実践的・効率的でスムー
ズなテストのやり⽅ (⾼橋, 2022)
• Extreme Programming Explained: Embrace Change
2nd (Beck, 2004)
• Specification by Example: How Successful Teams
Deliver the Right Software (Adzic, 2011)
• BDD in Action: Behavior-Driven Development for
the whole software lifecycle (Smart, 2014)

テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第33回】

  • 1.
  • 2.
    SimpleModeling2021 • オブジェクト指向分析設計での共通範囲 • UML/UP •本講座で使⽤するUMLプロファイル • プロファイル:SimpleModeling2021 (SM2021) • オブジェクト指向分析設計の基本からの拡張部を明確化 • アジャイル開発 • Communication • Embrace Change • Travel Light • Scaling • Component-Based Development • クラウド・アプリケーション • モデル駆動開発 SM2021 Travel Light Embrace Change Cloud Model-Driven Scaling CBD Testability Serviceability • ⾮機能要件 • Testability • Serviceability
  • 3.
    第1部 基本編の構成(1) • 概論[第1回] • 開発プロセス [第2回] • 基本モデル [第3回] • 静的モデル(1) [第4回] • 静的モデル(2) [第5回] • 動的モデル [第6回] • 協調モデル [第7回] • 関数モデル [第8回] • 物理モデル [第9回] • 作業分野 [第10回] • ビジネス・モデリング [第11回] • 要求 [第12回] • 要求/ユースケース [第13回] • 要求/シナリオ [第14回] • 分析 [第15回] • 分析/コンポーネント分析 [第16回] • 分析/イベント駆動 [第17回] • 作業分野 • 設計 [第18回] • 設計/アーキテクチャ設計 [第19回] • 設計/コンポーネント設計(1) [第20回] • 設計/コンポーネント設計(2) [第21回] • 設計/コンポーネント設計(3) [第22回] • 設計/ドメイン設計(1) [第23回] • 設計/ドメイン設計(2) [第24回] • 設計/ドメイン設計(3) [第25回] • 設計/ドメイン設計(4) [第26回] • 設計/ドメイン設計(5) [第27回] • 設計/原理 [第28回] • 設計/ UX/UI設計 [第29回] • 実装(1) [第30回] • 実装(2) [第31回] • 実装(3) [第32回] • テスト [第33回]
  • 4.
    第1部 基本編の構成(2) • アプリケーション・アーキテクチャ[第32回] • ドメイン・モデル [第33回] • アプリケーション・モデル [第34回] • プレゼンテーション・モデル [第35回] • ケーススタディ[第36回] • 要求モデル [第37回] • 分析モデル [第38回] • 設計モデル [第39回] • 実装 [第40回] • テスト [第41回]
  • 5.
    本講座のアプローチ • オブジェクト指向分析設計の基本を確認 • UML+ UP(Unified Process) • CBD (Component-Based Development) • 最新技術でアップデート • クラウド・コンピューティング • イベント駆動、分散・並列 • ビッグデータ、AI、IoT • コンテナ • 関数型 • OFP(Object-Functional Programming), Reactive Streams • ルール, AI • DevOps • アジャイル開発 • DX (Digital Transformation) 第25回 アプリケーション・アーキテクチャ 第2回 開発プロセス 第9回 物理モデル 第11回 ビジネス・モデリング 第2部 クラウド・アプリケーション編 第21回 設計/ドメイン設計 第20回 設計/コンポーネント設計 第2部 クラウド・アプリケーション編
  • 6.
    原理 (Principle) • AgileSoftware Development [ASD] • SRP (The Single Responsibility Principle) • OCP (The Open-Close Principle) • LSP (The Liskov Substitution Principle) • … • GRASP (General Responsibility Assignment Software Patterns or principles) • Low Coupling • High Cohesion • … • Writing Effective Use Cases [WEUC] • Scope • …
  • 7.
    パターン (Pattern) • DesignPatterns [DP] • Observer, Strategy, … • Domain Driven Design [DDD] • Ubiquitous Language, Intention- Revealing Interfaces, … • Analysis Patterns [AP] • Party, Quantity, … • Pattern-Oriented Software Architecture [POSA] • Layers, Pipes and Filters, … • Patterns of Enterprise Application Architecture [PEAA] • Unit of Work, Data Transfer Object, … • Enterprise Integration Patterns [EIP] • Message Bus, Aggregator, … • Patterns for Effective Use Cases [PEUC] • CompleteSingleGoal, VerbPhraseName, … • AntiPatterns [AnP] • Stovepipe System, Analysis Paralysis, …
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
    テストの位置つけ • QA (QualityAssurance) • ソフトウェア・システムの品質を確保 • テスト計画・テスト実⾏ • 伝統的な枠組み • 動く仕様書 • 「テスト」の位置つけを変える技術⾰新 • TDD/BDD • CI/CDパイプライン • オブジェクト指向技術 • CBD • シナリオ分析 • Scala DSL(Domain Specific Language)でさらに使いやすくなった Travel Light Embrace Change
  • 14.
  • 15.
    テストの枠組み • ソフトウェア開発でのテストの分類 • 開発者テスト •QAテスト • ユーザー・テスト • テストの基本的な考え⽅・技法など
  • 16.
  • 17.
    開発者テスト • 開発者によるテスト • ホワイトボックス・テスト •ユニット・テストが中⼼ • ユニット・テストを⽤いた結合テストまで
  • 18.
    QAテスト • QAチームによるテスト • 機能テスト •ブラックボックス・テストが中⼼ • システム・テスト • 負荷・連続運転テスト • 環境テスト • 評価テスト
  • 19.
    ユーザー・テスト • リリース可能かの最終確認 • ブラックボックス・テスト •ビジネス側の観点で確認を⾏う • 受託開発の場合は納品条件 • テスト • 受⼊れテスト • 運⽤テスト • アルファ・テスト • ベータ・テスト
  • 20.
    IEEE 829 • テスト⽂書の国際規格 •1998 • テスト計画 • テスト設計 • テスト・ケース • テスト⼿順 • 2008 • アジャイル開発への対応
  • 21.
    IEEE 29119 • IEEE829を統合 • ソフトウェアとシステムのテストに関するIEEEの標準規格 • テストプロセスの⼀貫性、再現性、品質の向上 • 内容 • テスト・プロセスの概念と定義 • テスト・プロセスのモデル • テスト・ドキュメントの標準 • テスト技法 • キーワード駆動テストの標準
  • 22.
    ISO/IEC 25010 (製品品質モデル) •機能適合性 • 性能効率性 • 互換性 • 使⽤性 • 信頼性 • セキュリティ • 保守性 • 移植性
  • 23.
    静的テスト • レビュー • 静的検査 •コンパイル • 関数型⾔語の場合は直観主義命題論理のスコープでのプログラムの動作証明 • リント (lint) • プログラムのバグや冗⻑を調べる • リンター (linter) : リントを⾏うプログラム
  • 24.
    テストの技法 • 同値分割テスト • 同値パーティション(同じ動作をする条件の集まり)ごとにテストを⾏う •境界値テスト • 仕様条件の境界値とその隣接値に対しテストを⾏う • デシジョン・テーブル・テスト • 複数のテスト項⽬を表にしたデシジョン・テーブルを⽤いてテストを⾏う • 状態遷移テスト • 状態遷移図/状態遷移表を⽤いてテストを⾏う • 組合せテスト • 複数の条件を組合せてテストを⾏う
  • 25.
    関数型のテスト技法 • プロパティ・ベース・テスト • プロパティを起点としたテスト •プロパティ群の値域の組合せに対して網羅的にテストを⾏う • 型クラスのルール・テスト • 型クラス実現時にインタフェースに適合するかコンパイル・チェック • コンパイル・チェックに加えてルール・テストが⾃動化できる
  • 26.
    Monoidの例 : Counter 再掲第8回 関数モデル
  • 27.
    case class Counter(c:Int) extends AnyVal: def +(rhs: Counter): Counter = Counter(c + rhs.c) object Counter: val empty = Counter(0) implicit object CounterEq extends Eq[Counter]: def eqv(x: Counter, y: Counter) = x == y implicit object CounterMonoid extends Monoid[Counter]: def empty: Counter = Counter.empty def combine(x: Counter, y: Counter): Counter = x + y Counterの定義 CounterのMonoid型クラスの定義 emptyメソッド(単位元) を定義 Semigroup由来のcombineメソッド(結合法則を満たした⼆項演算)を定義 再掲 第8回 関数モデル
  • 28.
    class CounterPropertySpec extendsAnyWordSpec with should.Matchers with ScalaCheckDrivenPropertyChecks: "Counter" should { val nonNegativeInts = Gen.listOf(Gen.choose(0, 10000)) "Property-Based TestingでCounterのfoldMap動作をテストする" in forAll(nonNegativeInts) { (xs: List[Int]) => val c: Counter = xs.foldMap(Counter.apply) c.c should be(xs.sum) } } Property-basedテスティングによるテスト テストデータの特性を定義 Property−basedテスティングの実⾏ BDD (Behavior-Driven Development)スタイルのテスト Travel Light 第16回 テスト 再掲 第8回 関数モデル
  • 29.
    class CounterLawSpec extendsAnyFunSuite with FunSuiteDiscipline with Configuration: lazy val counterGen: Gen[Counter] = Gen.choose(0, 10000).map(Counter.apply) implicit lazy val counterArbitrary: Arbitrary[Counter] = Arbitrary(counterGen) checkAll("Counter", MonoidTests[Counter].monoid) Monoid法則のテスト Monoid法則のテストを⼀括して⾏う 型クラスの規則のテスト⽤トレイト 再掲 第8回 関数モデル
  • 30.
    sbt:Scala 3 Cats>test [info] compiling 1 Scala source to /Users/asami/src/workspace2021/scala3cats/target/scala-3.1.0/classes ... [info] done compiling [info] CounterLawSpec: [info] - Counter.monoid.associative [info] - Counter.monoid.collect0 [info] - Counter.monoid.combine all [info] - Counter.monoid.combineAllOption [info] - Counter.monoid.intercalateCombineAllOption [info] - Counter.monoid.intercalateIntercalates [info] - Counter.monoid.intercalateRepeat1 [info] - Counter.monoid.intercalateRepeat2 [info] - Counter.monoid.is id [info] - Counter.monoid.left identity [info] - Counter.monoid.repeat0 [info] - Counter.monoid.repeat1 [info] - Counter.monoid.repeat2 [info] - Counter.monoid.reverseCombineAllOption [info] - Counter.monoid.reverseRepeat1 [info] - Counter.monoid.reverseRepeat2 [info] - Counter.monoid.reverseReverses [info] - Counter.monoid.right identity [info] CounterPropertySpec: [info] Counter [info] - should Property-Based TestingでCounterのfoldMap動作をテストする [info] ScalaTest [info] Run completed in 443 milliseconds. [info] Total number of tests run: 19 [info] Suites: completed 2, aborted 0 [info] Tests: succeeded 19, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [info] Passed: Total 20, Failed 0, Errors 0, Passed 20 [success] Total time: 1 s, completed 2021/11/07 5:54:50 CounterLawSpecによるMonoid法則テスト CounterPropertySpecによるBDDテスト 再掲 第8回 関数モデル
  • 31.
    Verification & Validation •Verification • 検証 • 仕様通りにシステムが動作するか確認 • Validation • 妥当性確認 • ユーザーの要求通りにシステムが動作するか確認
  • 32.
  • 33.
  • 34.
    TDD (Test-Driven Development) •テストをプログラミングの前に書く開発⼿法 • CI/CDパイプラインに⾃動テストとして組み込むことで常に⾃ 動テストによって品質が保持される • テストを動く仕様書とする • Specification as a Code • プログラミングの前にテストケースを整備することで、テスト ケースの作成⼯数を確保できる 再掲 第30回 設計/実装(1)
  • 35.
    TDDの⼿順 1. テストを作成 1. テストから呼ばれるインタフェースを作成 2.インタフェースのスタブを作成してコンパイル 3. テストを実⾏してエラーになることを確認 2. プログラムを実装 3. テストが成功することを確認
  • 36.
    テストから動く仕様書へ • テストを先に書く • 仕様を決めるということ •テストが仕様書の役割を果たす • テスト・ケースを仕様書として活⽤するための可読性を向上さ せたい • 専⽤のテスティング・フレームワーク • 本講座ではScalaTestを使⽤ • BDDでさらに重要な展開へ
  • 37.
  • 38.
  • 39.
    ⾃動テスト • 考慮点 • テスト時間 •テスト環境構築の難易度 • タイミング • 常時(夜間) • 開発時 • CI時 • CD時 • テストの⽅式 • スタブを使ってコンポーネントの単体テスト • Dockerを使って結合テスト
  • 40.
  • 41.
    BDD (Behavior-Driven Development) •振る舞いモデルを起点に開発を進める開発⼿法 • 要求仕様となる振る舞いモデルには「シナリオの実⾏例」を使⽤す る • 「シナリオの具体例」からテストケースを作成 • 要求仕様とテストケースが直結 • 受け⼊れテスト(Acceptance test)と呼んでいる。ユーザーテストの受け⼊れ テストとの混同に注意。 • 開発者、QA担当、顧客代表が「シナリオの具体例」で記述された要 求仕様を共有 • Validation : 要求仕様と実装のずれを防ぐ • テスト・レポートは最新の要求仕様のドキュメント • ⽣きた⽂書 (living document)
  • 42.
    BDDの応⽤ • BDDの技法をユニット・テスト(TDD)に適⽤する • コンポーネントの使⽤⽅法をシナリオで記述 •シナリオからユニット・テストを作成 • CI/CDパイプラインに⾃動テストとして組み込むことで常に⾃ 動テストによって要求仕様品質が保持される
  • 43.
  • 44.
  • 45.
    Find out whattime the next trains for my destination station leave Narrative: In order to plan my trips more effectively As a commuter I want to know the next trains going to my destinations Scenario: Find the optimal itinerary between stations on the name line Given Western line trains from Emu Plains leave Parramatta for Town Hall at 7:58, 8:00, 8:02, 8:11, 8:14, 0:21 When I want to travel from Parramatta to Town Hall at 8:00 Then I should be told about the trans at: 8:02, 8:11, 8:14 BDDシナリオ 出典:BDD in Action
  • 46.
    class ReservationServiceSpec extendsAnyFreeSpec with Matchers with GivenWhenThen with ReservationMatchers { "ReservationService" - { "reserveメソッド" - { "予約の追加" - { "現在時刻より後ろの有効な予約時間を予約" in { Given("テスト⽤に作成したReservationServiceを使⽤") val service = ReservationService.createForTest() When("運⽤時間内の時間") val dt = "2024-01-15T10:00:00+JST" Then("テスト対象時刻で実⾏コンテキストを⽤意") given ExecutionContext = ExecutionContext.createWithCurrentDateTime(dt) And("現在時刻より後ろの有効な予約時間で予約") ReservationServiceSpec.sbt (1/2) 再掲 第31回 設計/実装(2)
  • 47.
    val rid =ResourceId("id1234") val uid = UserId("user789") val start = LocalDateTime.of(2024, 1, 15, 11, 00) val end = LocalDateTime.of(2024, 1, 15, 12, 00) val interval = Interval.openUpper(start, end) val cmd = ReserveCommand(rid, uid, interval) service.reserve(cmd) should successReserve(cmd) } } } } } ReservationServiceSpec.sbt (2/2) 再掲 第31回 設計/実装(2)
  • 48.
    sbt:reservation> test [info] compiling2 Scala sources to /Users/asami/src/Project2023/ofad/domain/target/scala-3.1.1/test-classes ... [info] done compiling [info] ReservationServiceSpec: [info] ReservationService [info] reserveメソッド [info] 予約の追加 [info] - 現在時刻より後ろの有効な予約時間を予約 [info] + Given テスト⽤に作成したReservationServiceを使⽤ [info] + When 運⽤時間内の時間 [info] + Then テスト対象時刻で実⾏コンテキストを⽤意 [info] + And 現在時刻より後ろの有効な予約時間で予約 [info] Run completed in 270 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [success] Total time: 1 s, completed 2024/01/16 16:00:27 テストを実⾏ 再掲 第31回 設計/実装(2)
  • 49.
  • 50.
  • 51.
    テスタブル設計 • ソフトウェア・システムの性質 • テスト可能(testable) • 配備可能 (deployable) • リリース可能 (releasable) • テスト可能なシステムにするための設計技法
  • 52.
    テスト容易性 (Testability) • コンポーネントのテストのしやすさ •他のコンポーネントとの依存性をできるだけ排除する • インタフェース(提供、要求)を通してアクセス • コンポーネントの作成はDI(Dependency Injection)を可能にす る • クライアントの実⾏⽂脈は実⾏コンテキスト経由で取得するよ うにする • 認証情報、時間 • コンポーネントの内部情報がテスト・プログラムから取得でき るようにする 再掲 第21回 設計/コンポーネント設計 (2)
  • 53.
  • 54.
  • 55.
  • 56.
    まとめ • テストの位置つけ • QA(Quality Assurance) • 動く仕様書 • TDD (Test-Driven Development) • 動く仕様書でテスト • CI/CDパイプライン上で⾃動テスト • BDD (Behavior-Driven Development) • 要求仕様を動く仕様書にする • テスタブル設計 • TDD/BDDを可能にする設計⽅式
  • 57.
    参考⽂献 • The UnifiedModeling Language Reference Manual, 2nd (Rumbaugh他, 2004) • The Unified Modeling Language User Guide, 2nd (Booch他, 2004) • The Unified Software Development Process (Jacobson他, 1999) • The Object Constraint Language, 2nd (Warmer他, 2003) • UML 2 and the Unified Process: Practical Object- Oriented Analysis and Design (Arlow他, 2005) • OMG Unified Modeling Language Version 2.5 (OMG, 2015) • 上流⼯程UMLモデリング (浅海, 2008) • ソフトウェア・テストの技法 第2版 (マイ ヤーズ他, 2006) • 【この1冊でよくわかる】ソフトウェアテスト の教科書 [増補改訂 第2版](布施 他, 2021) • 知識ゼロから学ぶソフトウェアテスト 第3版 アジャイル・AI時代の必携教科書 (⾼橋, 2023) • ソフトウェア品質を⾼める開発者テスト 改訂 版 アジャイル時代の実践的・効率的でスムー ズなテストのやり⽅ (⾼橋, 2022) • Extreme Programming Explained: Embrace Change 2nd (Beck, 2004) • Specification by Example: How Successful Teams Deliver the Right Software (Adzic, 2011) • BDD in Action: Behavior-Driven Development for the whole software lifecycle (Smart, 2014)