{"id":15284328,"url":"https://github.com/rust-rspec/rspec","last_synced_at":"2025-04-04T11:16:13.327Z","repository":{"id":45369537,"uuid":"59903073","full_name":"rust-rspec/rspec","owner":"rust-rspec","description":"(Rust) Rspec - a BDD test harness for stable Rust","archived":false,"fork":false,"pushed_at":"2022-10-02T12:52:55.000Z","size":8143,"stargazers_count":173,"open_issues_count":14,"forks_count":23,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T10:09:55.210Z","etag":null,"topics":["bdd","bdd-test-harness","rust","unit-testing"],"latest_commit_sha":null,"homepage":"https://rust-rspec.github.io/rspec/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rust-rspec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-28T16:10:56.000Z","updated_at":"2025-02-04T20:50:42.000Z","dependencies_parsed_at":"2022-09-05T07:10:27.190Z","dependency_job_id":null,"html_url":"https://github.com/rust-rspec/rspec","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-rspec%2Frspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-rspec%2Frspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-rspec%2Frspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-rspec%2Frspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rust-rspec","download_url":"https://codeload.github.com/rust-rspec/rspec/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166169,"owners_count":20894654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","bdd-test-harness","rust","unit-testing"],"created_at":"2024-09-30T14:53:35.670Z","updated_at":"2025-04-04T11:16:13.310Z","avatar_url":"https://github.com/rust-rspec.png","language":"Rust","readme":"# rspec - a BDD test harness that works with stable Rust\n\n[![Build Status](https://travis-ci.org/rust-rspec/rspec.svg?branch=master)](https://travis-ci.org/rust-rspec/rspec) [![Coverage Status](https://coveralls.io/repos/github/rust-rspec/rspec/badge.svg)](https://coveralls.io/github/rust-rspec/rspec) [![Crates.io](https://img.shields.io/crates/v/rspec.svg?maxAge=2592000)](https://crates.io/crates/rspec) [![Crates.io](https://img.shields.io/crates/l/rspec.svg?maxAge=2592000)](https://github.com/rust-rspec/rspec/blob/master/LICENSE)\n\nWhen you like BDD, and all the nested `describe/context/it` way of testing, but\nyou also like when your code compiles every day 👌.\n\nIf you don't know what is Rust, are confused by the terms BDD, TDD, or just want\na gently beginner introduction, [please go to the Beginner Section](#beginners).\n\nThe last stable documentation is available for consultation at\n[docs.rs/rspec](https://docs.rs/rspec).\n\n## How to use\n\nAdd this in your `Cargo.toml`:\n\n```toml\n[dev_dependencies]\nrspec = \"1.0\"\n```\n\nand add this to your `src/lib.rs` or `src/main.rs`:\n\n```rust\n#[cfg(test)]\nextern crate rspec;\n```\n\nYou can see complete examples in the [`examples/`](https://github.com/rust-rspec/rspec/tree/master/examples) directory.\n\n```rust\nextern crate rspec;\n\npub fn main() {\n    // Use a local struct to provide the test contexts with an environment.\n    // The environment will contain the subject that is to be tested\n    // along with any additional data you might need during the test run:\n    #[derive(Clone, Default, Debug)]\n    struct Environment {\n        // ...\n    }\n\n    // `rspec::run(…)` is a convenience wrapper that takes care of setting up\n    // a runner, logger, configuration and running the test suite for you.\n    // If you want more direct control, you can manually set up those things, too.\n    rspec::run(\u0026rspec::describe(\"rspec, a BDD testing framework\", Environment::default(), |ctx| {\n        // `describe`, or any of its equivalents, opens the root context\n        // of your test suite. Within you can then either define test examples:\n        ctx.it(\"can define top-level tests\", |_| true);\n\n        // or make use of sub-contexts to add some structure to your test suite:\n        ctx.specify(\"contexts give your tests structure and reduce redundancy\", |ctx| {\n            ctx.before(|_| {\n                // Executed once, before any of the contexts/examples is entered.\n            });\n\n            ctx.after(|_| {\n                // Executed once, after all of the contexts/examples have been exited.\n            });\n\n            ctx.specify(\"rspec can handle results\", |ctx| {\n                ctx.it(\"passes if the return is_ok()\", |_| Ok(()) as Result\u003c(),()\u003e);\n                ctx.it(\"failes if the return is_err()\", |_| Err(()) as Result\u003c(),()\u003e);\n            });\n\n            ctx.specify(\"rspec can handle bools\", |ctx| {\n                ctx.it(\"should pass if true\", |_| true);\n                ctx.it(\"should fail if false\", |_| false);\n                ctx.it(\"is convenient for comparisons\", |_| (42 % 37 + 2) \u003e 3);\n            });\n\n            ctx.specify(\"rspec can handle units\", |ctx| {\n                ctx.it(\"should pass if the return is ()\", |_| {});\n            });\n\n            ctx.specify(\"rspec can handle panics\", |ctx| {\n                ctx.it(\"is convenient for asserts\", |_| assert_eq!(1, 1));\n            });\n        });\n    })); // exits the process with a failure code if one of the tests failed.\n}\n```\n\n### Suites, Contexts \u0026 Examples\n\nrspec provides three variants for each of the structural elements:\n\n|           | Variant A | Variant B  | Variant C |\n| --------- | --------- | ---------- | --------- |\n| Suites:   | `suite`   | `describe` | `given`   |\n| Contexts: | `context` | `specify`  | `when`    |\n| Examples: | `example` | `it`       | `then`    |\n\n**Note:** While the intended use is to stick to a single variant per test suite\nit is possible to freely mix structural elements across variants.\n\n#### Variant A: `suite`, `context` \u0026 `example`\n\n```rust\nrunner.run(\u0026rspec::suite(\"opens a suite\", /* environment */, |ctx| {\n    ctx.context(\"opens a context\", |ctx| {\n        ctx.example(\"opens an example\", |env| /* test condition */ );\n    });\n}));\n```\n\n#### Variant B: `describe`, `specify` \u0026 `it`\n\n```rust\nrunner.run(\u0026rspec::describe(\"opens a suite\", /* environment */, |ctx| {\n    ctx.specify(\"opens a context\", |ctx| {\n        ctx.it(\"opens an example\", |env| /* test condition */ );\n    });\n}));\n```\n\n#### Variant C: `given`, `when` \u0026 `then`\n\n```rust\nrunner.run(\u0026rspec::given(\"opens a suite\", /* environment */, |ctx| {\n    ctx.when(\"opens a context\", |ctx| {\n        ctx.then(\"opens an example\", |env| /* test condition */ );\n    });\n}));\n```\n\n### Before \u0026 After\n\n|         | All                   | Each          |\n| ------- | --------------------- | ------------- |\n| Before: | `before`/`before_all` | `before_each` |\n| After:  | `after` /`after_all`  | `after_each`  |\n\n#### All\n\nThe \"All\" variants of before and after blocks are executed once upon\nentering (or exiting, respectively) the given context.\n\n#### Each\n\n`before_each` and `after_each` blocks are executed once before each of the\ngiven context's sub-contexts or examples.\n\n### More Examples\n\nAgain, you can see complete examples in the [`examples/`](https://github.com/rust-rspec/rspec/tree/master/examples) directory.\n\n## Documentation\n\nThe last stable documentation is available for consultation at\n[https://docs.rs/rspec](https://docs.rs/rspec).\n\n## Contributions\n\n... are greatly welcome! Contributions follow the standard Github workflow,\nwhich is:\n\n1. Fork this repository\n2. Create a feature branch\n3. Code and commit inside this branch. I have a personnal preference for small\n   atomic commits, but that's not a hard rule.\n4. Make sure you have written tests for your feature. If you don't know how to\n   do that, push the PR with `[WIP]` in the title and we'll gladly help you.\n5. When tests are ok, and you features/bug fixes are covered, we will review the\n   code together, make it better together.\n6. When everyone agrees that the code is right, and the tests pass, you will\n   have the privilege to merge your PR and become a mighty Contributor.\n   Congrats.\n\nTake a look at [the issues](https://github.com/rust-rspec/rspec/issues) if you want\nto help without knowing how. Some issues are mentored!\n\n## Contributors\n\n- Thomas WICKHAM [@mackwic](https://github.com/mackwic)\n- Pascal HERTLEIF [@killercup](https://github.com/killercup)\n- Matthias BOURG [@pol0nium](https://github.com/pol0nium)\n- Vincent ESCHE [@regexident](https://github.com/regexident)\n\n## Beginners\n\n#### About Rust\n\nWelcome in the Rust community! Here are some links which can hopefully help:\n\n- [**Rust is a system programming language**](https://www.rust-lang.org). Check the\n  rust-lang link for a detailed description, you can install it [with rustup](https://www.rustup.rs/).\n- **Newcomers**: [Rust by Example](http://rustbyexample.com/) is a fantastic\n  resource to get started and grasp most of the Rust semantic. Check it out!\n- **Intermediate**: [The Rust Book](https://doc.rust-lang.org/book/) is the best\n  resource to begin the journey to learn Rust.\n- **Advanced**: [Learning Rust with too many linked lists](http://cglab.ca/~abeinges/blah/too-many-lists/book/) is a great book which explains by examples and with great details the system of ownership and how to use it. [The Rustonomicon](https://doc.rust-lang.org/nomicon/) Is another resoure helpful to understand how the compiler thinks and will help you converge quickly to a compilable code.\n\n#### About TDD\n\nTDD, short for Tests Driven Development, is a methodology of development where\nyour code is always working, where refactoring is easy, and you know exactly\nwhat piece of code do _and what it doesn't_.\n\nWith TDD, legacy code is limited, your build is always green and you don't have\nregresssions.\n\nThis is a wonderful and magical land, a well-keeped secret where only the best\nof the best are admitted, people who don't compromise on quality because they\nknow the cost of the absence of quality. People who know that over-quality is\na non-sense.\n\nHere are some useful links:\n\n- [Uncle Bob's 3 rules of\n  TDD](http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd)\n- [The Art of Agile: Test Driven\n  Development](http://www.jamesshore.com/Agile-Book/test_driven_development.html)\n- TDD also enable [simple and emergeant\n  designs](http://www.jamesshore.com/Agile-Book/simple_design.html) by reducing\n  the number of decisions you have to take at each step.\n\n#### About BDD\n\nBDD, short for Behavior Driven Development, is a variation on TDD; some would\nsay that BDD is simply TDD but refined.\n\nBDD states that tests are not the center of the methodology. They are one of the\nmost usefull tool available, but we should not look at them in too high regard.\nWhat matters is the contract they seal, the _described behavior_.\n\nThus, there is enough tests when the behavior of the `struct` is sufficiently\ndescribed. Thinking in term of behavior has two benefits:\n\n- When doing TDD, it helps to make incremential steps. Just write examples of\n  how to use the functions, and make this example pass, then go to the next one.\n  Your tests will naturally have one clear intent, and so will be easy to debug\n  / rely on when refactoring.\n  This is the describe/it approach, which this crate hopes to fill.\n\n- By describing behavior, we are doing an _analysis_ of our program. This\n  analysis can be very useful! Say... an User Story, for example. Given the\n  formalism _As a X, When Y, I want Z_, you can assign scenarii describing the\n  high-level behavior of your units. The Gherkin formalism is often employed for\n  this, it use a _Given X, When Y, Then Z_ structure.\n  This project does not aim to help on high-level BDD, see [the cucumber for\n  Rust port](https://github.com/acmcarther/cucumber)\n  for that.\n\nThe foundation of BDD [is well explained here](https://dannorth.net/introducing-bdd/)\nand [also here](http://blog.daveastels.com.s3-website-us-west-2.amazonaws.com/2014/09/29/a-new-look-at-test-driven-development.html).\n\nBDD written with the Gherkin formalism can really gain from a layer of DDD\n(Domain Driven Development), [but this is another\nstory...](https://msdn.microsoft.com/en-us/magazine/dd419654.aspx).\n\n## Licence\n\nMozilla Public Licence 2.0. See the LICENCE file at the root of the repository.\n\nIn non legal terms it means that:\n\n- if you fix a bug, you MUST give back the code of the fix (it's only fair, see\n  the [Contributing Section](#contributions)).\n- if you change/extend the API, you MUST give back the code you changed in the\n  files under MPL2. The [Contributing Section](#contributions) can help there.\n- you CAN'T sue the authors of this project for anything about this code\n- appart from that, you can do almost whatever you want. See the LICENCE file\n  for details.\n\nThis section DOES NOT REPLACE NOR COMPLETE the LICENCE files. The LICENCE file\nis the only place where the licence of this project is defined.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-rspec%2Frspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frust-rspec%2Frspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-rspec%2Frspec/lists"}