Assertions

Grillon provides domain-specific language per protocol and framework to make it natural to write assertions.

An assertion is made up of:

  • A part under test like status,
  • a predicate such as is, is_not,
  • and an expected value, for example 200.

The predicates of a specific part can handle different type parameters. For example if you want to assert that a status code is 200, you can pass a u16 or a StatusCode. This information is described below in the types column.

Execution order

Your assertions are executed sequentially and in a blocking fashion. Asynchronous executions are not supported yet. With sequential runs, order matters, so if you want to fail early under specific conditions, it's possible. Each assertion produces logs.

HTTP assertion table

partpredicatestypes
headersis, is_not, contains, does_not_containVec<(HeaderName, HeaderValue)>, Vec<(&str, &str)>, HeaderMap
headeris, is_notString, &str, HeaderValue
statusis, is_not, is_betweenu16, StatusCode
json_bodyis, is_not, schemaString, &str, Value, json!, PathBuf
json_pathis, is_not, schema, contains, does_not_contain, matches, does_not_matchString, &str, Value, json!, PathBuf
response_timeis_less_thanu64

Note about json_path

Json path requires one more argument than other predicates because you have to provide a path. The expected value should always be a valid json representation. To enforce this the provided value is always converted to a Value.

Here is an example of a json path assertion, where we are testing the value under the path $[0].id.

#[tokio::test]
async fn test_json_path() -> Result<()> {
    Grillon::new("https://jsonplaceholder.typicode.com")?
        .get("posts?id=1")
        .assert()
        .await
        .json_path("$[0].id", is(json!(1)))
        .json_path("$[0].id", is("1"));

    Ok(())
}

Custom assertions

You may need to create more complex assertions or have more control on what is executed as part of an assertion. If so, the library provides a specific function, assert_fn, allowing you to write your own logic.

Grillon::new("https://jsonplaceholder.typicode.com")?
    .post("posts")
    .payload(json!({
        "title": "foo",
        "body": "bar",
        "userId": 1
    }))
    .assert()
    .await
    .status(is_success())
    .assert_fn(|assert| {
        assert!(!assert.headers.is_empty());
        assert!(assert.status == StatusCode::CREATED);
        assert!(assert.json.is_some());

        println!("Json response : {:#?}", assert.json);
    });

With this function you can access the Assert structure which is the internal representation of an http response under test. You should have access to all parts that Grillon supports (headers, status, json, etc.). It's also possible to add your own stdout logs if you want more control over the results or need to debug what you receive.