generate contextually sensible fuzz tests for servant apps
Go to file
2020-09-29 09:17:06 -04:00
.github/workflows update stack 2020-09-23 23:09:13 -04:00
app autogenerated stuff 2020-06-05 12:01:44 -04:00
scripts tidying up 2020-06-06 10:24:56 -04:00
src initial breakdown 2020-09-29 09:17:06 -04:00
test working through details of chewable dynamics 2020-09-26 17:49:36 -04:00
.gitignore cleaned up some type level stuff, added some type level bits 2020-08-08 18:46:09 -04:00
ChangeLog.md autogenerated stuff 2020-06-05 12:01:44 -04:00
LICENSE autogenerated stuff 2020-06-05 12:01:44 -04:00
Makefile revamp tests, change interface 2020-09-23 22:48:59 -04:00
package.yaml revamp tests, change interface 2020-09-23 22:48:59 -04:00
README.md split up todo/readme 2020-09-23 23:11:05 -04:00
roboservant.cabal break up Types into modules 2020-09-26 15:26:15 -04:00
Setup.hs autogenerated stuff 2020-06-05 12:01:44 -04:00
stack.yaml revamp tests, change interface 2020-09-23 22:48:59 -04:00
stack.yaml.lock revamp tests, change interface 2020-09-23 22:48:59 -04:00
TODO.md split up todo/readme 2020-09-23 23:11:05 -04:00

roboservant

Automatically fuzz your servant apis in a contextually-aware way.

CI

why?

Servant gives us a lot of information about what a server can do. We use this information to generate arbitrarily long request/response sessions and verify properties that should hold over them.

example

Our api under test:

newtype Foo = Foo Int
  deriving (Generic, Eq, Show, Typeable)
  deriving newtype (FromHttpApiData, ToHttpApiData)

type FooApi =
  "item" :> Get '[JSON] Foo
    :<|> "itemAdd" :> Capture "one" Foo :> Capture "two" Foo :> Get '[JSON] Foo
    :<|> "item" :> Capture "itemId" Foo :> Get '[JSON] ()

From the tests:

  assert "should find an error in Foo" . not
    =<< checkSequential (Group "Foo" [("Foo", RS.prop_sequential @Foo.FooApi Foo.fooServer)])

We have a server that blows up if the value of the int in a Foo ever gets above 10. Note: there is no generator for Foo types: larger Foos can only be made only by combining existing Foos with itemAdd. This is an important distinction, because many APIs will return UUIDs or similar as keys, which make it impossible to cover a useful section of the state space without using the values returned by the API

why not servant-quickcheck?

servant-quickcheck is a great package and I've learned a lot from it. Unfortunately, as mentioned previously, there's a lot of the state space you just can't explore without context: modern webapps are full of pointer-like structures, whether they're URLs or database keys/uuids, and servant-quickcheck requires that you be able to generate these without context via Arbitrary.