{"id":17164154,"url":"https://github.com/sminez/simple_test_case","last_synced_at":"2025-04-13T14:42:58.191Z","repository":{"id":57667484,"uuid":"453372816","full_name":"sminez/simple_test_case","owner":"sminez","description":"simple parameterised tests for rust","archived":false,"fork":false,"pushed_at":"2023-07-20T08:05:40.000Z","size":30,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-04-08T14:41:59.943Z","etag":null,"topics":["rust","testing","testing-library"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/simple_test_case","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sminez.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":"2022-01-29T11:02:54.000Z","updated_at":"2025-01-30T16:35:01.000Z","dependencies_parsed_at":"2022-09-02T14:22:39.355Z","dependency_job_id":null,"html_url":"https://github.com/sminez/simple_test_case","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/sminez%2Fsimple_test_case","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sminez%2Fsimple_test_case/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sminez%2Fsimple_test_case/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sminez%2Fsimple_test_case/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sminez","download_url":"https://codeload.github.com/sminez/simple_test_case/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248731696,"owners_count":21152838,"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":["rust","testing","testing-library"],"created_at":"2024-10-14T22:51:04.244Z","updated_at":"2025-04-13T14:42:58.156Z","avatar_url":"https://github.com/sminez.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Test helpers should be simple.\n\nYou don't want to have to worry about bugs in your test suite or unexpected behaviour leading\nto failing tests silently passing. With that in mind, `simple_test_case` aims to do the bare\nminimum to eliminate the boilerplate of writing parameterised tests and no more.\n\nThe `test_case` attribute macro handles generating multiple test functions for you which are\nparameterised by the inputs you provide. You still need to provide the `#[test]` attribute (or\nan alternative such as `#[tokio::test]`) and all test cases _must_ be provided before any\nadditional attribute macros you wish to apply.\n\nAnd that's it.\n\nThere is no additional support for custom assertions, fixtures etc. That said, if you want or\nneed a more complicated testing set up, additional attribute macros should play nice with\n`simple_test_case` provided you follow the advice below.\n\n\n## Usage\n\n### Valid\nHere the `#[test]` attribute is provided after all instances of `test_case`. This will work.\n```rust\nuse simple_test_case::test_case;\n\nfn double(n: usize) -\u003e usize {\n    n * 2\n}\n\n#[test_case(1, 2; \"case 1\")]\n#[test_case(3, 6; \"case 2\")]\n#[test]\nfn double_test(n: usize, double: usize) {\n    assert_eq!(double(n), double)\n}\n```\n\n### Invalid\nHere the `#[test]` attribute is provided before all instances of `test_case`. This will cause\nthe compiler to complain about functions used as tests not being allowed to have any arguments.\n```rust\nuse simple_test_case::test_case;\n\nfn double(n: usize) -\u003e usize {\n    n * 2\n}\n\n#[test]\n#[test_case(1, 2; \"case 1\")]\n#[test_case(3, 6; \"case 2\")]\nfn double_test(n: usize, double: usize) {\n    assert_eq!(double(n), double)\n}\n```\n\n## Additional attributes\n\n`test_case` preserves all attributes beneath it, forwarding them on to the individual generated\ntest functions. As an example, the standard library `should_panic` attribute works just fine as\nshown below (just make sure to provide your test cases first as described above):\n\n```rust\nuse simple_test_case::test_case;\n\n#[test_case(1, 2; \"case 1\")]\n#[test_case(3, 6; \"case 2\")]\n#[test]\n#[should_panic(expected = \"this works\")]\nfn panic_test(n: usize, double: usize) {\n    assert_eq!(double(a), b);\n    panic!(\"this works\")\n}\n```\n\n### Async tests\n\nAsync tests are supported in the same way that all other attributes are supported: add your\ntests cases first and then apply the async testing macro of your choice beneath.\n```rust\nuse simple_test_case::test_case;\n\nasync fn async_double(n: usize) -\u003e usize {\n    n * 2\n}\n\n#[test_case(1, 2; \"case 1\")]\n#[test_case(3, 6; \"case 2\")]\n#[tokio::test]\nasync fn double_test(n: usize, double: usize) {\n    assert_eq!(double(n).await, double)\n}\n```\n\n## How does it work?\n\nYou are encouraged to read the source of the macro itself (the macro plus associated helper\nfunctions are under 150 lines of code) but the general idea is as follows:\n\n- Collect all `test_case` (or `simple_test_case::test_case`) attributes, each of which maps a\n  set of function arguments to a test case name.\n- For each test case create a copy of the original test function with the function arguments\n  replaced with explicit variable bindings at the top of the function body.\n- Write out each of the cases as their own test inside of a new module that is named using the\n  original test function name.\n\nYou can use [cargo expand](https://github.com/dtolnay/cargo-expand) to see what the generated\ntests look like using the example provided in the `examples` directory like so:\n\n```bash\n$ cargo expand --example=expand_me --tests\n  Compiling simple_test_case v0.1.0 (/home/innes/repos/personal/simple_test_case)\n   Finished test [unoptimized + debuginfo] target(s) in 0.12s\n```\n```rust\n#![feature(prelude_import)]\n#[prelude_import]\nuse std::prelude::rust_2021::*;\n#[macro_use]\nextern crate std;\nuse simple_test_case::test_case;\nmod example {\n    #[allow(unused_imports)]\n    use super::*;\n    extern crate test;\n    #[cfg(test)]\n    #[rustc_test_marker]\n    pub const small_example: test::TestDescAndFn = test::TestDescAndFn {\n        desc: test::TestDesc {\n            name: test::StaticTestName(\"example::small_example\"),\n            ignore: false,\n            allow_fail: false,\n            compile_fail: false,\n            no_run: false,\n            should_panic: test::ShouldPanic::No,\n            test_type: test::TestType::Unknown,\n        },\n        testfn: test::StaticTestFn(|| test::assert_test_result(small_example())),\n    };\n    fn small_example() {\n        let a: usize = 1;\n        let b: usize = 2;\n        if !(a \u003c b) {\n            ::core::panicking::panic(\"assertion failed: a \u003c b\")\n        }\n    }\n    extern crate test;\n    #[cfg(test)]\n    #[rustc_test_marker]\n    pub const large_example: test::TestDescAndFn = test::TestDescAndFn {\n        desc: test::TestDesc {\n            name: test::StaticTestName(\"example::large_example\"),\n            ignore: false,\n            allow_fail: false,\n            compile_fail: false,\n            no_run: false,\n            should_panic: test::ShouldPanic::No,\n            test_type: test::TestType::Unknown,\n        },\n        testfn: test::StaticTestFn(|| test::assert_test_result(large_example())),\n    };\n    fn large_example() {\n        let a: usize = 100;\n        let b: usize = 200;\n        if !(a \u003c b) {\n            ::core::panicking::panic(\"assertion failed: a \u003c b\")\n        }\n    }\n}\n#[allow(dead_code)]\nfn main() {}\n#[rustc_main]\npub fn main() -\u003e () {\n    extern crate test;\n    test::test_main_static(\u0026[\u0026small_example, \u0026large_example])\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsminez%2Fsimple_test_case","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsminez%2Fsimple_test_case","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsminez%2Fsimple_test_case/lists"}