テスト駆動開発(TDD)オンライン勉強会 #1 に行ってきた #tdd_online

先日、テスト駆動開発(TDD)オンライン勉強会 #1 に参加しました。今回はオンライン開催。簡単に所感をまとめます。

ddd-community-jp.connpass.com

所感

ライブコーディングが2本ありました。TDD のセッションで FizzBuzz 以外の題材が見れたのはとても参考になりました。途中でググったり普段の生々しい感じのコーディング風景が見れてなかなか面白かったです。

FizzBuzz の TDD と言えば、de:code 2017 で t_wada さんが公演されていた動画がとてもわかりやすいです。今回、コメント欄にもいらっしゃって大変学びがありました。

channel9.msdn.com

TDD や自動テストの特徴や課題について、感覚的になんとなく理解はしているつもりでも、きちんと言葉で説明されるとなるほどと思うところがあります。特に自動テストと TDD の違いやカバレッジのあたりの話とか。

以前、TDD (モドキ) を実践してみましたが、リファクタリングや機能追加に対して安心感があって、やはりそのあたりは TDD の大きなメリットかなと思います。最近はテストがほぼないレガシーな環境にいるので、まずは自動テストから取り組まなければ...。

TDD とは関係ないけど、JUnit の diff のビューが便利そう。Eclipse でも使えるんだろうか。あと、懇親会は参加してないけど、spatial.chat が面白そう。Vue.js が使われてるっぽい。

以下、メモから抜粋。

ライブコーディングで体感するTDD基礎

https://youtu.be/UhHdnLTxOjEyoutu.be

  • TDDはDDDとも相性がよい
  • Red-Green-Refactor
  • TDDは開発スタイルであり教義ではない
    • 手段が目的になってはいけない
  • TDDだけで十分に品質保証できるわけではない
  • 必要なければリファクタリングはスキップしてよい
  • ステップを細かくすると過剰な設計を防げる
    • Red ⇒ Green までに時間がかかるときは過剰な設計を疑う☆
    • 差分が大きいとテストコード外の不具合を埋め込んでいるかも
    • フィードバックサイクルの短さが大事
  • @ParameterizedTest, @CsvSource, @MethodSource (JUnit)
  • ループで回すと各テストを展開してくれない
  • Parameterized Test
    • 期待値ごとに分けるかどうかはテスト対象の性質とテストコードの可読性による
    • テストコードから仕様が読み取れるか
    • 同値分割における同値クラスを増やす場合に楽?☆
  • リファクタリングしたテストコードがきちんと動作するかプロダクションコードをわざと壊してテストが落ちることを確認することも大事 (テストのテスト)
  • TDDと自動テストは解決したい課題が異なる☆
  • 自動テスト
    • 自動テストはTDDがなくても実施できる
    • 自動テストは回帰テストの実行コストを抑える
    • リファクタリングしやすく
    • テストコードに想定される挙動が記述される
    • ドキュメントと違って形骸化しない (実行可能ドキュメント)
  • TDD
    • 十分なテストが書かれやすい
    • カバレッジは「足りないこと」は不足はわかるが「十分であること」の根拠には使えない☆
    • テストが書きにくい設計であることに気付く
    • 自然と高凝集/低結合なクラスを書くようになる☆
  • 外部APIはモックにする
    • Dockerで代用するのもあり?
  • Red からなかなか Green にならないと正しい方向に進んでいるか分からない
  • Red-Green-Refactorの うち Refactor のところで設計する☆
    • Red-Green のうちは汚くてもいいからとりあえず通す
  • ToDoリスト
  • テストしやすくするためにメソッドを括り出す
    • テスト観点が明確になる
  • 1テストメソッドにまとめるとテストのバリエーションを増やしにくい
  • カバレッジが100%でもアサーションが十分かどうかは分からない☆
    • テストから書いた方が抜けにくい
  • 自動テストはMust/TDDはWant
    • TDDは開発の進め方なので強制しにくい
  • テストコードの保守コスト
    • 自動テストの問題 ⇒ 解決するにはテストを書くスキルが必要
  • TDDだけでは品質は担保できない
    • テスト戦略の問題 ⇒ UT以外に全体としてどうするか
  • テスト実装工数
    • 自動テストの問題 ⇒ 長期的に回帰テストのコスト削減になるかで判断
  • TDDの問題の多くは自動テストの問題であることが多い

実践クリーンアーキテクチャに行ってきた #narusemi

実践クリーンアーキテクチャに参加しました。今回はオンライン開催。簡単に所感をまとめます。

nrs-seminar.connpass.com

所感

JJUG CCC 2019 Spring の再演。このセッションは参加してなかったのでこの機会に聴けてよかったです。先月、ドメイン駆動設計入門を読み終わったところなのでより理解が深められた気がする。

クリーンアーキテクチャは確かに定義するファイルが多くなりがちみたいだけど、それぞれがどういう役割を担っているか、特にクリーンアーキテクチャの図で右下の図がどういうことを表しているのかが理解できました。あと、課題に対してどういうアプローチを取るか、そのあたりの話は参考になります。

とはいえ、クリーンアーキテクチャを知らなくてもインタフェースの役割が理解できていれば、ある程度は近しい形というか同じような目的を実現する仕組みにはなるのかなって思ったり。ただまぁ、そのあたりの共通認識になるものとしてアーキテクチャとして提言されてるんでしょうけど。

次回はフロントエンド寄りの話らしいです。期待。

以下、メモから抜粋。

先行開発!クリーンアーキテクチャ -- ゼロから始める新規開発

https://youtu.be/5oJeSrwztPgyoutu.be

  • 最終形に辿り着くために試行錯誤したい
  • クリーンアーキテクチャ
  • 先にヘキサゴナルアーキテクチャを学ぶのがおすすめ☆
  • クリーンアーキテクチャ
  • SOLID原則
  • Entities (Enterprise Business Rules)
  • Use Cases (Application Business Rules)
  • Controllers, Presenters, Gateways (Interface Adapters)
    • Use Case Interactor
    • Use Case Input Port / Output Port (interface)
  • Frameworks & Drivers
  • 依存の方向を内向きにする
  • Controller
    • アプリが要求するデータに入力を変換する
    • Input Data に変換する
  • Input Data / Output Data / View Model
    • Data Structure (データ構造体)
    • DTO (POJO)
  • Input Boundary (interface)
  • Use Case Interactor
    • Input Boundary の実装
    • アプリケーションロジック
    • Input Data を受け取って処理して Output Data を返す
  • Data Access Interface (interface)
    • Repository
    • データにアクセスするためのインタフェース
    • クリーンアーキテクチャの Gateways
  • Data Access
    • Entity のオブジェクトを再構築する
    • 実装は何でもOK (SQL, ORM, Mock, ...)
  • Entities
  • Output Boundary (interface)
    • Presenter のインタフェース
    • 出力データを渡すためのインタフェース
  • Presenter
    • Output Boundary の実装
    • Output Data から View Model に変換する
    • View Model を View に引き渡す
  • 処理の流れ☆
  • フロントを先行開発したい
  • Web アプリのフレームワークでは Controller でレスポンスが必要
    • Presenter と相性がわるい
    • ネイティブアプリの場合は Presenter は相性がいい?
    • ⇒ Presenter を捨てる
    • ⇒ Output Data をそのまま返す
    • ⇒ Output Data を Boundary に渡すか、戻り値で返すかの違いだけ
    • Output Data に変換してるからビジネスロジックに依存していないはず☆
    • Output Data ⇒ View Model の変換は Controller が担う
  • アクションごとにユースケースがある
    • Controller のフィールドが多くなりがち (@Inject Hell)
    • ユースケースが増えるたびに Controller の修正が必要
    • ⇒ Message Bus (UseCaseBus)
    • ⇒ Command オブジェクト
    • Input Data から期待する Output Data は分かる
    • 処理の実体 (Interactor) は何でもOK
  • 定義するものが多い (作るファイルが多い)
    • ⇒ 自動生成ツール
    • モジュール / テストモジュール / テストデータ / DI 設定
    • 同名の JSON ファイルから Output Data を構築するスタブ
    • BFF とかだと特に便利
  • 依存関係逆転の原則☆
  • ビジネスを中心にシステムを組み立てる☆
  • https://github.com/nrslib/play-clean-java

JJUGナイトセミナー「みんなの小噺」に行ってきた #jjug

JJUGナイトセミナー「みんなの小噺」に参加しました。今回はオンライン開催。簡単に所感をまとめます。

jjug.doorkeeper.jp

所感

Retrofit は割と前からあるみたいだけど、初めて知りました。もともとは Android 向けなんだろうか。Type-safe だし、新しいプロトコルにも対応しているようでなかなかよさそう。

今回、初めて JIG のデモを見ましたが、思ってたよりずっといい感じ。設計と実装のサイクルを回すという考えをしっかりサポートしてるように見えました。DDD の勉強でコード書くときに使ってみようかな。

Dapr は、この前の JSUG で聴いた Spring Cloud Consul の話に似てるような気がした...?同じ目的で作られてるものなんだろうか。あと、組み合わせ問題の話があったけど、そのあたりがイマイチ腹落ちしてない...。

[2020/05/02 追記] YouTube の URL

youtu.be

以下、メモから抜粋。

JavaでHTTP接続してみよう

  • JSON は js のオブジェクトをデータ記述に流用したもの
  • 標準 API
  • java.net.Socket
    • TCP 接続
    • バークレイソケットをラップ
  • HTTP プロトコル
  • java.net.URLConnection
    • HTTP で使うときは HttpURLConnection にダウンキャストが必要
    • 主にドキュメント取得で使う (POST パラメータ送信は面倒)
    • 同期処理のみ
  • java.net.http.HttpClient
    • HttpResponse.BodyHandler でレスポンスのハンドラ
    • BodyHandlers#ofLines でレスポンスを Stream で返せる
    • HTTP2 に対応
    • 非同期でモダンな API
  • Retrofit
    • Type-safe HTTP Client
    • interface のメソッドにマッピングする
    • 内部では OkHttp で HTTP 接続する
    • リクエストのオブジェクトは Call<T> でラップする
    • HTTPS, WebSocket, WebRTC, HTTP2, HTTP3
  • フレームワークで用意されているものがあればそっちを使うのがよさそう

RDRA2.0のサンプルをJIGを利用して実装してみたよ

www.youtube.com

  • system-sekkei/library
  • RDRA
  • JIG
  • ドメインモデルの実装
    • バリエーションダイアグラム
      • ビジネスに登場する値/区分(条件)
    • 状態モデル
      • ビジネスに登場する状態/状態遷移
    • 情報モデル
      • ビジネスに登場する情報とそれらの関連を表す
      • パッケージ構成
  • アプリケーション層の実装
  • JIG ドキュメント
    • パッケージの依存関係 (深さはファイル名の -depthN で見れる?)
    • ビジネスルールの関連 (クラスの関連)
    • クラス間の相互依存が見つけやすい
    • 各層の呼び出し関係が分かりやすい
      • Controller ⇒ Coordinator
      • Coordinator ⇒ Service
      • Service ⇒ Repository
      • 画面 ⇒ ユースケース
  • RDRA ⇔ JIG で図を比較しながら実装する
    • サイクルを回す

なぜ僕がDaprを使おうとしているのかという話

  • 分散アプリケーションランタイム
    • アプリとインフラの間に置く (プロキシ?)
    • マイクロサービスのビルディングブロック?を提供
    • マイクロサービス開発の機能群を抽象化する
    • サイドカーとして提供
      • アプリ ⇔ Dapr API は HTTP/gRPC
  • Dapr のコンテナ上でアプリが動くわけではない
  • サービス呼び出しやデータストア保存は Dapr のプロセス経由
  • サービスディスカバリは Dapr が担う
  • Spring Boot / Spring Cloud でも実現可
  • Dapr
  • バージョンアップ
  • Java と Dapr のバージョンアップを別にできる
  • Spring のようにフルスタックではない
    • 組み合わせ問題が起きるかも?
  • https://github.com/cero-t/dapr-trial

IAM クロスアカウントロール作成

AWS アカウント間でアクセスを委任 (クロスアカウントアクセス) するための IAM ロール (クロスアカウントロール) を作成する手順。

docs.aws.amazon.com

IAM 本 を読んでて、クロスアカウントロール作成のところでイマイチ流れが掴めなくてモヤモヤしてました。そこで、AWS のドキュメントにあるチュートリアルを読みつつ、自分の理解のために手順をざっくり図解してみたらなんとなく理解できた気はする。

f:id:knt_mr:20200426135349p:plain

※切り替え先の AWS アカウントの IAM ユーザー

  1. 対象サービスへのアクセス許可を定義したポリシーを作成
  2. 切り替え用のロールを作成
  3. 1) で作成したポリシーを 2) のロールに割り当てる

※切り替え元の AWS アカウントの IAM ユーザー (図と番号がズレてる)

  1. 切り替え用のロールへのアクセス許可を定義したポリシーを作成
  2. 1) で作成したポリシーをアクセス許可するユーザーのグループに割り当てる
  3. 切り替え用のロールへのアクセス拒否を定義したポリシーを作成
  4. 3) で作成したポリシーをアクセス拒否するユーザーのグループに割り当てる

切り替え元のユーザーは切り替え用のロールを使って対象のサービスにアクセスする。なお、切り替え用のロールにアクセスできるユーザーはポリシーで制限できる。AWSチュートリアルでは、Deny を定義したポリシーを切り替え元のグループに割り当てている。IAM 本では、切り替え用のロールに割り当てているポリシーにアクセスを許可するユーザーを定義している。(Principal)

SQS メッセージ送受信 & SES メール送信 (PHP)

いきなり余談ですけど、以前購入したまま中途半端になってた AWS のオンライン講座を改めて見直してみました。マネジメントコンソールとか設定できるパラメータはいろいろ変わってるところはあっても、基礎的なところはあまり変わってなくて、オンライン講座のコンテンツとしてまだ全然有用そうな印象を受けました。

そのオンライン講座の中で、SQS と SES を組み合わせるちょっとした課題があったので備忘録。初めて PHP を書きました。

  1. SQS メッセージ送信 (メッセージに送信元/送信先/タイトル/本文を含む)
  2. SQS メッセージ受信 & メール送信 (メール送信したらメッセージを削除)

SQS メッセージ送信

gist.github.com

SQS メッセージ受信 & メール送信

gist.github.com

JSUG勉強会 2020 その3 Spring Cloud without Netflix OSS に行ってきた #jsug

JSUG勉強会 2020 その3 Spring Cloud without Netflix OSS に参加しました。今回はオンライン開催。簡単に所感をまとめます。

jsug.doorkeeper.jp

所感

Spring Cloud やマイクロサービスはあまり知識がないため、自分にはなかなかハイレベルな内容でした...。後半2つのセッションは若干内容が被ってたけど、特に最後のセッションは Kubernetes 絡みの事例で貴重な内容だったかも。こういうのをしっかり理解できるようになりたいものです。

ところどころ、Spring Cloud 関連は EOL が短い傾向あり?という話が出てたのが気になる。そんなに困らないということだったけど、後方互換はちゃんと考慮されてる感じなんだろうか。

Spring Cloud のようなマイクロサービス向けのライブラリは、アーキテクチャや設定などがサービスやライブラリ間で疎結合になるように工夫されてるような印象があります。最初は覚えるのが大変そうだけど簡単に運用できるようになってるんだろうと思います。

以下、メモから抜粋。

Introduction to Resilience4j

  • フォールトトレランスライブラリ
    • サーキットブレイカ
  • Netflix OSS
    • Eureka, Zuul 以外は保守モードに移行
    • Spring Cloud Netflix も同様
  • Hystrix の代替の1つとして Resilience4j
  • 関数型プログラミングモデル
  • コアモジュール☆
  • アドオンモジュール☆
  • recover に代替処理を記述
  • サーキットブレイカーの状態遷移☆
    • CLOSED, OPEN, HALF_OPEN
    • Resilience4j にはもう2つの状態がある
    • OPEN から一定時間経過すると HALF_OPEN
  • スライディングウィンドウ (呼び出し結果を保存する配列)
    • 回数ベース (N個の循環配列) ※デフォルト
    • 時間ベース (1秒ごとの部分集約のN個の循環配列)
  • 最小呼び出し回数に満たない場合は失敗率や遅延率は計算されない
    • 回数未満の間は状態遷移しない
  • HALF_OPEN ⇒ OPEN は回数ベース
  • 呼び出し遅延とタイムアウトの設定は別
  • resilience4j-spring-boot2
  • Actuator で CircuitBreaker の状態を監視
    • resilience4j-prometheus は非 Spring Boot 向け?
  • Spring Cloud Circuit Breaker
  • TimeLimiter?

Spring Cloud Consul / Consul 入門

  • 大規模分散システムを構築するための機能を提供
  • HashiCorp Consul
    • Web API の設計がきれい
  • Server/Agent によるクラスタ構成 ※同じバイナリ
    • Agent 配下の node の情報は Server 経由でクラスタ内に同期される
  • Consul ⇒ サービスの状態管理 & Key-Value Storage
  • Multi Datacenter
  • Consul Connect (Service Mesh)
  • Spring Cloud Consul
    • Service Discovery, クライアントサイドロードバランシング
    • Distributed Configuration ≒ Spring Cloud Config
  • Spring Cloud Consul はライブラリとして動作する
    • サービスと同じプロセス内で動く?
    • ⇔ サービスメッシュ
  • ローカルのプロパティを Consul の設定で上書きできる
  • @RefreshScope
    • Key-Value Storage の値を変更すると Bean をリフレッシュする (DIをやり直す)
    • もしくは /refresh エンドポイントを叩く
  • Spring Cloud Gateway
  • 通信や API の通信を暗号化するため TLS は必須
  • デフォルトは認証なしのため ACL を有効 + 必要最低限の API を公開する
    • デフォルトはすべての API が認証なしでアクセスできる

github.com

Spring Cloud Gateway on Kubernetes

www.slideshare.net

  • API Gateway Pattern
    • マイクロサービスのエッジに API Gateway を置く
    • サービスごとに横断する関心ごとをゲートウェイに持たせる
    • それぞれのサービスはシンプルに
  • Route, Predicate, Filter
    • ルーティングの設定は Functional に記述可
  • WebFlux & Reactor でノンブロッキングに実装されている
    • 大量リクエストを効率的に捌けるはず
  • Spring Cloud Kubernetes
  • Discovery Client (Service Discovery)
    • @EnableScheduling を付けないとポーリングしてくれない
  • Distributed Configuration
  • Circuit Breaker
    • Resilience4j
  • Security (Spring Security)
    • Spring Cloud Gateway 上で session と資格情報を関連付ける
    • Scope による権限制御
  • Monitoring (Prometheus)
    • Actuator + Micrometer

github.com

Windows の curl で SSL 証明書の失効チェックができない

前回の続き。備忘録。

Jenkins から curl で Google Chat に通知する - kntmr-blog

しばらくは問題なく動作していたが、いつ頃からか Jenkins から curl を実行したところで以下のようなエラーが出るようになった。

curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092013) - 失効サーバーがオフラインのため、失効の関数は失効を確認できませんでした。

SSL 証明書の失効チェックができてないっぽい?

次のどちらかのオプションで回避する。セキュリティ的にはよろしくないかもだけど、社内の限定的な範囲でしか使わないのでよしとする。

  • --ssl-no-revoke: SSL 証明書の失効チェックを無効にする (Windows のみ)
  • -k, --insecure: SSL で安全ではないサーバー接続を許可する

参考

curl - How To Use