Save 37% off PRO during our Black Friday Sale! »

Writing Test Driven Apps with http4k

Writing Test Driven Apps with http4k

Testing HTTP services can be a painful and challenging process for developers: tests are often slow running, involve complicated (or coupled) setup, rely on unreliable 3rd party dependencies, or deal with complicated outputs.

In this talk, the speakers will demonstrate how the http4k library leverages its "Server as a Function" roots to enable writing apps which can be test-driven at all levels of the Testing Pyramid, using a set of tools derived from decades of experience testing backend applications to make many of the above issues go away.

This talk is about Kotlin HTTP server technologies and how to test them to overcome problems (slow/flakey tests, lack of reuse, etc.). The audience gets an intro to the Server as a Function concept and http4k, but also can take away a lot of knowledge about how to apply the solutions to those problems in a unique and original way.

Ed250c56ee7dac44d90e5fdf712314f2?s=128

David Denton

June 17, 2020
Tweet

Transcript

  1. HTTP4K WRITING TEST-DRIVEN APPS WITH DAVID DENTON / IVAN SANCHEZ

  2. WRITING TEST-DRIVEN APPS WITH HTTP4K / WHAT PROBLEMS ARE WE

    TRYING TO SOLVE? ▸ Problems encountered in app development lifecycle: ▸ Slow test suites impact delivery speed / MTTR ▸ Flakey tests cause build instability ▸ Switching technologies impossible without ditching tests ▸ Duplication caused by different levels of pyramid UI INTEGRATION UNIT Can we write HTTP tests that won’t get in our way?
  3. WRITING TEST-DRIVEN APPS WITH HTTP4K / WHAT ARE THE CHARACTERISTICS

    OF A GOOD TEST? ▸ What makes a good test? ▸ Easy to write and maintain ▸ Quick & reliable to run ▸ Uncoupled to underlying technology ▸ Reusable in different contexts
  4. WRITING TEST-DRIVEN APPS WITH HTTP4K / WHAT YOU NEED TO

    KNOW ABOUT HTTP4K ▸ http4k == Server as a Function in Kotlin typealias HttpHandler = (Request) -> Response ▸ Uniform: HTTP server == HTTP Client ▸ HTTP Messages are immutable data classes ▸ Designed for Testability
  5. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEFINING OUR REQUIREMENTS ▸

    Writing an HTTP application to Analyse Sentences ▸ Endpoints: ▸ Valid word count in a sentence: POST to /count ▸ Record and report app hit count: GET to /calls ▸ Analyse the letter makeup of a sentence: POST to /analyse ▸ Utilise 3rd party Dictionary HTTP service
  6. STEPS 1-4

  7. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / DEFINING MIDDLEWARE

    WITH FILTERS ▸ Decorate HttpHandlers with Filter typealias Filter = (HttpHandler) -> HttpHandler val stack: Filter = logging.then(security) val app: HttpHandler = stack.then(httpHandler) ▸ Use to modify HTTP messages or Security, Logging etc.. ▸ They compose together into “stacks”:
  8. STEPS 5-6

  9. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / REUSABLE TEST

    CONTRACTS ▸ Service tests should be reusable ▸ Unit tests - entirely in memory ▸ Integration tests - running a live server ▸ We can extract a common test contract… TEST CONTRACT UNIT TEST INTEGRATION TEST val app: HttpHandler val app = SentenceAnalyser() val app = OkHttp()
  10. STEPS 7-9

  11. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / ANALYSING SENTENCES

    ▸ Provide JSON breakdown of character content in a submitted sentence INPUT OUTPUT { "breakdown":{ “a":2, "d":2, “i”:2, “n”:1, "v":2, } } POST /analyse BODY: david ivan
  12. STEP 10

  13. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / AUTO JSON

    FORMATTING WITH LENSES ▸ What is a Lens - it’s 2 functions! ▸ Represent JSON model objects as Kotlin data classes ▸ Lens creation: Inject<X>: (HttpMessage, X) -> HttpMessage Extract<X>: (HttpMessage) -> X val lens = Body.auto<Analysis>().toLens()
  14. STEP 11

  15. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / ABOUT THE

    DICTIONARY ▸ Use the dictionary service to validates words ▸ Lives at http://api.dictionary.com:10000/ ▸ Endpoint GET /{word} - returns 200 (valid) or 404 ▸ Create a domain client ▸ We can write a contract test to prove our usage
  16. STEP 13

  17. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / FAKING 3RD

    PARTY DEPENDENCIES ▸ 3rd party test services are slow and unreliable ▸ Create a simple stateful fake ▸ Can start this as a server ▸ Prove behaviour using reusable contract test ▸ Can add test cases to check failure modes DICTIONARY CONTRACT FAKE TEST REAL TEST val dict: HttpHandler val dict = FakeDictionary() val dict = OkHttp() + + Failure tests
  18. STEP 14

  19. STEP 15

  20. WRITING TEST-DRIVEN APPS WITH HTTP4K / WRAPPING UP ▸ What

    did we gain? ▸ Fast in memory tests - no port required! ▸ Reusable test code (no custom infrastructure!) ▸ 3rd party dependency problems mitigated: ▸ Flakey ▸ Can’t make them fail
  21. WRITING TEST-DRIVEN APPS WITH HTTP4K / DEVELOP / AND THERE’S

    MORE! ▸ http4k also supports: ▸ Chaos/failure mode testing with the ChaosEngine ▸ Service Virtualisation with Servirtium ▸ In-memory browser testing with WebDriver
  22. WRITING TEST-DRIVEN APPS WITH HTTP4K / FIN ivan@http4k.org @s4nchez david@http4k.org

    @daviddenton #questions quickstart: start.http4k.org web: www.http4k.org slack: #http4k @ kotlinlang @http4k source code: bit.ly/tdd_http4k_code