15. Testing the wire-server Haskell code base

Every package in this repository should have one or more directories named test or test*. Ideally, there are at least unit tests (eg. in test/unit) for libraries, and and at least unit and integration tests (eg. test/integration) for packages with executables (/services).

15.1. General rule

Write as much pure code as possible. If you write a function that has an effect only in a small part of its implementation, write a pure function instead, and call if from an effectful function.

15.2. Unit tests

All data types that are serialized (ToByteString, ToByteString, swagger, cassandra, …) should have roundtrip quickcheck tests like here. All pure functions f that do something interesting should have a couple of tests of the form shouldBe (f <args>) <result> to cover corner cases. If code is refactored, all the effects should be mocked with polysemy or mtl, the old implementation should be moved to the test suite, and there should be quickcheck tests running the new implementation against the old and comparing results (example).

15.3. Integration tests

  • All new rest API end-points need to be called a few times to cover as much of the corner cases as feasible.

  • We have machinery to set up scaffolding teams and modify context such as server configuration files where needed. Look through the existing code for inspiration.

  • Test only semantics, not syntax: do not post verbatim json to an end-point, but use the Haskell data types to render the json that you post.