aaronabramov/k9

K9 - Rust Testing Library

Snapshot testing + better assertions

Available test macros

  • snapshot
  • assert_equal
  • assert_greater_than
  • assert_greater_than_or_equal
  • assert_lesser_than
  • assert_lesser_than_or_equal
  • assert_matches_regex
  • assert_err_matches_regex
  • assert_matches_snapshot
  • assert_matches_inline_snapshot
  • assert_ok
  • assert_err

See https://docs.rs/k9 for API documentation

snapshot!() macro

Snapshot macro provides the functionality to capture the Debug representation of any value and make sure it does not change over time.

If it does change, the test will fail and print the difference between "old" and "new" values.

If the change is expected and valid, running cargo test with K9_UPDATE_SNAPSHOTS=1 env variable set will automatically take the new value and insert it into the test source code file as a second argument, after which all subsequent test runs should start passing again.

assert_equal!() macro

Rust already provides a good built-in test runner and a set of assertion macros like assert! and assert_eq!. They work great for for quick unit tests, but once the codebase and test suites grows to a certain point it gets harder and harder to test things and keep tests readable.

For example, when testing that two structs are equal using assert_eq! macro the output does not provide a lot of help in understanding why exactly this test failed.


#[derive(PartialEq, Debug)]
struct Person {
    name: &'static str,
    age: usize,
}

#[test]
fn test_eq() {
    let person1 = Person {name: "Bob", age: 12 };
    let person2 = Person {name: "Alice", age: 20 };
    assert_eq!(person1, person2, "These two must be the same person!");
}

All we get is usually a wall of wite text collapsed into a single line and you have to find the difference between two structs yourself. Which becomes very time consuming when structs are 10+ fields.

---- eq::test_eq stdout ----
thread 'eq::test_eq' panicked at 'assertion failed: `(left == right)`
  left: `Person { name: "Bob", age: 12 }`,
 right: `Person { name: "Alice", age: 20 }`: These two must be the same person!', src/eq.rs:13:5

using k9::assert_equal macro improves this output and prints the difference between two structs:

use k9::assert_equal;
assert_equal!(person1, person2, "These two must be the same person!");

Non-equality based assertions

Testing equality is very simple and can definitely work for most of the cases, but one of the disadvantages of only using assert! and assert_eq! is the error messages when something fails. For example, if you're testing that your code produces valid URL

let url = generate_some_url();
assert_eq!(URL_REGEX.is_match(url), true);

What you get is

thread 'eq::test_eq3' panicked at 'assertion failed: `(left == right)`
  left: `false`,
 right: `true`', src/eq.rs:19:5

Which doesn't help much. Especially, if you're new to the code base, seeing things like expected 'true' but got 'false' will make you go and look at the code before you even know what the problem can be, which can be very time consuming.

What we probably want to see is:

Which gives us enough context on what the problem is and how to fix it without for us having to go and run/debug the test first.

Issues

Collection of the latest Issues

TheWebDevel

TheWebDevel

Comment Icon12

Usecase: Difference between two structs. Assertion: assert_equal

Current Output: image

Collapsed Output: image

Method: String Iteration

Implementation:

  1. Computed the index of each occurrence with reference to (- or +). // [4, 5, 16, 17, 20, 21]
  2. I have a cur_index and a peek_index.
  3. If the difference between cur_index and peek_index is <= 5, I'll have those index and the intermediate values in the final collapsed output else I have a .... // [4, 5, 16, 17, 18, 19, 20, 21]
aaronabramov

aaronabramov

Comment Icon1

we have line! and column! macros. we can technically take out a pice of code with some context around it where assertion failed and add it to the error message e.g.

Assertion Failure!

43 | fn do something() { 44 | let stuff = 1 45 | assert_equal!(stuff, 2); 46 | }

Information - Updated Dec 22, 2021

Stars: 234
Forks: 13
Issues: 5

Repositories & Extras

utest standard testing for Rust

Make sure your not using this for testing no_std code as it relies on the unstable branch

utest standard testing for Rust

Spec &quot;it&quot; for Rust testing

The test output is like the following

Spec &quot;it&quot; for Rust testing

Shuttle is a library for testing concurrent Rust code

It is an implementation of a number of

Shuttle is a library for testing concurrent Rust code

Let's make a web service and client in Rust

So I'm working on this project Rust regression testing

Let's make a web service and client in Rust

Simple golden file testing for Rust

Add the following to your Cargo manifest

Simple golden file testing for Rust
Http

329

HTTP mocking to test Rust applications

wiremock provides HTTP mocking to perform black-box testing of Rust applications that

HTTP mocking to test Rust applications

just testing rust

cli + advanced cli features

just testing rust

Testing Rust Code

This repo contains examples of many common features and approaches for testing here

Testing Rust Code
Facebook Instagram Twitter GitHub Dribbble
Privacy