Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/reem/stainless

Organized, flexible testing framework for Rust
https://github.com/reem/stainless

Last synced: 3 months ago
JSON representation

Organized, flexible testing framework for Rust

Lists

README

        

# Stainless [![Build Status](https://travis-ci.org/reem/stainless.svg?branch=master)](https://travis-ci.org/reem/stainless)

> Stainless is a lightweight, flexible, unopinionated testing framework.

**Note that stainless currently requires the nightly version of the Rust compiler!**

## This project is unmaintained

Users are advised to use [speculate.rs](https://github.com/utkarshkukreti/speculate.rs) instead which implements a similar idea.

## Installation

Add stainless as a dependency in your `Cargo.toml` file
``` toml
[dev-dependencies]
stainless = "*"
```

Add the following lines to the top of your
[root module](https://doc.rust-lang.org/book/crates-and-modules.html).
That file is normally called `src/main.rs` for executables and
`src/lib.rs` for libraries:

``` rust
#![feature(plugin)]
#![cfg_attr(test, plugin(stainless))]
```

This will make stainless available when you run the tests using `cargo
test`.
When using stainless only with a library, make sure to run tests using
`cargo test --lib`.

## Overview

Stainless exports the `describe!` syntax extension, which allows you
to quickly generate complex testing hierarchies and reduce boilerplate
through `before_each` and `after_each`.

Stainless currently supports the following types of subblocks:
- `before_each` and `after_each`
- `it`, `failing`, and `ignore`
- `bench`
- nested `describe!`

`before_each` and `after_each` allow you to group common
initialization and teardown for a group of tests into a single block,
shortening your tests.

`it` generates tests which use `before_each` and `after_each`.
`failing` does the same, except the generated tests are marked with
`#[should_panic]`. It optionally takes an argument which is matched against the
failure message. `ignore` is equivalent to marking a test with `#[ignore]` which
disables the test by default.

`bench` allows you to generate benchmarks in the same fashion, though
*`before_each` and `after_each` blocks do not currently affect `bench`
blocks*.

Nested `describe!` blocks allow you to better organize your tests into
small units and gives you granular control over where `before_each`
and `after_each` apply. Of course the `before_each` and `after_each`
blocks of the wrapping `describe!` blocks are executed as well.

Together, these 4 types of subblocks give you more flexibility and
control than the built in testing infrastructure.

## Example

```rust
describe! stainless {
before_each {
// Start up a test.
let mut stainless = true;
}

it "makes organizing tests easy" {
// Do the test.
assert!(stainless);
}

after_each {
// End the test.
stainless = false;
}

bench "something simple" (bencher) {
bencher.iter(|| 2 * 2)
}

describe! nesting {

before_each {
let mut inner_stainless = true;
}

after_each {
inner_stainless = false;
}

it "makes it simple to categorize tests" {
// It even generates submodules!
assert_eq!(2, 2);
}
}
}
```

Expands to (roughly):

```rust
mod stainless {
#[test]
fn makes_organizing_tests_easy() {
let mut stainless = true;
assert!(stainless);
stainless = false;
}

#[bench]
fn something_simple(bencher: &mut test::Bencher) {
bencher.iter(|| 2 * 2)
}

mod nesting {
#[test]
fn makes_it_simple_to_categorize_tests() {
let mut stainless = true;
let mut inner_stainless = true;
assert_eq!(2, 2);
inner_stainless = false;
stainless = false;
}
}
}
```

## Importing modules

At this point it is not possible to put `use` statements inside the
`describe!` blocks. To allow usage of data structures from other
modules and crates each `describe!` block comes with a silent `pub use
super::*;` in it. That way everything you `pub use` in the containing
module is available in your tests.

```rust
#[cfg(test)]
mod tests {
pub use std::collections::HashMap;

describe! stainless {
it "can use HashMap" {
let map = HashMap::new();
}
}
}
```

## License

MIT. See the LICENSE file for details.

## Authors

See Cargo.toml for the full list of authors.