#tap #results #protocols #anything #generate #format

no-std testanything

Generate results in the Test Anything Protocol (TAP)

12 releases

0.4.2 Oct 16, 2023
0.4.0 Mar 2, 2023
0.3.2 Dec 1, 2022
0.3.1 Jun 10, 2022
0.1.1 Sep 26, 2018

#127 in Testing

Download history 27/week @ 2024-02-25 6/week @ 2024-03-03 8/week @ 2024-03-10 6/week @ 2024-03-17 2/week @ 2024-03-24 23/week @ 2024-03-31 34/week @ 2024-04-07 1/week @ 2024-04-14

62 downloads per month
Used in 4 crates (2 directly)


387 lines

TAP: Test Anything Protocol

-> Lives on crates.io as the testanything crate.

This Rust library provides facilities for the generating and emitting results in the Test Anything Protocol. Please feel free to see testanything.org for more information.


Please see the examples in the examples folder.


ok 1 Panda Bamboo
not ok 2 Curry Noodle
# Tree
# Flower

Use with alloc only (#[no_std])

To use this crate with alloc in #[no_std], use:

testanything = { version = "*", default-features = false, features = ["alloc"] }


cargo test


Apache License Version 2.0


The Test Anything Protocol (TAP) is a plaintext format for expressing test results. It has been around since 1987 when it was invented to help test Perl. With this crate, this wonderfully-useful tool has been brought to Rust!

This crate provides the machinery needed for producing and emitting TAP streams.

For working, executable examples, please see the examples directory.


The first method for producing a TAP stream is the TapSuite mechanism. This will come in handy when you're iterating over a collection and want to map it to a collection of TapTest results. We supply a TapSuiteBuilder and a TapTestBuilder to make this as nice as possible.

Behold! The TapSuite

use testanything::tap_test_builder::TapTestBuilder;
use testanything::tap_suite_builder::TapSuiteBuilder;

use std::io;

// Build a failing test
let failing_tap_test = TapTestBuilder::new()
    .name("Example TAP test")
    .diagnostics(&vec!["This test failed because of X"])

// Construct a test result suite
let tap_suite = TapSuiteBuilder::new()
    .name("Example TAP suite")

// Print TAP to standard output in one chunk
match tap_suite.print(io::stdout().lock()) {
    Ok(_) => {}
    Err(reason) => eprintln!("{}", reason),

The second method uses the TapWriter facility and may be thought of as the direct approach. This mechanism allows you to write a semi-customizable TAP stream to STDOUT from anywhere in your program. Since the TAP specification requires that TAP be emitted to STDOUT, the TapWriter doesn't get fancy with any of the stream interfaces.

Behold, the TapWriter!

use testanything::tap_writer::TapWriter;

let writer = TapWriter::new("Example TAP stream");

// Write the plan out. This can come before or after the test results themselves.
writer.plan(1, 6);

// Give me the name as a diagnostic line

// Print out some test results
writer.ok(1, "Panda");
writer.ok(2, "Bamboo");
writer.ok(3, "Curry");
// This one failed, so explain why with a diagnostic line
writer.not_ok(4, "Noodle");
writer.diagnostic("The above test failed because of XYZ reason");
writer.ok(5, "Tree");

// Uh oh! something went horribly wrong and we need to stop before
// we print out the results from test 6!
writer.bail_out_with_message("Destabilized warp core! Can't continue!");

No runtime deps