yesod-test- integration testing for WAI/Yesod Applications

Safe HaskellNone




Yesod.Test is a pragmatic framework for testing web applications built using wai and persistent.

By pragmatic I may also mean dirty. It's main goal is to encourage integration and system testing of web applications by making everything easy to test.

Your tests are like browser sessions that keep track of cookies and the last visited page. You can perform assertions on the content of HTML responses, using css selectors to explore the document more easily.

You can also easily build requests using forms present in the current page. This is very useful for testing web applications built in yesod for example, were your forms may have field names generated by the framework or a randomly generated _nonce field.

Your database is also directly available so you can use runDBRunner to set up backend pre-conditions, or to assert that your session is having the desired effect.


Declaring and running your test suite

yesodSpec :: YesodDispatch site => site -> YesodSpec site -> SpecSource

type YesodSpec site = Writer [YesodSpecTree site] ()Source

Corresponds to hspec's Spec.

Since 1.2.0

yesodSpecWithSiteGenerator :: YesodDispatch site => IO site -> YesodSpec site -> SpecSource

Same as yesodSpec, but instead of taking already built site it takes an action which produces site for each test.

type YesodExample site = StateT (YesodExampleData site) IOSource

A single test case, to be run with yit.

Since 1.2.0

data YesodSpecTree site Source

Internal data structure, corresponding to hspec's YesodSpecTree.

Since 1.2.0

ydescribe :: String -> YesodSpec site -> YesodSpec siteSource

Start describing a Tests suite keeping cookies and a reference to the tested Application and ConnectionPool

yit :: String -> YesodExample site () -> YesodSpec siteSource

Describe a single test that keeps cookies, and a reference to the last response.

Making requests

To make a request you need to point to an url and pass in some parameters.

To build your parameters you will use the RequestBuilder monad that lets you add values, add files, lookup fields by label and find the current nonce value and add it to your request too.

get :: (Yesod site, RedirectUrl site url) => url -> YesodExample site ()Source

Perform a GET request to url, using params

post :: (Yesod site, RedirectUrl site url) => url -> YesodExample site ()Source

Perform a POST request to url

postBody :: (Yesod site, RedirectUrl site url) => url -> ByteString -> YesodExample site ()Source

Perform a POST request to url with sending a body into it.

request :: Yesod site => RequestBuilder site () -> YesodExample site ()Source

General interface to performing requests, allowing you to add extra headers as well as letting you specify the request method.

addPostParam :: Text -> Text -> RequestBuilder site ()Source

Add a parameter with the given name and value.

addFile :: Text -> FilePath -> Text -> RequestBuilder site ()Source

Add a file to be posted with the current request

Adding a file will automatically change your request content-type to be multipart/form-data

setRequestBody :: Yesod site => ByteString -> RequestBuilder site ()Source

Simple way to set HTTP request body

type RequestBuilder site = StateT (RequestBuilderData site) IOSource

The RequestBuilder state monad constructs an url encoded string of arguments to send with your requests. Some of the functions that run on it use the current response to analize the forms that the server is expecting to receive.

setUrl :: (Yesod site, RedirectUrl site url) => url -> RequestBuilder site ()Source

Yesod can auto generate field ids, so you are never sure what the argument name should be for each one of your args when constructing your requests. What you do know is the label of the field. These functions let you add parameters to your request based on currently displayed label names.

Does the current form have a _nonce? Use any of these to add it to your request parameters.

addNonce :: RequestBuilder site ()Source

For responses that display a single form, just lookup the only nonce available.

addNonce_ :: Query -> RequestBuilder site ()Source

Lookup a _nonce form field and add it's value to the params. Receives a CSS selector that should resolve to the form element containing the nonce.


assertEqual :: Eq a => String -> a -> a -> YesodExample site ()Source

Asserts that the two given values are equal.

assertHeader :: CI ByteString -> ByteString -> YesodExample site ()Source

Assert the given header key/value pair was returned.

assertNoHeader :: CI ByteString -> YesodExample site ()Source

Assert the given header was not included in the response.

statusIs :: Int -> YesodExample site ()Source

Assert the last response status is as expected.

bodyEquals :: String -> YesodExample site ()Source

Assert the last response is exactly equal to the given text. This is useful for testing API responses.

bodyContains :: String -> YesodExample site ()Source

Assert the last response has the given text. The check is performed using the response body in full text form.

htmlAllContain :: Query -> String -> YesodExample site ()Source

Queries the html using a css selector, and all matched elements must contain the given string.

htmlAnyContain :: Query -> String -> YesodExample site ()Source

Queries the html using a css selector, and passes if any matched element contains the given string.

Since 0.3.5

htmlCount :: Query -> Int -> YesodExample site ()Source

Performs a css query on the last response and asserts the matched elements are as many as expected.

Grab information

getTestYesod :: YesodExample site siteSource

Get the foundation value used for the current test.

Since 1.2.0

getResponse :: YesodExample site (Maybe SResponse)Source

Get the most recently provided response value, if available.

Since 1.2.0

Debug output

printBody :: YesodExample site ()Source

Outputs the last response body to stderr (So it doesn't get captured by HSpec)

printMatches :: Query -> YesodExample site ()Source

Performs a CSS query and print the matches to stderr.

Utils for building your own assertions

Please consider generalizing and contributing the assertions you write.

htmlQuery :: Query -> YesodExample site [HtmlLBS]Source

Query the last response using css selectors, returns a list of matched fragments

parseHTML :: HtmlLBS -> CursorSource

Use HXT to parse a value from an html tag. Check for usage examples in this module's source.

withResponse :: (SResponse -> YesodExample site a) -> YesodExample site aSource

Performs a given action using the last response. Use this to create response-level assertions