OutSystems Developer Cloudでのテスト検討
調査・検討すべきToDo
- ODCで他のサービス (他のAppにあるService ActionやEntity)をモックが必要なテストを書くときどうするか? OutSystems 11の頃と同じ面倒な手順が必要か?
から。ODCのアーキテクチャを検討する中で、Microservices Patterns: With examples in Javaという本の目次を見ていたら、マイクロサービスにおけるテストの章があり、テストについてもメモを作っておこうと思った。
OutSystems公式ドキュメント・動画、マイクロサービスに関する書籍、Webサイト等からメモしていく。
Microservices Patterns: With examples in Java - Chapter 9.Testing microservices: Part 1
testing strategyとユニットテストをカバーする章。
- microservice導入の重要な目的の1つはテストの作りやすさ。
- ソフトウェアを素早く信頼性のある方法でリリースするには自動テストが必要
- 業務アプリケーションで頻繁にリリースする必要が無い場合は、自動テストのメリットは落ちるかも
- だからといって、自動テストがないアプリケーションのメンテナンスするのは嫌だな
- test doubleの分類。stub: SUTに値を返す、mock: SUTが正しく依存先を呼んだかを確認するためにテストが使う
- 機能テストの自動化、それぞれの説明(マイクロサービスアーキテクチャ視点での)が良い
- Unit Test: classのような小さい部品をテストする
- Integration Test: サービスがDB等の他のインフラレベルのサービスとやり取りできることを確認する
- Component Test: サービスの受入テスト
- End-to-end Test: アプリケーション全体での受入テスト
- Component Testという概念については、既にOutSystemsのテスト関連のドキュメントに登場している(そこではユニットテストに代わる、という位置づけだった)
- https://success.outsystems.com/documentation/best_practices/outsystems_testing_guidelines/ のTesting Pyramidとか参照
- ただ、このURLのTesting Pyramidとこの本でのテスト分類はうまく当てはまらない(本では4種類のテストに明確に違う役割が与えられ、URLではUnit Testの代わりにComponent Testが入ってきているという位置づけ。この違いは意識しながら本を読んだほうが良さそう)
- 本の分類に従った場合のTesting PyramidはUnit -> Integratio -> Component -> End-to-end
- consumer contract testsなんだけど、OutSystemsのService Action/Entityであれば、OutSystemsがI/Fの整合性を見てくれるから必要性は低いかな
9.2 Writing unit tests for a service
ユニットテストの別の見方として、技術的側面から行われる開発者を支援するテスト、というものもある。
OutSystemsでユニットテストするとなると、Actionが対象。Actionはオブジェクト指向言語でいうとメソッド。なのでテスト対象の粒度としてはOOPの場合と変わらない……と言いたいところだが
- テストできるのはPublicなActionのみ
- コミット前のテスト実行はできない(Publishしたものしかテストできない)
- 実行が遅い
- 他の言語ほど手軽にはテスト実行できない(本当はIDEから簡単な操作で実行したいところだが)
これだと、Testing Pyramidの最下辺を支えるテストとしては厳しい。それが最近のOutSystemsのドキュメントで、Unit TestをComponent Testに置き換えた理由だろうか。
- Unit Testを以下の2種類に分類している
- Solitary Unit Test: classを単独でテストする(依存先があればモックする)
- Sociable Unit Test: classと依存先をまとめてテストする
- Unit Testを書くときに、単一の責務のみを果たす小さなコードをテストするものだ、というような記述を見て、その範囲に収まらないものも多いという印象だった。2のタイプのUnit Testもやはりありということか
ドメインサービスをユニットテストするときは、Solitary Unit Testがよい
Controller (ドメインサービスやレポジトリを呼び出す)もSolitary Unit Test (Controllerの場合、フレームワークが見ているルーティングのテストも行いたいため、単純なモックライブラリではなく、そのあたりも含めたテスティングフレームワークを使う。ODCの場合は、このタイプのテストは必要か? ODCにすると、1つのマイクロサービスを構成するレイヤーがだいぶ薄くなる印象だが……)
OutSystems 11/ODCの場合は、ソフトウェアを構成するレイヤーが一般(OOPとそれをベースにしたDDD)と違うので、最終的には、OutSystemsの各要素に対して個別にテスト方法(Solitary/Sociableも含めて)を検討しなければならない。
Microservices Patterns: With examples in Java - Chapter 10. Testing microservices: Part 2
以下のテストが対象
- Integration Test: この本ではインフラレベルのサービスとの結合テストである点に注意
- Component Test
- End-to-end Test
Integration TestでAdaptorをテストするのって、OutSystemsでいうとCore Serviceモジュールが提供するCRUD Wrapperをテストするみたいな感じかな。External DatabaseのEntityは自動作成だからテスト不要だろうか(外部DBのテーブル/ビューを取り込む ないし Service Centerでの設定があるからテストは書いてもいいかもしれないが)。
Regarding integration tests to verify persistence in databases, how does ODC handle aurora PostgreSQL databases? Are the databases always there, and do our apps connect them?
10.2 Developing component tests
Component Tests in this context mean acceptance tests that verify the behaviors of services in isolation.
A component test calls a service under the test, and that service calls stubs of dependencies.
Some options:
- In-Process component tests: stubs and mocks are in-memory using dependency injection
- Out-of-process component tests: uses actual infrastructure services but uses stubs for dependencies
In OutSystems apps, component tests for Service Actions should be easy, just by unit testing the actions.
10.3 Developing end-to-end tests
Write tests as user journey tests.