All Projects → rust-rspec → Rspec

rust-rspec / Rspec

Licence: mpl-2.0
(Rust) Rspec - a BDD test harness for stable Rust

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Rspec

kmtest
Kernel-mode C++ unit testing framework in BDD-style
Stars: ✭ 42 (-60.38%)
Mutual labels:  unit-testing, bdd
Spectrum
A BDD-style test runner for Java 8. Inspired by Jasmine, RSpec, and Cucumber.
Stars: ✭ 142 (+33.96%)
Mutual labels:  unit-testing, bdd
Ut
UT: C++20 μ(micro)/Unit Testing Framework
Stars: ✭ 507 (+378.3%)
Mutual labels:  unit-testing, bdd
chai-exclude
Exclude keys to compare from a deep equal operation with chai expect or assert.
Stars: ✭ 33 (-68.87%)
Mutual labels:  unit-testing, bdd
respect
RSpec inspired test framework for Reason/OCaml/Bucklescript.
Stars: ✭ 28 (-73.58%)
Mutual labels:  unit-testing, bdd
Codeception
Full-stack testing PHP framework
Stars: ✭ 4,401 (+4051.89%)
Mutual labels:  unit-testing, bdd
Jasmine Matchers
Write Beautiful Specs with Custom Matchers for Jest and Jasmine
Stars: ✭ 552 (+420.75%)
Mutual labels:  unit-testing, bdd
Quick
The Swift (and Objective-C) testing framework.
Stars: ✭ 9,303 (+8676.42%)
Mutual labels:  bdd
Scram
Probabilistic Risk Analysis Tool (fault tree analysis, event tree analysis, etc.)
Stars: ✭ 98 (-7.55%)
Mutual labels:  bdd
Saul
Experimental annotation-based javascript unit tests 🚀
Stars: ✭ 90 (-15.09%)
Mutual labels:  unit-testing
Netdumbster
netDumbster is a .Net Fake SMTP Server clone of the popular Dumbster
Stars: ✭ 88 (-16.98%)
Mutual labels:  unit-testing
React Redux Starter Kit
Modular starter kit for React+Redux+React Router projects.
Stars: ✭ 92 (-13.21%)
Mutual labels:  unit-testing
Airtap
Run TAP unit tests in 1789+ browsers.
Stars: ✭ 1,364 (+1186.79%)
Mutual labels:  unit-testing
Phpunit Json Assert
PHPUnit assertions for JSON documents
Stars: ✭ 90 (-15.09%)
Mutual labels:  unit-testing
Atoum
The modern, simple and intuitive PHP unit testing framework.
Stars: ✭ 1,382 (+1203.77%)
Mutual labels:  unit-testing
Bitsofbytes
Code and projects from my blog posts.
Stars: ✭ 89 (-16.04%)
Mutual labels:  unit-testing
Automation Arsenal
Curated list of popular Java and Kotlin frameworks, libraries and tools related to software testing, quality assurance and adjacent processes automation.
Stars: ✭ 105 (-0.94%)
Mutual labels:  unit-testing
Dd
Binary Decision Diagrams (BDDs) in pure Python and Cython wrappers of CUDD, Sylvan, and BuDDy
Stars: ✭ 102 (-3.77%)
Mutual labels:  bdd
Js Unit Testing Guide
📙 A guide to unit testing in Javascript
Stars: ✭ 1,346 (+1169.81%)
Mutual labels:  unit-testing
Cuckoo
Boilerplate-free mocking framework for Swift!
Stars: ✭ 1,344 (+1167.92%)
Mutual labels:  unit-testing

rspec - a BDD test harness that works with stable Rust

Build Status Coverage Status Crates.io Crates.io

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.

The last stable documentation is available for consultation at docs.rs/rspec.

How to use

Add this in your Cargo.toml:

[dev_dependencies]
rspec = "1.0"

and add this to your src/lib.rs or src/main.rs:

#[cfg(test)]
extern crate rspec;

You can see complete examples in the examples/ directory.

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:

Variant A Variant B Variant C
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

runner.run(&rspec::suite("opens a suite", /* environment */, |ctx| {
    ctx.context("opens a context", |ctx| {
        ctx.example("opens an example", |env| /* test condition */ );
    });
}));

Variant B: describe, specify & it

runner.run(&rspec::describe("opens a suite", /* environment */, |ctx| {
    ctx.specify("opens a context", |ctx| {
        ctx.it("opens an example", |env| /* test condition */ );
    });
}));

Variant C: given, when & then

runner.run(&rspec::given("opens a suite", /* environment */, |ctx| {
    ctx.when("opens a context", |ctx| {
        ctx.then("opens an example", |env| /* test condition */ );
    });
}));

Before & After

All Each
Before: before/before_all before_each
After: after /after_all after_each

All

The "All" variants of before and after blocks are executed once upon entering (or exiting, respectively) the given context.

Each

before_each and after_each blocks are executed once before each of the given context's sub-contexts or examples.

More Examples

Again, you can see complete examples in the examples/ directory.

Documentation

The last stable documentation is available for consultation at https://docs.rs/rspec.

Contributions

... are greatly welcome! Contributions follow the standard Github workflow, which is:

  1. Fork this repository
  2. Create a feature branch
  3. Code and commit inside this branch. I have a personnal preference for small atomic commits, but that's not a hard rule.
  4. Make sure you have written tests for your feature. If you don't know how to do that, push the PR with [WIP] in the title and we'll gladly help you.
  5. When tests are ok, and you features/bug fixes are covered, we will review the code together, make it better together.
  6. When everyone agrees that the code is right, and the tests pass, you will have the privilege to merge your PR and become a mighty Contributor. Congrats.

Take a look at the issues if you want to help without knowing how. Some issues are mentored!

Contributors

Beginners

About Rust

Welcome in the Rust community! Here are some links which can hopefully help:

About TDD

TDD, short for Tests Driven Development, is a methodology of development where your code is always working, where refactoring is easy, and you know exactly what piece of code do and what it doesn't.

With TDD, legacy code is limited, your build is always green and you don't have regresssions.

This is a wonderful and magical land, a well-keeped secret where only the best of the best are admitted, people who don't compromise on quality because they know the cost of the absence of quality. People who know that over-quality is a non-sense.

Here are some useful links:

About BDD

BDD, short for Behavior Driven Development, is a variation on TDD; some would say that BDD is simply TDD but refined.

BDD states that tests are not the center of the methodology. They are one of the most usefull tool available, but we should not look at them in too high regard. What matters is the contract they seal, the described behavior.

Thus, there is enough tests when the behavior of the struct is sufficiently described. Thinking in term of behavior has two benefits:

  • When doing TDD, it helps to make incremential steps. Just write examples of how to use the functions, and make this example pass, then go to the next one. Your tests will naturally have one clear intent, and so will be easy to debug / rely on when refactoring. This is the describe/it approach, which this crate hopes to fill.

  • By describing behavior, we are doing an analysis of our program. This analysis can be very useful! Say... an User Story, for example. Given the formalism As a X, When Y, I want Z, you can assign scenarii describing the high-level behavior of your units. The Gherkin formalism is often employed for this, it use a Given X, When Y, Then Z structure. This project does not aim to help on high-level BDD, see the cucumber for Rust port for that.

The foundation of BDD is well explained here and also here.

BDD written with the Gherkin formalism can really gain from a layer of DDD (Domain Driven Development), but this is another story....

Licence

Mozilla Public Licence 2.0. See the LICENCE file at the root of the repository.

In non legal terms it means that:

  • if you fix a bug, you MUST give back the code of the fix (it's only fair, see the Contributing Section).
  • if you change/extend the API, you MUST give back the code you changed in the files under MPL2. The Contributing Section can help there.
  • you CAN'T sue the authors of this project for anything about this code
  • appart from that, you can do almost whatever you want. See the LICENCE file for details.

This section DOES NOT REPLACE NOR COMPLETE the LICENCE files. The LICENCE file is the only place where the licence of this project is defined.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].