<!-- .slide: style="font-size: 30px;" --> # Testing microservices: Part 2 ## CH. 10 --- <!-- .slide: style="font-size: 30px;" --> ## Agenda - Test pyramid (CH.9) - Unit tests (CH.9) - Integration tests (10.1) - Component tests (10.2) - End-to-end tests (10.3) --- <!-- .slide: style="font-size: 30px;" --> ## Test pyramid (CH.9) ![](https://i.imgur.com/H0oNcAZ.png) Note: 下到上:越下面越多 左邊:測試目的 右邊:特性 - 測試 & 獲得回饋的速度 - 可靠的程度 - 花費的時間 & 人力成本 --- <!-- .slide: style="font-size: 25px;" --> ## Unit tests (CH.9) ![](https://i.imgur.com/UjEWRMO.png =600x400) - 目標:Test business logic - 方法:Verify unit (class, function) behaves as expected - 面向:Technology-facing tests that support development Note: - sociable unit test (business logiic) - test class and its dependencies - entity: test order.getOrderTotal() is correct - value object: test Monet object can be added - saga: test saga send the correct command message - solitary unit test - test a class in isolation - controller、service、adapter:mock their dependencies, Verifies that the value returned by the service method is correct and that the dependencies have been invoked correctly ---- <!-- .slide: style="font-size: 25px;" --> ### Sociable unit test & Solitary unit test ![](https://i.imgur.com/adAbOxQ.png =800x600) Note: - sociable unit test (business logiic) - test class and its dependencies - entity: test order.getOrderTotal() is correct - value object: test Monet object can be added - saga: test saga send the correct command message - solitary unit test - test a class in isolation - controller、service、adapter:mock their dependencies, Verifies that the value returned by the service method is correct and that the dependencies have been invoked correctly --- <!-- .slide: style="font-size: 25px;" --> ## Integration tests ![](https://i.imgur.com/SZVimHe.png =300x300) - 目標:Verify a service can properly interact with other services/infrastructure - 方法:Test the individual adapter classes that implement the communication - 面向:Technology-facing tests that support development (between services) ---- <!-- .slide: style="font-size: 25px;" --> ### Order Service Example ![](https://i.imgur.com/OJG1eVJ.png =600x500) - Strategy 1: test service's adapters - Strategy 2: use contracts to veriyfy interactions between applications Note: 先講 strategy,再講圖 ---- <!-- .slide: style="font-size: 30px;" --> ### Persistence integration tests - Test interaction with DB - Directly tests the OrderRepository class - Setup (docker) > Execute > Verify > Teardown ![](https://i.imgur.com/yByLsYj.png =600x450) Note: Rather than test persistence through Order Service’s API, it directly tests the OrderRepository class - different: The unit tests we wrote earlier only test in-memory objects - steps: - setup - execute - verify - teardown ---- <!-- .slide: style="font-size: 30px;" --> ### Contract tests (CH.9) - Verify Service (provider) and its Client (consumer) can communicate - If both are tested with the same contracts: - Provider and Consumer can communicate - Testing them **in isolation** ![](https://i.imgur.com/4AD9kdS.png =120x180) ![](https://i.imgur.com/tGFX6ly.png) Note: - client vs provider (判斷誰是誰) - Consumer-side: - tests consumer’s adapter. - simulate provider res/output - verify can call provider corectlly - Provider-side: - tests provider’s adapter. - simulate consumer req/input - test the adapters call its dependencies corectlly - consumer-driven contract: 由 consumer 撰寫 - 取代聯調? ---- <!-- .slide: style="font-size: 30px;" --> #### Order Service Example ![](https://i.imgur.com/El0MRNU.png =480x400) ![](https://i.imgur.com/qXS7XQj.png =500x200) ---- <!-- .slide: style="font-size: 30px;" --> #### Contract for REST API ![](https://i.imgur.com/yJe1Q1c.png =650x300) - Provider: Verify OrderController can handle this endpoint and generate the expected response - Consumer: Invokes OrderServiceProxy and verifies that either it returns the correct values or throws the expected exception ---- <!-- .slide: style="font-size: 30px;" --> #### Contract for publish/subscribe interactions ![](https://i.imgur.com/PKLoRzk.png =700x400) - Provider: Invokes OrderDomainEventPublisher to publish an OrderCreated event and verify it match clients’ expectations - Consumer: Verify OrderHistoryEventHandlers invokes its dependencies correctly ---- <!-- .slide: style="font-size: 30px;" --> #### Contract for asyncrequest/response interactions ![](https://i.imgur.com/crMnssD.png =650x430) - Provider: Invokes KitchenServiceCommandHandler and verifies the reply message is correct - Consumer: Invokes KitchenServiceProxy and verifies that it returns the expected result --- <!-- .slide: style="font-size: 30px;" --> ## Component tests ![](https://i.imgur.com/RvXqMnX.png =600x400) - 目標:Acceptance test for service - 方法:Tests a service in isolation by using stubs for its dependencies - 面向:Business-facing tests for a software component Note: which treat it as a black box and verify its behavior through its API. 測試可以滿足 use case ---- <!-- .slide: style="font-size: 30px;" --> ### Designing component tests ![](https://i.imgur.com/I3spfwx.jpg =450x300) - In-process: runs the service with in-memory stubs and mocks for its dependencies - Out-of-process: test uses real infrastructure services (db, message brokers) but uses stubs for any dependencies that are application services ---- <!-- .slide: style="font-size: 30px;" --> ### Out-of-process component tests ![](https://i.imgur.com/3m1MLQq.jpg =600x450) ---- <!-- .slide: style="font-size: 30px;" --> ### Defining acceptance tests for order service User stories (use case) -> Test cases ```text Place order ``` ```text As a consumer of the Order Service, I should be able to place an order ``` ```text (setup) Given a valid consumer Given using a valid credit card Given the restaurant is accepting orders (execute) When I place an order for Chicken Vindaloo at Ajanta (verification) Then the order should be APPROVED And an OrderAuthorized event should be published ``` ---- <!-- .slide: style="font-size: 30px;" --> ### Write acceptance tests for order service Gherkin: writing specifications (human readable) Cucumber: execute the specifications and validate ![](https://i.imgur.com/qaDRXnD.png =600x450) ---- <!-- .slide: style="font-size: 30px;" --> ### Write acceptance tests for order service - setup ![](https://i.imgur.com/qhDyrB7.png) ---- <!-- .slide: style="font-size: 30px;" --> ### Write acceptance tests for order service - execute ![](https://i.imgur.com/mfSakOo.png =750x600) ---- <!-- .slide: style="font-size: 30px;" --> ### Write acceptance tests for order service - verification ![](https://i.imgur.com/G1JQah9.png =750x600) --- <!-- .slide: style="font-size: 30px;" --> ## End-to-end tests ![](https://i.imgur.com/nIZ6hAh.png =600x300) - 目標:Acceptance test for entire application - 方法:Launch all services and test together - 面向:Business-facing tests for entire application ---- <!-- .slide: style="font-size: 30px;" --> ### Designing End-to-end tests - Write user journey tests (combo of use case) e.g.: write a single test for create order + revise order + cancel order - Use Gherkin & Cucumber ![](https://i.imgur.com/E41MHCQ.png) Note: slow, brittle, and expensive way --- <!-- .slide: style="font-size: 30px;" --> ### Testing Tools - [Pact](https://docs.pact.io) A code-first consumer-driven contract testing tool > Pact generates language-neutral acceptance contracts, in the form of JSON pact files. > These pact files can be created, or tested, by anything that implements the Pact specification, whether the code is Ruby, Javascript, the JVM, or any other language Note: Spring Cloud Contract => for java spring ---- <!-- .slide: style="font-size: 30px;" --> ### Testing Tools - [Cucumber](https://cucumber.io/docs/guides/overview/) A tool that supports Behaviour-Driven Development(BDD) > Cucumber reads executable specifications written in plain text and validates that the software does what those specifications say. Note: Behavior-driven development 行為驅動開發 --- ### Q&A ![](https://i.imgur.com/CDeR85s.png)
{"metaMigratedAt":"2023-06-17T16:12:47.086Z","metaMigratedFrom":"Content","title":"Testing microservices: Part 2","breaks":true,"contributors":"[{\"id\":\"877c0604-9ea2-40ff-8834-5ea8a760ce56\",\"add\":10802,\"del\":2539}]"}
    211 views