06open 25 min

Testing in Rust: from JavaScript test runners to explicit, compiler-checked tests

Translate familiar JavaScript testing habits into Rust's built-in testing style.

by the end of this lesson you can

  • Uses a Rust test function with direct assertions
  • Keeps expected values explicit
  • Avoids trying to recreate a matcher-heavy JavaScript style

Overview

JavaScript developers often arrive from Jest or Vitest, where matcher APIs and mocks shape the experience. Rust testing is plainer, but the combination of explicit assertions and compiler help makes the suite highly trustworthy.

In JavaScript/Node, you often

use a test runner with matcher-heavy assertions and async helpers around Promise-based code.

In Rust, the common pattern is

to use `#[test]`, direct assertions, and small helper functions without relying on a large matcher DSL.

why this difference matters

Rust tests often feel simpler because the language removes many of the runtime ambiguities that JavaScript tests must guard against.

JavaScript/Node

test("square", () => {
  expect(square(4)).toBe(16);
});

Rust

#[test]
fn square_returns_expected_value() {
    assert_eq!(square(4), 16);
}

Deeper comparison

JavaScript/Node version

it("normalizes names", () => {
  expect(slugify("Hello World")).toBe("hello-world");
});

Rust version

#[test]
fn slugify_normalizes_names() {
    assert_eq!(slugify("Hello World"), "hello-world");
}

Reflect

What becomes easier to trust when the language and the tests both push toward explicitness?

what a strong answer notices

A strong answer mentions fewer runtime surprises, smaller need for mocking gymnastics, and assertions that stay close to the behavior under test.

Rewrite

Rewrite this JavaScript test into Rust using the built-in test style.

Rewrite this JavaScript/Node

it("returns admin users", () => {
  expect(filterAdmins(users)).toEqual([admin]);
});

what good looks like

  • Uses a Rust test function with direct assertions
  • Keeps expected values explicit
  • Avoids trying to recreate a matcher-heavy JavaScript style

Practice

Design a Rust test for a username normalizer that includes multiple cases and clear assertions.

success criteria

  • Uses test names or helper structure that stay easy to scan
  • Keeps each assertion explicit
  • Shows how the compiler and types simplify the test surface

Common mistakes

  • Looking for Jest-style ergonomics before learning Rust's default testing shape.
  • Overusing helper layers that make simple assertions harder to read.
  • Assuming the testing style should mirror JavaScript because the original code came from there.

takeaways

  • Rust tests often feel simpler because the language removes many of the runtime ambiguities that JavaScript tests must guard against.
  • A strong answer mentions fewer runtime surprises, smaller need for mocking gymnastics, and assertions that stay close to the behavior under test.
  • Uses test names or helper structure that stay easy to scan