Skip to main content

Crate spectacular

Crate spectacular 

Source
Expand description

An RSpec-inspired test framework for Rust with stackable before/after hooks.

Spectacular provides three layers of test hooks that stack in a predictable order:

LayerRuns once per…Runs per test
Suitebinary (before)test (before_each / after_each)
Groupgroup (before / after)test (before_each / after_each)
Testthe test body

§Hook Execution Order

For each test in a group that opts into suite hooks:

suite::before          (Once — first test in binary triggers it)
  group::before        (Once — first test in group triggers it)
    suite::before_each
      group::before_each
        TEST
      group::after_each
    suite::after_each
  group::after         (countdown — last test in group triggers it)

Groups without suite; skip the suite layer entirely.

§Quick Start

use spectacular::spec;

spec! {
    mod arithmetic {
        it "adds two numbers" {
            assert_eq!(2 + 2, 4);
        }

        it "multiplies two numbers" {
            assert_eq!(3 * 7, 21);
        }
    }
}

§Group Hooks

use spectacular::spec;
use std::sync::atomic::{AtomicBool, Ordering};

static READY: AtomicBool = AtomicBool::new(false);

spec! {
    mod with_hooks {
        use super::*;

        before { READY.store(true, Ordering::SeqCst); }

        it "runs after setup" {
            assert!(READY.load(Ordering::SeqCst));
        }
    }
}

§Suite Hooks (3-Layer)

Place suite! as a sibling of your test groups, then opt in with suite; (in spec!) or #[test_suite(suite)] (attribute style):

use spectacular::{suite, spec};
use std::sync::atomic::{AtomicBool, Ordering};

static DB_READY: AtomicBool = AtomicBool::new(false);

suite! {
    before { DB_READY.store(true, Ordering::SeqCst); }
}

spec! {
    mod database_tests {
        use super::*;
        suite;

        it "has database access" {
            assert!(DB_READY.load(Ordering::SeqCst));
        }
    }
}

§Attribute Style

For those who prefer standard Rust attribute syntax:

use spectacular::{test_suite, test_case, before};

#[test_suite]
mod my_tests {
    #[before]
    fn setup() { }

    #[test_case]
    fn it_works() {
        assert_eq!(1 + 1, 2);
    }
}

Modules§

prelude
Convenience re-export of all spectacular macros.

Macros§

spec
Defines a test group using RSpec-style DSL.
suite
Defines suite-level hooks that run across all opted-in test groups.

Attribute Macros§

after
Marks a function as a once-per-group teardown hook inside a #[test_suite] module.
after_each
Marks a function as a per-test teardown hook inside a #[test_suite] module.
before
Marks a function as a once-per-group setup hook inside a #[test_suite] module.
before_each
Marks a function as a per-test setup hook inside a #[test_suite] module.
test_case
Marks a function as a test case inside a #[test_suite] module.
test_suite
Marks a module as a test suite using standard Rust attribute syntax.