Basic passing suite
Put this complete module in src/lib.rs. Each case is opened, decided, and closed exactly once.
#[cfg(test)]
mod tests {
use vanilla_test::VanillaTest;
#[test]
fn basic_suite() {
let mut test = VanillaTest::new();
test.expects("2 + 2 equals 4").unwrap();
if 2 + 2 == 4 { test.pass().unwrap(); } else { test.fail().unwrap(); }
test.done().unwrap();
test.expects("uppercase preserves the word").unwrap();
if "rust".to_uppercase() == "RUST" { test.pass().unwrap(); } else { test.fail().unwrap(); }
test.done().unwrap();
let result = test.report().unwrap();
assert!(result.ok, "{}", result.report);
assert_eq!(result.total, 2);
}
}cargo testIntentional failed result
A failed expectation is recorded in TestResult. It is separate from a TestError, which represents invalid runner usage.
#[test]
fn intentional_failed_result() {
use vanilla_test::VanillaTest;
let mut test = VanillaTest::new();
test.expects("intentional failure").unwrap();
test.fail().unwrap();
test.done().unwrap();
let result = test.report().unwrap();
assert!(!result.ok);
assert_eq!(result.failure_count, 1);
assert_eq!(&*result.failed, ["1) .expects intentional failure"]);
}Typed lifecycle error
#[test]
fn typed_lifecycle_error() {
use vanilla_test::{TestError, VanillaTest};
let mut test = VanillaTest::new();
assert_eq!(test.pass(), Err(TestError::NoActiveTest));
test.expects("active").unwrap();
assert_eq!(test.report(), Err(TestError::ActiveTestNotDone));
}The failed operations leave the suite state unchanged.
Build the same tests for the browser
rustup target add wasm32-unknown-unknown
cargo install vanilla-test --version 2.1.0
cargo vanilla-test --browserServe dist/vanilla-test/ over HTTP. The host adapter reports passive page and delivery checks on-page and in DevTools, then calls the safe exported Rust harness main() once. This repository's same seven Rust #[test] functions, including its Behavioral consumer journey, run natively and in WASM.
Complete passive rendered-text page
This page supports passive rendered-text checks only. Save it as tests/browser.html; the result hooks are the adapter contract, and the two marked elements become named host checks.
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Rust browser tests</title></head>
<body>
<main data-rust-browser-result>
<h1 data-rust-browser-site-check="dashboard heading is visible"
data-rust-browser-expected="Dashboard">Dashboard</h1>
<div role="status" aria-live="polite" aria-atomic="true">
<h2 data-rust-browser-status>Running…</h2>
<p data-rust-browser-detail>Loading Rust tests.</p>
</div>
<strong data-rust-browser-score aria-label="Browser checks pending">0/?</strong>
<p>Target: <code data-rust-browser-target
data-rust-browser-site-check="canonical target is visible"
data-rust-browser-expected="wasm32-unknown-unknown">wasm32-unknown-unknown</code></p>
<p>Rust harness: <code data-rust-browser-harness>not run</code></p>
<dl>
<div><dt>Passed</dt><dd data-rust-browser-passed>0</dd></div>
<div><dt>Failed</dt><dd data-rust-browser-failed>0</dd></div>
<div><dt>Skipped</dt><dd data-rust-browser-skipped>0</dd></div>
</dl>
<ul data-rust-browser-checks aria-label="Rust browser checks">
<li data-rust-browser-waiting>Waiting for the browser adapter</li>
</ul>
</main>
<script type="module" src="./browser.js"></script>
</body>
</html>cargo vanilla-test --browser --page tests/browser.html--page copies this file's bytes without validating the HTML, copying assets, or waiting for dynamic content. The adapter checks one snapshot of connected, visible, nonempty rendered text and optional exact text; it does not click, type, navigate, retry, or call JavaScript from Rust. Test JavaScript functions in the JavaScript lane.