Code Monkey home page Code Monkey logo

dredd-hooks-rust's Introduction

dredd-hooks-rust โ€ข Dredd HTTP API testing integration for Rust

Build Status Crates.io docs.rs License

This package contains a Rust Dredd hook handler which provides a bridge between the Dredd API Testing Framework and Rust environment to ease implementation of testing hooks provided by Dredd. Write Dredd hooks in Rust to glue together API Blueprint with your Rust project.

Not sure what these Dredd Hooks are? Read the Dredd documentation on them.

The following are a few examples of what hooks can be used for:

  • loading db fixtures
  • cleanup after test step or steps
  • handling authentication and sessions
  • passing data between transactions (saving state from responses to stash)
  • modifying request generated from blueprint
  • changing generated expectations
  • setting custom expectations
  • debugging via logging stuff

Installation

Global installation

If you don't have it already, install the Dredd CLI via npm:

npm install -g dredd

In order for the Dredd CLI to be able to interface with your test binaries, you need to have the dredd-hooks-rust binary installed, which you can get by running:

# This will install both `dredd-hooks-rust` and `cargo-dredd`
cargo install dredd-hooks

Per-project setup

To start testing your Rust project with Dredd, just add dredd-hooks to your Cargo.toml:

[dependencies]
dredd-hooks = "0.3.0"

Or if you have cargo-edit installed you can just run this on the command line:

cargo add dredd-hooks

Quickstart example

Following this is a short example showcasing Dredd tests running against an iron server.

The name of the project in this example is assumed to be dredd-rust-test:

test.apib

# My Api
## GET /message
+ Response 200 (text/plain)
    Hello World!

main.rs:

extern crate iron;
extern crate router;
extern crate dredd_hooks;

use iron::prelude::*;
use router::Router;
use dredd_hooks::{HooksServer};

// HTTP endpoint
fn endpoint(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((iron::status::Ok, "Hello World!\n\n")))
}

fn main() {
    let mut hooks = HooksServer::new();
    // Start the server before any of the tests are running.
    hooks.before_all(Box::new(|tr| {
        ::std::thread::spawn(move || {
            let mut router = Router::new();
            router.get("/message", endpoint, "endpoint");

            Iron::new(router).http("127.0.0.1:3000").unwrap();
        });
        tr
    }));
    // Execute a hook before a specific test.
    hooks.before("/message > GET", Box::new(|mut tr| {
        // Set the skip flag on this test.
        // Comment out the next line and you should see a passing test.
        tr.insert("skip".to_owned(), true.into());

        tr
    }));
    HooksServer::start_from_env(hooks);
}

Run the command:

cargo build && dredd ./test.apib http://127.0.0.1:3000 --language=dredd-hooks-rust --hookfiles=target/debug/dredd-rust-test

You should now see Dredd trying to run the tests against the binary that was just compiled, but actually skipping the single test it tries to run because we told Dredd to do so via a before hook.

Project setup

The quickstart example above assumes that the hookfile is compiled as a bin target. However, in most projects, you will probably want to have a more robust setup that looks like this:

Cargo.toml:

[[test]]
name = "dredd_test_hooks"
path = "tests/dredd/hooks.rs"
test = false
harness = false

[package.metadata.dredd_hooks]
hook_targets = ["dredd_test_hooks"]

Setting the test value to false, is needed so that our blocking hookserver doesn't interfere with the other tests when running cargo test. Setting the harness to false will result in the test binary being compiled without a test harness, because we already have dredd as our test harness.

Finally the values under package.metadata.dredd_hooks give us some additional metadata about our test setup, which allows us to use the cargo dredd command to simplify the invocation:

cargo dredd ./test.apib http://127.0.0.1:3000

License

Licensed under either of

at your option.

Acknowledgements

Thank you to:

dredd-hooks-rust's People

Contributors

hobofan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dredd-hooks-rust's Issues

Add cargo-dredd cargo subcommand

I think a dedicated cargo subcommand could make working with Dredd more comfortable.

Currently to run the test you have to rune something along the lines:

cargo build --test dredd_tests
dredd blueprint.apib http://127.0.0.1:3000 --language=rust --hookfiles=target/debug/dredd_tests-da753c1dc5b4e740

The length of the commands grows with number of hookfiles, and the compiled binaries also have an unwiedly hash appended to the end of them.

With a subcommand this could be reduced to:

cargo dredd blueprint.apib http://127.0.0.1:3000

or even less.

I think we could store the targets that should be included as hookfiles under the package.metadata.dredd_hooks field in the Cargo.toml

It might also be possible to cut down the required configuration for a hookfile target in the Cargo.toml when it is compiled via the subcomand by incejcting some build arguments, so

[[test]]
name = "dredd_test_hooks"
path = "tests/dredd/hooks.rs"
test = false
harness = false

turns into

[[test]]
name = "dredd_test_hooks"
path = "tests/dredd/hooks.rs"

Difficulties setting up dredd-hooks-rust in existing project

Hey,

First of all, thanks for setting this up!

I found myself here after following https://dredd.org/en/latest/hooks/rust.html#hooks-rust and trying add it to an exiting project. Following that + the Readme here, I've been trying to setup dredd hooks into an existing project, but I'm running into some issues:

  1. Running cargo install dredd-hooks ends with
.....
Compiling tokio-proto v0.1.1
   Compiling dredd-hooks v0.3.0
    Finished release [optimized] target(s) in 9.51s
error: no binaries are available for install using the selected features

Which I think eventually leads to problems when trying to run cargo dredd:

cargo dredd <openapicontract.yml> http://127.0.0.1:8000
error: no such subcommand: `dredd`

	Did you mean `tree`?
  1. I've added the sections toCargo.toml as describe in the Readme here, but I'm not sure how to build a binary from just the hooks file. (could be I'm still farily new to Rust)
[[test]]
name = "dredd_test_hooks"
path = "tests/dredd/hooks.rs"
test = false
harness = false

[package.metadata.dredd_hooks]
hook_targets = ["dredd_test_hooks"]

The hooks file is the one from the examples folder here just to help the initial setup.


Edit: Forgot to mention, while I see that the last commits are from 2017, I assume it works as expected and didn't need changes ๐Ÿ˜„

Also trying to install via:

cargo install dredd-hooks --features binaries

fails with

......
error: failed to run custom build command for `openssl v0.9.24`
......
......
 --- stderr
  thread 'main' panicked at 'Unable to detect OpenSSL version'
......

Enhance Transaction type

It would be nice to add a sort of builder pattern to the Transaction type, so common modifications can be done more ergonomically.

E.g. skipping a transaction could turn from

tr.insert("skip".to_owned(), true.into());

into

tr.set_skip(true);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.