Skip to content

Black-box integration tests for your REST API using the Rust and its test framework

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

iomentum/restest

Repository files navigation

restest

Black-box integration test for REST APIs in Rust.

restest provides primitives that allow to write REST API in a declarative manner. It leverages the Rust test framework and uses macro-assisted pattern tho assert for a pattern and add specified variables to scope.

Adding to the Cargo.toml

restest provides test-only code. As such, it can be added as a dev-dependency:

[dev-dependencies]
restest = "0.1.0"

Example

use restest::{assert_body_matches, path, Context, Request};

use serde::{Deserialize, Serialize};
use http::StatusCode;

const CONTEXT: Context = Context::new().with_port(8080);

let request = Request::post(path!["user/ghopper"]).with_body(PostUser {
    year_of_birth: 1943,
});

let body = CONTEXT
    .run(request)
    .await
    .expect_status(StatusCode::OK)
    .await;

assert_body_matches! {
    body,
    User {
        year_of_birth: 1943,
        ..
    }
}

struct PostUser {
    year_of_birth: usize,
}

struct User {
    year_of_birth: usize,
    id: Uuid
}

Writing tests

Writing tests using restest always follow the same patterns. They are described below.

Specifying the context

The Context object handles all the server-specific configuration:

  • which base URL should be used,
  • which port should be used.

It can be created with Context::new. All its setters are const, so it can be initialized once for all the tests of a module:

use restest::Context;

const CONTEXT: Context = Context::new().with_port(8080);

async fn test_first_route() {
    // Test code that use `CONTEXT` for a specific route
}

async fn test_second_route() {
    // Test code that use `CONTEXT` again for another route
}

As we're running async code under the hood, all the tests must be async, hence the use of tokio::test

Creating a request

Let's focus on the test function itself.

The first thing to do is to create a Request object. This object allows to specify characteristics about a specific request that is performed later.

Running Request::get allows to construct a GET request to a specific URL. Header keys can be specified by calling the with_header method. The final Request is built by calling the with_body method, which allows to add a body.

use restest::{path, Request};

let request = Request::get(path!["users", "scrabsha"])
    .with_header("token", "mom-said-yes")
    .with_body(());

Similarly, POST requests can be creating by using [Request::post] instead of [Request::get].

Performing the request

Once that the Request object has been created, we can run the request by passing the Request to the Context when calling Context::run. Once await-ed, the expect_status method checks for the request status code and converts the response body to the expected output type.

use http::StatusCode;
use uuid::Uuid;
use serde::Deserialize;

let user: User = CONTEXT
    .run(request)
    .await
    .expect_status(StatusCode::OK)
    .await;

struct User {
    name: String,
    age: u8,
    id: Uuid,
}

Checking the response body

Properties about the response body can be asserted with assert_body_matches. The macro supports the full rust pattern syntax, making it easy to check for expected values and variants. It also provides bindings, allowing you to bring data from the body in scope:

use restest::assert_body_matches;

assert_body_matches! {
    user,
    User {
        name: "Grace Hopper",
        age: 85,
        id,
    },
}

// id is now a variable that can be used:
println!("Grace Hopper has id `{}`", id);

The extracted variable can be used for next requests or more complex testing.

And that's it!

About

Black-box integration tests for your REST API using the Rust and its test framework

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages