# rspec - a BDD test harness that works with stable Rust
[](https://travis-ci.org/rust-rspec/rspec) [](https://coveralls.io/github/rust-rspec/rspec) [](https://crates.io/crates/rspec) [](https://github.com/rust-rspec/rspec/blob/master/LICENSE)
When you like BDD, and all the nested `describe/context/it` way of testing, but
you also like when your code compiles every day 👌.
If you don't know what is Rust, are confused by the terms BDD, TDD, or just want
a gently beginner introduction, [please go to the Beginner Section](#beginners).
The last stable documentation is available for consultation at
[docs.rs/rspec](https://docs.rs/rspec).
## How to use
Add this in your `Cargo.toml`:
```toml
[dev_dependencies]
rspec = "1.0"
```
and add this to your `src/lib.rs` or `src/main.rs`:
```rust
#[cfg(test)]
extern crate rspec;
```
You can see complete examples in the [`examples/`](https://github.com/rust-rspec/rspec/tree/master/examples) directory.
```rust
extern crate rspec;
pub fn main() {
// Use a local struct to provide the test contexts with an environment.
// The environment will contain the subject that is to be tested
// along with any additional data you might need during the test run:
#[derive(Clone, Default, Debug)]
struct Environment {
// ...
}
// `rspec::run(…)` is a convenience wrapper that takes care of setting up
// a runner, logger, configuration and running the test suite for you.
// If you want more direct control, you can manually set up those things, too.
rspec::run(&rspec::describe("rspec, a BDD testing framework", Environment::default(), |ctx| {
// `describe`, or any of its equivalents, opens the root context
// of your test suite. Within you can then either define test examples:
ctx.it("can define top-level tests", |_| true);
// or make use of sub-contexts to add some structure to your test suite:
ctx.specify("contexts give your tests structure and reduce redundancy", |ctx| {
ctx.before(|_| {
// Executed once, before any of the contexts/examples is entered.
});
ctx.after(|_| {
// Executed once, after all of the contexts/examples have been exited.
});
ctx.specify("rspec can handle results", |ctx| {
ctx.it("passes if the return is_ok()", |_| Ok(()) as Result<(),()>);
ctx.it("failes if the return is_err()", |_| Err(()) as Result<(),()>);
});
ctx.specify("rspec can handle bools", |ctx| {
ctx.it("should pass if true", |_| true);
ctx.it("should fail if false", |_| false);
ctx.it("is convenient for comparisons", |_| (42 % 37 + 2) > 3);
});
ctx.specify("rspec can handle units", |ctx| {
ctx.it("should pass if the return is ()", |_| {});
});
ctx.specify("rspec can handle panics", |ctx| {
ctx.it("is convenient for asserts", |_| assert_eq!(1, 1));
});
});
})); // exits the process with a failure code if one of the tests failed.
}
```
### Suites, Contexts & Examples
rspec provides three variants for each of the structural elements:
| Suites: | `suite` | `describe` | `given` |
| Contexts: | `context` | `specify` | `when` |
| Examples: | `example` | `it` | `then` |
**Note:** While the intended use is to stick to a single variant per test suite
it is possible to freely mix structural elements across variants.
#### Variant A: `suite`, `context` & `example`
```rust
```rust