Slide 1

Slide 1 text

「コンパイル時のユニットテスト」 #NextbeatTechBar 導⼊するとユニットテストを 書かなくてよくなるのか?

Slide 2

Slide 2 text

⾃⼰紹介 高丘 知央 ( Tomohisa Takaoka ) 株式会社ジェイテックジャパンCTO イベントソーシング・CQRSフレームワーク Sekiban メンテナ 米国カリフォルニア州ロングビーチ在住(ロスの近く) ● X : @tomohisa ● Github : @tomohisa ● Linkedin : tomohisatakaoka 自作キーボード、3Dプリント自作トラックボール製作 London Tech Talk ポッドキャストとブッククラブ出演 #NextbeatTechBar 🆗

Slide 3

Slide 3 text

株式会社ジェイテックジャパンの紹介 ● 創業50年を超えた総合IT企業、株式会社 ジャパンテクニカルソフトウェア (JTS) のグループ企業。 ● New York 所在 J-Tech Creations, Inc. の 東京拠点。 ● B2C / B2B アプリケーションを 開発‧運⽤するソフトウェア開発企業。 ● .NET‧Azure 等 Microsoft の 技術スタックを主に使⽤。 🆗 #NextbeatTechBar

Slide 4

Slide 4 text

Overview 「コンパイル時のユニットテスト」 1. どこからきた、どんな概念なのか? 2. どのような書き⽅なのか? 3. テストにどんな影響があるのか? 🆗 #NextbeatTechBar

Slide 5

Slide 5 text

「コンパイル時のユニットテスト」 どこからきた、どんな概念なのか?

Slide 6

Slide 6 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? Scott Wlaschin (スコット ラーション) ⽒の発⾔、著書がもとになっている 🆗 #NextbeatTechBar

Slide 7

Slide 7 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? 🆗 Scott Wlaschin (スコット ラーション) ⽒ 「F# for Fun and Profit」 ● Wlaschin ⽒の運営するブログ ● https://fsharpforfunandprofit.com/ ● F#を⽤いて多くの関数型ドメインモデリングの概念 が説明されている ● 関数型ドメインモデリングの概念はF#などの関数型 ⾔語以外でも参考にできる #NextbeatTechBar

Slide 8

Slide 8 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? Scott Wlaschin (スコット ラーション) ⽒ 「Domain Modeling Made Functional」 ● 関数型を⽤いてドメインモデリングを⾏う⼿法につ いて解説した本 - Pragmatic Bookshelfで購⼊可能 ● 2018年1⽉発⾏ 英語のみ、⽇本語は未発⾏ ● ADT(代数的データ型)を使⽤して型の合成(AND, OR) を⾏い、ドメインの定義を⾏う⼿法 ● Railway Oriented Programming - 型の合成と Result型を使⽤したエラーハンドリング 🆗 #NextbeatTechBar

Slide 9

Slide 9 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? Scott Wlaschin (スコット ラーション) ⽒ 「Domain Modeling Made Functional - Scott Wlaschin KanDDDinsky 2019」YOUTUBE ● 上記の「Domain Modeling Made Functional」 本の概要について2019年に説明している講演 ● この講演の中で”Compile Time Unit Test” - コ ンパイル時のユニットテストに⾔及している 🆗 #NextbeatTechBar

Slide 10

Slide 10 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? 実際に話している内容 ① ● メールアドレスを表現するEmailContact 型は VerifiedEmailもしくは UnverifiedEmail型のどちらかの型の多相性を持つ型とする type EmailContactInfo = VerifiedEmail | UnverifiedEmail ● メール送信サービスの⼊⼒はVerifiedEmailのみとする。 ● このような静的な型を⽤いたモデリングにより、ビジネスの要件を表現するこ とができる。 🆗 #NextbeatTechBar

Slide 11

Slide 11 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? 実際に話している内容 ② ● フラグをチェックするたくさんのコードが不要になり、ユニットテストを書く 必要がない。 With this new things called “VerifiedEmail”, I don’t have to write a unit test, I don’t have to check any billion flags. ● これは⾃⼰⽂書化であり、コンパイル時のユニットテストです。 This is self documenting and it’s a Compile Time Unit Test. 🆗 #NextbeatTechBar

Slide 12

Slide 12 text

「コンパイル時のユニットテスト」どこからきた、どんな概念なのか? まとめ ● 「コンパイル時のユニットテスト」とは Scott Wlaschin ⽒のDomain Modeling Made Functional に関する登壇で出てきた表現 ● 1つのオブジェクトの状態の遷移をパラメータやフラグで表現するのではなく、 別の型として定義する。各機能は特定のオブジェクトの状態でないと実⾏でき ないように動作を制限する。 ● 不正なデータを⼊れることができず、⼊れようとするとコンパイルエラーとな るため、「コンパイル時のユニットテスト」と表現している ● その部分に関してはコンパイルでチェックできるので”テストを書く必要がな い”と書いており、ロジックのテストが不要であると⾔っているわけではない。 🆗 #NextbeatTechBar

Slide 13

Slide 13 text

「コンパイル時のユニットテスト」 どのように記述するのか?

Slide 14

Slide 14 text

② 状態ごとに型を変える書き⽅ 「コンパイル時のユニットテスト」どのように記述するのか? Wlaschin⽒のF#版のコード ① フラグを使ったオブジェクト指 向的な書き⽅ 🆗 OR #NextbeatTechBar

Slide 15

Slide 15 text

② 状態ごとに型を変える書き⽅ 「コンパイル時のユニットテスト」どのように記述するのか? 個⼈的に作ったC#版 ① フラグを使ったオブジェクト指 向的な書き⽅ 🆗 OR #NextbeatTechBar

Slide 16

Slide 16 text

② 状態ごとに型を変える書き⽅ 「コンパイル時のユニットテスト」どのように記述するのか? 個⼈的に作ったC#版 - メール検証 ① フラグを使ったオブジェクト指向的 な書き⽅ 🆗 検証の成功、失敗に関わらず EmailContactInfo 型を使用する #NextbeatTechBar

Slide 17

Slide 17 text

個⼈的に作ったC#版 - メール検証 ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ 「コンパイル時のユニットテスト」どのように記述するのか? 🆗 検証成功した時だけ VerifiedEmailAddres型を生成可能 #NextbeatTechBar

Slide 18

Slide 18 text

「コンパイル時のユニットテスト」どのように記述するのか? 個⼈的に作ったC#版 - パスワードリセットメール送信 🆗 ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ Verifyされていないと送 ることができないので チェックが必要 #NextbeatTechBar

Slide 19

Slide 19 text

「コンパイル時のユニットテスト」どのように記述するのか? 個⼈的に作ったC#版 - パスワードリセットメール送信 🆗 ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ 入力の型で制限しているので、関数内 でのチェックの必要がない #NextbeatTechBar

Slide 20

Slide 20 text

「コンパイル時のユニットテスト」 テストにどんな影響があるのか?

Slide 21

Slide 21 text

「コンパイル時のユニットテスト」テストにどんな影響があるのか? 個⼈的に作ったC#版 - パスワードリセットメール送信のテスト 🆗 ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ Verifyされているものと いないものが両方想定し た結果となるかをテスト する #NextbeatTechBar

Slide 22

Slide 22 text

「コンパイル時のユニットテスト」テストにどんな影響があるのか? 個⼈的に作ったC#版 - パスワードリセットメール送信のテスト 🆗 ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ VerifiedEmailしか関数の入力に できないため、UnverifiedEmail に関しては関数に渡すことができ ず、コンパイルエラーとなる #NextbeatTechBar

Slide 23

Slide 23 text

個⼈的に作ったC#版 - パスワードリセットメール送信のテスト ① フラグを使ったオブジェクト指向的 な書き⽅ ② 状態ごとに型を変える書き⽅ 「コンパイル時のユニットテスト」テストにどんな影響があるのか? 🆗 VerifiedEmailしか関数の入力に できないため、UnverifiedEmail に関しては関数に渡すことができ ないので、テストを書く必要がな い。 ”コンパイル時の ユニットテスト” #NextbeatTechBar

Slide 24

Slide 24 text

「コンパイル時のユニットテスト」テストにどんな影響があるのか? 静的な型を使ってモデリングをした場合... ● 特定の状態の型に対して機能を記述できるため、フラグのチェックが不要にな る。正しいデータしか⼊⼒できないため⼊⼒に関するテストが不要になる。 ● 全体としてそれぞれの状態でどう振る舞うかに関してのテストは必要であり、 テストの数は減るが無くなるわけではない ● フラグを持たないことによる型の⾃⼰⽂書化 ↔ 型が増えることによって管 理が⾯倒になるというトレードオフがある 🆗 #NextbeatTechBar

Slide 25

Slide 25 text

注意点

Slide 26

Slide 26 text

「コンパイル時のユニットテスト」注意点 静的な型の合成を使ってのモデリングの注意点 - パターンマッチング F# のような判別共⽤体 - Discriminated Unions があるとパターンマッチングでの網羅、完 全性をコンパイルでチェックできるので便利 判別共⽤体 - Discriminated Unions 直和型 - Disjoint Union タグ付きユニオン - Tagged Union 選択型 - Choice Type など状況によって⾊々表現される。C#などには直接の実装がないため、Interfaceや型の多相 性などを⽤いて似た機能として実装できるが、パターンマッチングでの完全性をコンパイル 時の判別はできないという問題はある 🆗 #NextbeatTechBar

Slide 27

Slide 27 text

「コンパイル時のユニットテスト」注意点 静的な型の合成をドメイン内で使⽤したデータの永続化 ‧復元 Domain Modeling Made Functionalでは、カスタムのシ リアライザ‧デシリアライザを定義して永続化、データ の復元を⾏う⽅法を紹介している。 JSONを使⽤している場合、JSON内に型のタグをつける ことにより、カスタムシリアライザを定義せずにデータ の永続化、復元を型を保持して⾏うことができる。 [JsonDerrivedData(typeof(VerifiedEmail),nameof(VerifiedEmail))] https://zenn.dev/jtechjapan_pub/articles/618539ba9 43093 🆗 #NextbeatTechBar

Slide 28

Slide 28 text

「コンパイル時のユニットテスト」注意点 静的な型の合成を使ってのモデリングを⾏ってみての感想 ● 静的な型によるデータの変換にフォーカスすることにより、複雑なプログラム を記述しやすくなった ● 型によるパターンマッチやswitch式を多⽤するようになり、if ⽂で記述するこ とが少なくなった。 ● フラグをできるだけ無くして型の遷移でビジネスロジックを表現することによ り、型の数は多いが、それぞれの型とロジックはシンプルに表現できるように なった 🆗 #NextbeatTechBar

Slide 29

Slide 29 text

「コンパイル時のユニットテスト」注意点 関数型ドメインモデリングとイベントソーシング ● Domain Modeling Made Functionalの本は基本的に 関数型でドメインモデリングを⾏い、イベントソー シングで実装する⽅法について書かれている。 ● 関数型ドメインモデリングはイベントソーシングと 相性はよく、データの状態の遷移をイベントで表現 して、ドキュメントデータベースにデータを保存す ることにより扱いやすくなる。 ● ただ、関数型ドメインモデリングはイベントソーシ ングを採⽤しなくても実践可能 🆗 #NextbeatTechBar

Slide 30

Slide 30 text

Sekiban の紹介 ● イベントソーシング / CQRS ⽤のアプリケーション開発フレームワーク ● ⾔語は C# .NET 7 + ● データストアに Microsoft Azure Cosmos DB / Amazon DynamoDB、 PostgreSQL にも対応済み。 ● 2023年12⽉にオープンソースソフトウェアとして公開 (Apache 2.0)、 有料プランはない。 ● 関数型ドメインモデリングとの相性もよく、実際に複数プロジェクトで使⽤ されている。 🆗 #NextbeatTechBar

Slide 31

Slide 31 text

まとめ

Slide 32

Slide 32 text

まとめ ● Domain Modeling Made Functional 本はどの⾔ 語で実装するにしてもアイデアが得られるのでお すすめ。 ● Scott Wlaschin⽒はテストを軽視しているわけで はなく、データの意味が変わるときに型を変える ことにより、特定の処理を特定の状況でしか実⾏ できないように制限することにより、フラグの チェックやテストの個数を減らすことを勧めてい る ● 実装の選択肢としてイベントソーシングと組み合 わせてツールの⼀つとして持っておくのは良いか もしれない。 🆗 #NextbeatTechBar

Slide 33

Slide 33 text

おわり 🆗 質問などありましたらXなどで連絡ください @tomohisa 今回のサンプルコード https://github.com/tomohisa/PublicSamples Samples/20240322Test01 型の状態遷移を⽤いて書いた公開プログラム https://github.com/tomohisa/CSharpOdai/tree/main/20240102/kaito/tomohisa/202402/Modeling https://github.com/tomohisa/Long2Long Sekiban GitHub https://github.com/J-Tech-Japan/Sekiban J-Tech Japan Tech Blog https://zenn.dev/p/jtechjapan_pub #NextbeatTechBar