| Crates.io | json2tests |
| lib.rs | json2tests |
| version | 0.3.1 |
| created_at | 2025-10-20 13:21:41.961849+00 |
| updated_at | 2025-10-28 15:54:37.075659+00 |
| description | Macro to generate your Rust tests from a provided JSON file |
| homepage | https://github.com/niri81/json2tests-rs/ |
| repository | https://github.com/niri81/json2tests-rs/ |
| max_upload_size | |
| id | 1891911 |
| size | 304,147 |
json2tests — Generate Rust Tests from a Given JSON FileThe macro provided in this crate allows for generating test cases from a given JSON file following the schema defined in schema.json.
The example code shows how to use the macro. Notice how you can run cargo test for this example and the tests from the JSON files are executed.
cargo test --example implementation
Add the following to your Cargo.toml (if not already in it):
[packages]
assert-json-diff = "2.0"
json2test = { version = "0.1.0", path = "YOUR_PATH" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = "1.0"
Please note that this macro is not yet available via cargo add, you need to clone the repository and specify the local path!
Add the following to your source code:
#[cfg(test)]
mod test {
use super::*;
use json2tests::json2tests;
json2tests!(file_path)
}
Generate tests from JSON takes a file path as input and will invoke a run() function for each testcase contained in the JSON. Your run function needs to be defined as follows:
fn run(action: &str, args: serde_json::Value) -> Result<serde_json::Value, impl std::error::Error>;
[!NOTE] Cargo will not detect if you change something on your test files. I therefore recommend to add a
build.rsfile declaring a dependency on your JSON file(s), to ensure a recompilation when you change your tests.Example:
fn main() { println!("cargo:rerun-if-changed=tests.json"); }
You can specify that your code is expected to panic by setting the panic property in the JSON file. This will add the #[should_panic] attribute to the test.
{
"testcases": {
"test_addition": {
"action": "add",
"arguments": {
"a": 2,
"b": 3
},
"result": 4,
"panic": true
}
}
}
When the panic property is set to a string, it will be matched against the panic message using the #[should_panic(expected = "...")] attribute.
This JSON script
{
"testcases": {
"test_addition": {
"action": "add",
"arguments": {
"a": 2,
"b": 3
},
"result": 5
}
}
}
will generate the following code, when implemented as described in Usage:
mod test {
use super::*;
use json2tests::json2tests;
extern crate test;
#[rustc_test_marker = "test::test_addition"]
#[doc(hidden)]
pub const test_addition: test::TestDescAndFn = test::TestDescAndFn {
// Snip
};
fn test_addition() {
let value = serde_json::from_str("{\"a\":2,\"b\":3}").unwrap();
let result = run("add", value);
if !result.is_ok() {
::core::panicking::panic("assertion failed: result.is_ok()")
}
let expected_result: serde_json::Value = serde_json::from_str("5").unwrap();
{
{
if let Err(error) = ::assert_json_diff::assert_json_matches_no_panic(
&result.unwrap(),
&expected_result,
::assert_json_diff::Config::new(
::assert_json_diff::CompareMode::Strict,
),
) {
{
::std::rt::panic_fmt(format_args!("\n\n{0}\n\n", error));
};
}
}
}
}
}

(This shall include all Rustaceans equally, without regard to gender :crab:).
Happy coding (and testing)! :rocket: