Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strategies for Microservices

1,156 views

Published on

The primary goal of the microservice architecture is to enable the rapid, reliable delivery of software with DevOps. One of the pillars of DevOps is automated testing, yet many organizations attempt to adopt microservices while still doing manual testing. What’s more, the microservice architecture has its own distinctive automated testing challenges.

This presentation describes how to descend the testing pyramid and replace slow, brittle, end-to-end tests with faster, more reliable tests for individual services. You will learn how to write tests that ensure that service APIs evolve while preserving backward compatibility. You’ll learn how, by running these tests in a deployment pipeline, you will fully benefit from microservices.

Published in: Software
  • Be the first to comment

Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strategies for Microservices

  1. 1. @crichardson Descending the test pyramid Copyright © 2019. Chris Richardson Consulting, Inc. All rights reserved Chris Richardson Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action and Microservices Patterns @crichardson chris@chrisrichardson.net https://adopt.microservices.io
  2. 2. @crichardson Presentation goal Effective testing strategies for microservices
  3. 3. @crichardson About Chris http://adopt.microservices.io
  4. 4. @crichardson About Chris https://microservices.io/book 40% discount with code ctworaclecodeone19
  5. 5. About Chris: microservices.io Microservices pattern language Articles Example code Microservices Assessment Platform
  6. 6. @crichardson Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production
  7. 7. @crichardson The state of automated testing today: Oops! https://cdn.agilitycms.com/sauce-labs/white-papers/sauce-labs-state-of-testing-2018.pdf 😢
  8. 8. @crichardson + Marketplace is volatile, uncertain, complex and ambiguous + Businesses must innovate faster Deliver software rapidly, frequently and reliably Software
  9. 9. Daily Commits Use DevOps & Continuous Delivery/Deployment A highly testable and deployable architecture is essential ApplicationAutomated deployment pipeline Production Source code repository Automated testing is essential
  10. 10. @crichardson The problem with a large, complex monolith Time Maintainability Testability Deployability Modularity Evolvability Size/ Complexity -ilities required to be competitive Risk of disruption
  11. 11. The microservice architecture is an architectural style that structures an application as a set of services Each microservice is: • highly maintainable and testable • loosely coupled • independently deployable • organized around business capabilities • owned by a small team
  12. 12. @crichardson Autonomous service teams Order Service Automated deployment pipeline Source code repository Kitchen Service Automated deployment pipeline Source code repository Delivery Service Automated deployment pipeline Source code repository Production Orders Team Kitchen Team Delivery Team
  13. 13. @crichardson Microservices enable DevOps DevOps requires automated testing Complexity of microservices requires good automated testing Using the Microservice Architecture without automated testing is self-defeating AND risky http://bit.ly/msa-antipattern-flying-before-walking
  14. 14. @crichardson What is a test? Test System under test (SUT) Verifies behavior • SUT = thing being tested = class … entire application • Collection of tests = Test Suite
  15. 15. @crichardson The testing pyramid and microservices Unit Integration Includes consumer-driven contract tests Component End to End Classes within service A services adapters An entire service Multiple services or application Brittle, Slow, Costly Reliable, Fast, Cheap
  16. 16. Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production Unit testing Unit Integration Component End to End
  17. 17. @crichardson About unit tests Test Class or cluster of classes Test Double Test Double Dependency Dependency Dependen Simulates dependency SUT
  18. 18. @crichardson Business logic Controller POST /something GET /something/id Database Database adapter Inbound Message Adapter Repository Service Entity Value object Outbound Message Adapter Unit test Unit test Unit test Saga <<Message Channel>> <<Message Channel>> Primary focus is the business logic “algorithms" Unit testing adapters is sometimes useful Maybe unit test coordination logic
  19. 19. @crichardson Unit test selectively http://blog.stevensanderson.com/2009/11/04/selective-unit-testing-costs-and-benefits/ Cost of unit testing = # dependencies Benefit of unit testing = non-obviousness High HighLow Low Algorithms Trivial code Coordinators Overly complex code (rewrite)
  20. 20. Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production Unit Integration Component End to End
  21. 21. About integration testing Inbound adapters: HTTP controller … Outbound adapters: HTTP proxy DAO Messaging adapter … Integration Test Adapter Verifies behavior Adapter Adapter AdapterAdapter Service
  22. 22. @crichardson Integration testing persistence code
  23. 23. @crichardson Inter-service dependencies integration testing
  24. 24. @crichardson Consumer-driven contract testing Verify that a service (a.k.a. provider) and its clients (a.k.a. consumers) can communicate while testing them in isolation
  25. 25. @crichardson Contract testing example Api Gateway Order Service Proxy Order Service Order Controller GET /orders/{id} ProviderConsumer
  26. 26. @crichardson Contract testing example Request from consumer Response from service Describes Written by API Gateway Team API definition by example Order Service Proxy Order Controller GET /orders/{id} ProviderConsumer
  27. 27. @crichardson Consumer-side contract test OrderService Proxy Order ServiceProxy Tests Use WireMock- based Order Service Test Double Configures Verify that proxy makes requests that match contract and can consume responses “service virtualization” GET /orders/{id}
  28. 28. @crichardson Provider-side contract test Class BaseHttp { } class HttpTest extends BaseHttp {… Spring Cloud Contract Code generates Reads Configures with mock OrderRepository Order Controller Tests Order Repository Must be consistent Verify API structure matches contracts GET /orders/{id}
  29. 29. @crichardson Assumption: If consumer and provider are tested independently with the same contracts Consumer and provider can communicate OrderService Proxy Order Controller Test Test
  30. 30. @crichardson Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production Unit Integration Component End to End
  31. 31. Goal of component testing Minimalist Verify that the container is deployable Passes health check … VS. Acceptance tests Real world/user focussed But avoid duplicating unit and integration tests Component Test Service Verifies behavior In isolation
  32. 32. @crichardson Test process (eg. JVM) In-process component testing In-memory database Test Some Service REST API Outbound adapter, eg. Service Proxy Mock IPC, e.g. RestTemplate/Messaging Some other service Messaging API Configures mocks
  33. 33. @crichardson
  34. 34. @crichardson Out-of-process component testing Real Database Test Some Service REST API Mock Other Service REST API Message Broker Configures mocks Separate process, e.g Docker container Exchanges messages
  35. 35. About WireMock: Mockito for HTTP servers http://wiremock.org/ @Test public void shouldProxyCreateOrder() { … stubFor(post(urlEqualTo("/orders")) .willReturn( aResponse() .withStatus(200) .withHeader("Content-Type", "application/json") .withBody(expectedResponse))); … verify(postRequestedFor( urlMatching("/orders"))); }
  36. 36. @crichardson Running out of process component tests: $ ./gradlew componentTest = @Before/@After
  37. 37. @crichardson In-process vs out-of-process Benefits Drawbacks In-process Simpler Faster Less realistic Out-of-process More realistic Slower More complex
  38. 38. @crichardson Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production Unit Integration Component End to End
  39. 39. @crichardson End to End testing verifies behavior of application End to End Test FTGO application Order Service Consumer
 Service … https://docs.cucumber.io/gherkin/
  40. 40. @crichardson Application Deployment pipeline Running end to end tests Order Service deployment pipeline Kitchen Service deployment pipeline Delivery Service deployment pipeline …. End to End tests Production
  41. 41. About scenario-based end-to- end testing Typically, BDD user scenarios = original requirements user focussed/real world Parallelization can accelerate testing BUT Duplicates tests lower down the pyramid Brittle, slow, complex Potential bottleneck that delays getting changes (e.g. bug fixes) into production Use selectively based on risk My Bank App Given … When … Then … Loan Repayment Calculator Loan Document Generator Slow External Service Bottleneck
  42. 42. @crichardson Replace end-to-end tests with per-service (component) tests My Bank App Given … When … Then … Loan Repayment Calculator Loan Document Generator Slow External Service My Bank App Loan Repayment Calculator Loan Document Generator Slow external Service Given … When … Then … Given … When … Then … Bottleneck only for Loan Document Generator
  43. 43. @crichardson Agenda Overview of testing microservices Unit testing Integration testing Component testing End to end testing Testing in production
  44. 44. @crichardson https://blogs.msdn.microsoft.com/seliot/2011/04/25/i-dont-always-test- my-code-but-when-i-do-i-do-it-in-production/
  45. 45. @crichardson Test environment != production Issues will appear in production
  46. 46. @crichardson Testing in production* Separate Deployment - running in production Release - available to users Test code Before releasing When releasing Automate for fast deployment, rollback and roll forward * a.k.a. Validation in production https://medium.com/@copyconstruct/testing-in-production-the-safe-way-18ca102d0ef1
  47. 47. Order Service V1 Order Service V2 Test deployed code before releasing: e.g. Canary release 1.Deploy V2 alongside V1 2.Test V2 3.Route test traffic to V2 4.Release V2 to a small % of production users 5.Monitor/test (latency, errors) - undo rollout if errors 6. Increase % of production traffic going to V2 7.Repeat until 100% of traffic going to V2 8.Eventually undeploy V1 Intelligent traffic router Order Service V1 Order Service V2 Monitoring system
  48. 48. Feature toggles/flags A toggle controls which of several code paths is used Release toggle - allow incomplete code to be safely committed/ deployed during trunk based development Ops toggles - enable Ops to enable/disable features Permissioning toggles - user attribute features/experience Experiment toggles - e.g. A/B testing https://martinfowler.com/articles/feature-toggles.html
  49. 49. @crichardson Summary Use the microservice architecture accelerate software delivery by improving testability and deployability Using microservices without automated testing is self-defeating AND risky Accelerate the deployment pipeline by pushing testing as far down the test pyramid as possible End-to-end tests: Use selectively Replace with per-service tests as much as possible Test in production for reliable deployments/releases
  50. 50. @crichardson @crichardson chris@chrisrichardson.net http://adopt.microservices.io Questions? 40% discount with code ctworaclecodeone19

×