Fact-checked by Grok 2 weeks ago

Test Anything Protocol

The Test Anything Protocol (TAP) is a simple, text-based interface protocol designed to communicate test results between testing modules—known as producers—and es—known as consumers—in a manner, thereby error reporting from result presentation to reduce noise and facilitate analysis. Originating in 1988 as part of the test harness for 1.0, TAP enables streamlined test output by focusing on essential diagnostics while allowing harnesses to filter or format successes as needed. TAP's development began with Larry Wall's basic t/TEST program in 1.0, which introduced core syntax like plan lines (1..N) and pass/fail indicators (ok or not ok), evolving through contributions from the Perl community, including Joshua Pritikin, Ilya Zakharevich, and Michael G. Schwern. Key milestones include the addition of checks in Perl 5.002 (1996), skip and TODO directives in later Perl versions, and formal version numbering starting with TAP 13 in 2006 via the TAP::Parser module. The protocol reached version 14 in recent years, incorporating subtests, diagnostics, and pragmas for enhanced harness control, while a " nonproliferation treaty" was established to minimize conflicts in Perl implementations. At its core, TAP 14 specifies a stream format beginning with a version declaration, followed by a indicating the number of tests, individual test points with optional descriptions and directives (e.g., # [SKIP](/page/Skip) for conditional omission or # TODO for planned failures), and support for nested subtests via indentation. Additional elements include bailout commands (Bail out!) to halt execution, comments prefixed with #, and escaped special characters for robustness, ensuring the protocol remains human-readable and machine-parseable across diverse environments. This structure promotes interoperability, as producers output while consumers handle rendering, diagnostics, and aggregation. TAP has been widely adopted beyond Perl, with implementations in languages such as C, C++, , , , , Go, and , powering tools like Python's unittest extensions and JavaScript's tap library. It also influenced the kernel's KTAP (Kernel TAP) version 1, integrated into the kernel testing framework for consistent result reporting in device drivers and modules. This broad ecosystem underscores TAP's role in standardizing test output, enabling cross-language test suites and pipelines in open-source and development.

Introduction

Definition and Purpose

The Test Anything Protocol (TAP) is a simple, line-oriented, text-based protocol designed for communicating test outcomes between a test script, known as the TAP producer, and a , known as the TAP consumer. This interface allows test scripts to report results in a standardized format, independent of the underlying programming language or testing framework. The primary purpose of TAP is to enable portable and human-readable reporting of test results, decoupling the execution of tests from their presentation and analysis. By providing a consistent output structure, TAP facilitates the aggregation of results from multiple tests, supports automated parsing for statistics and error tracking, and minimizes noise in test suites by focusing on diagnostics rather than verbose success messages. This design promotes interoperability across diverse tools and environments, allowing test harnesses to process outputs uniformly regardless of the source. TAP originated as a solution for unit testing in the Perl programming language but was intentionally crafted to be language-agnostic, enabling adoption beyond its initial context. Its creation addressed the need for a lightweight, extensible way to handle test reporting in early software development practices. Key benefits of TAP include its inherent simplicity through plain text output, which ensures readability for humans and machines alike; extensibility via optional directives that allow for additional metadata without altering the core format; and strong interoperability, which permits the mixing and aggregation of test results from various sources and languages in a single harness. These attributes have contributed to TAP's widespread use in software testing ecosystems.

Key Features

The Test Anything Protocol (TAP) employs a simple, line-based format for reporting test results, where each test outcome is indicated by a line beginning with "" for passing tests or "not ok" for failing ones, followed by a sequential number and an optional descriptive comment. This structure ensures that test results are easily parseable by harnesses, with the numbering allowing for clear tracking of individual tests within a suite. A fundamental element is the plan line, which declares the expected total number of tests in the format "1..N", where N is the count; this line must appear exactly once, either at the beginning or end of the output, and helps consumers anticipate the scope of the test run. For instance, "1..5" signals five tests, promoting reliability in test execution by enabling early detection of incomplete runs. TAP supports diagnostics through comment lines prefixed with "#", which allow producers to output supplementary information—such as details or explanations—without interfering with the pass/fail determination of tests. These can include YAML-formatted blocks for structured data, indented under a test line to associate them directly with specific results, enhancing the protocol's utility for detailed reporting. In cases of critical failures, TAP provides a bailout mechanism via the "Bail out!" directive (case-insensitive), optionally followed by a reason, which instructs consumers to immediately halt the and report the termination. This feature is essential for preventing further execution when conditions like resource unavailability make continuation futile. Versioning is explicitly supported by an initial line stating "TAP version 14" (or the relevant version number), ensuring compatibility across implementations and allowing for the introduction of new features without breaking existing parsers. The protocol's extensibility is achieved through directives appended to test lines, such as "# SKIP" to mark a test as skipped with an optional reason, "# TODO" to indicate a test expected to fail temporarily, and support for subtests as nested, indented TAP streams that begin and end with their own test points. These mechanisms allow TAP to handle complex testing scenarios, like conditional skips or hierarchical test organization, while maintaining a uniform, streamable format.

History

Origins in Perl

The Test Anything Protocol (TAP) traces its origins to the programming language, where it emerged as a foundational element of the language's testing infrastructure. The protocol's basis was established by in the original test script for Perl 1, released in December 1987, as part of the core located in the t/TEST file. This initial implementation provided a rudimentary format for reporting test outcomes directly within Perl's build process. In 1987–1988, Tim Bunce and Andreas J. König refined and implemented the t/TEST harness, introducing the core TAP output format to standardize test reporting. Their contributions formalized the simple line-based structure, such as "ok 1" and "not ok 2," enabling straightforward integration with Perl's make-based build system. The primary motivation was to create an uncomplicated mechanism for conveying test results from individual scripts to the overall harness, avoiding the need for complex parsing logic that could complicate automated builds and regressions. This approach ensured that test output remained human-readable while being machine-processable, facilitating early Perl development workflows. TAP saw initial informal adoption within Perl's core test suite, where files in the t/ directory began producing output in this format to verify language features and standard library functions. As Perl modules proliferated in the late 1980s and early 1990s, developers informally extended TAP usage to custom tests for these modules, embedding it in scripts run via make test without a dedicated parser module. This grassroots integration helped solidify TAP as a de facto standard in the Perl community prior to formal documentation. By the early 1990s, TAP's role expanded through the development of the module, attributed to either Tim Bunce or Andreas J. and inspired by Wall's original TEST script. Released around this period, Test::Harness provided the first dedicated consumer of TAP output, aggregating results from multiple test files and generating summary statistics for Perl distributions and modules. This tool marked a key step in TAP's institutionalization within , enabling more robust testing for the growing ecosystem of Comprehensive Perl Archive Network () contributions starting in 1995.

Evolution and Versioning

The Test Anything Protocol (TAP) began as an informal convention within Perl's testing ecosystem but progressively formalized through iterative releases that refined its structure and capabilities. , introduced in 1988 with 1.0, established the foundational elements of basic pass/fail reporting, featuring a plan line indicating the number of tests ("1..M") followed by simple "ok" or "not ok" assertions. Subsequent early versions built on this: , released in 1996 alongside 5.002beta3, incorporated checks to signal overall test outcomes, enhancing integration. By (also 1996, 5.003_01), support for skipping entire test suites via "1..0" was added, while (1997, 5.004_55) introduced the skip directive for individual tests. The protocol continued evolving, with (2001, via Test::Harness) adding the TODO directive to mark expected failures. This incremental progression transformed TAP from a Perl-specific into a more robust, parseable format suitable for broader adoption. Formalization efforts solidified TAP as a de facto standard primarily through Perl's testing infrastructure, particularly the introduction of the TAP::Parser module in the Test::Harness distribution, which provided a standardized mechanism for interpreting and aggregating TAP streams. Coordination of these developments has been centralized via the Test Anything Protocol website (testanything.org), established in the 2000s as a dedicated hub for maintaining specifications, documenting compatible tools, and fostering community contributions. By the mid-2000s, this site had become essential for tracking the protocol's evolution, including catalogs of TAP producers (test emitters) and consumers (parsers and harnesses), ensuring interoperability across evolving implementations. Standardization attempts beyond the Perl community began in 2008 with an initiative to draft TAP as an IETF Internet-Draft, aiming to position it as a standard for test result interchange. This effort produced an ongoing draft document on , outlining TAP version 13 for potential RFC submission, though as of 2025, it remains unratified and in a developmental state. Recent advancements culminated in Version 14 (current as of 2023), which enhanced support for nested subtests to enable hierarchical test and refined harness behaviors for better . Community-driven updates continue through the producers and consumers catalog on testanything.org, promoting while addressing modern testing needs.

Specification

Core Elements

The Test Anything Protocol (TAP) in its Version 14 specification defines a structured text-based format for reporting test results, ensuring interoperability between test modules and harnesses across programming languages. The core structure of a TAP stream consists of an optional line, a plan line, a body containing test points and diagnostics, and an optional trailing plan, all adhering to a precise to facilitate . The version line, if present, must appear as the very first line of the stream and is formatted exactly as TAP version 14, followed by a newline; this declares compliance with the current specification and aids parsers in interpreting the output correctly. Immediately following or preceding the body, the plan line specifies the expected number of tests using the syntax 1..N, where N is a non-negative integer (where N can be 0 for skipped tests) representing the total count of test points anticipated in the stream; this line must occur exactly once and may include an optional trailing comment starting with #. The absence of a plan or a mismatch between the declared N and the actual number of test points results in an error condition for the harness, typically interpreted as a failure, with parsers expected to handle unexpected early termination by treating unaccounted tests as failed. Within the body, test result lines form the primary content, each beginning with either ok for a passing test or not ok for a failing test—these keywords are case-sensitive and mandatory. An optional test number may follow, separated by a space, ensuring sequential numbering from 1 to N without gaps or duplicates; a description may then be appended after a literal " - ", providing human-readable context. Diagnostic output, such as additional details or YAML-structured data, can intersperse the test lines but must not disrupt the sequential flow of test points, with the entire body allowing for comments (lines starting with #) and empty lines while maintaining parseability. The for TAP streams, as outlined in the specification, defines the document as either Version Plan Body or Version Body Plan, where the body comprises zero or more elements including test points, bail-out instructions, pragmas, comments, arbitrary lines, empty lines, or subtest blocks. A trailing plan is permitted only if all test points precede it, reinforcing the expected count and enabling harnesses to validate completeness post-execution. This rigid yet flexible structure ensures that TAP remains a lightweight, machine-readable suitable for automated testing pipelines.

Directives and Extensions

The Test Anything Protocol (TAP) includes several optional directives that allow test producers to handle special conditions, such as intentionally skipping tests or marking known failures, without altering the core pass/fail reporting. These directives are appended to test lines following the # symbol and are case-insensitive, enabling flexible annotations for test harnesses to interpret and display appropriately. The skip directive, denoted as # SKIP [reason], indicates that a test is intentionally omitted and should not be evaluated as a failure, often due to unmet prerequisites like unavailable dependencies. For instance, a test line might read ok 1 # SKIP requires external module, where the optional reason provides context for the omission. Similarly, the todo directive, # TODO [reason], flags a test expected to fail due to known issues, treating it as a pass if it unexpectedly succeeds; an example is not ok 2 # TODO fix later. Both directives follow the test result and do not affect the overall test count or plan. Diagnostics in TAP provide structured additional information about test points, typically in YAML format for machine-readable details. These appear as indented blocks immediately following a test line, beginning with --- and ending with ..., adhering to 1.2 specifications. For example:
not ok 3 - connection test
  ---
  error: "Connection refused"
  severity: high
  ...
This format allows harnesses to extract key-value pairs, such as messages, without relying on unstructured comments, though no standardized fields are mandated. The bailout directive, Bail out! [reason], serves as an emergency mechanism to immediately halt the entire test suite, signaling a critical failure that prevents further execution. It is case-insensitive, with an optional explanatory reason, and when used within subtests, it propagates to abort the parent stream as well. An example usage is Bail out! Database unavailable, which instructs harnesses to stop and report the suite as incomplete. Introduced in TAP version 14, subtests enable nested TAP streams to represent hierarchical test structures, such as suites within suites, by indenting child output with four spaces under a parent test line. The parent line, like ok 1 - subtest name # Subtest: passed 3/5, summarizes the subtest's outcome, including pass/fail counts, while the nested content follows TAP rules without its own version declaration for . This feature supports deeper nesting via incremental indentation and optional # Subtest: [name] comments for clarity. TAP extensions, including custom directives and , allow producers to add non-conflicting features while preserving core compatibility; custom elements must avoid reserved keywords like ok or not ok and may use prefixes to them. , formatted as pragma [+|-]key, toggle harness behaviors—such as pragma +strict for stricter —with unrecognized ones safely ignored. YAML diagnostics further extend output richness by embedding complex data structures.

Implementations

In Perl

The Test Anything Protocol (TAP) originated in the programming language, where it serves as the foundational standard for test output and harness integration. In , TAP is primarily produced using the core module Test::More, which provides a flexible framework for writing tests that generate compliant TAP streams, including assertions like ok, is, and like for diagnostics and comparisons. Complementing this, TAP::Harness acts as the test runner, aggregating results from multiple test files and outputting summaries, while TAP::Parser handles the consumption and parsing of TAP output, converting it into structured objects for analysis, such as test plans, results, and diagnostics. These modules form the backbone of 's testing ecosystem, enabling seamless separation between test logic and reporting. TAP integrates deeply with the Comprehensive Perl Archive Network (CPAN), Perl's primary distribution repository, where the prove command-line tool executes TAP-compliant tests from directories like t/*.t during module builds and installations. This tool leverages TAP::Harness internally to parse and summarize results automatically as part of Perl's standard build process, ensuring that tests run consistently across environments without manual intervention. Such integration makes TAP the default for CPAN module validation, with prove supporting options for verbosity, parallelism, and error highlighting to facilitate debugging. For advanced usage, offers extensible tools like the TAP::Formatter::* family of modules, which customize output formats beyond plain text; for instance, TAP::Formatter::HTML generates browser-friendly reports with detailed test breakdowns, while TAP::Formatter::JSON produces structured data for programmatic consumption or integration with CI systems. Additionally, Devel::Cover enhances workflows by collecting metrics during test execution, invoking -based runs via commands like cover -test to analyze which code paths are exercised and report results in or other formats. Perl's TAP implementation maintains full backward compatibility with Perl 5.6 and later versions, allowing legacy codebases to leverage modern parsing without issues. TAP::Parser specifically supports up to TAP version 14, accommodating all specification extensions while defaulting to version 12 for unversioned streams. As of 2025, TAP dominates Perl testing, powering the vast majority of over 35,000 distributions on CPAN through modules like Test::More.

In Other Languages

The Test Anything Protocol (TAP) has been adapted into numerous non-Perl programming languages, enabling test producers and consumers to generate and parse standardized output across diverse ecosystems. This portability allows developers to integrate into polyglot projects, where tests written in different languages can be aggregated and reported uniformly. As a interface, 's adoption beyond underscores its role in facilitating cross-platform testing without requiring custom parsers for each environment. Key TAP producers, or test generators, exist in languages such as , where tap4j provides a full-featured library supporting TAP version 13 with features like diagnostic output and plan declarations. In JavaScript, node-tap serves as both a producer and harness, implementing TAP for applications with support for asynchronous tests and subtests. Python implementations include pytest-tap, a for the pytest that outputs TAP-compliant results, and tappy, a standalone tool for generating and viewing TAP streams. Go's tap.go library adapts the testing/quick package to produce TAP, while Ruby's minitest-tap extends the Minitest with TAP reporting. In C, libtap offers an mirroring Perl's Test::More for embedding TAP in low-level applications. Rust's testanything crate enables TAP output in Cargo-based projects, and additional producers appear in via ex_tap for ExUnit integration and in through tasty-tap for the Tasty testing suite. These examples illustrate TAP's flexibility, with libraries often prioritizing core elements like test plans, assertions, and diagnostics while extending to language-specific idioms. TAP consumers, or parsers and harnesses, further enhance interoperability, including language-agnostic tools like the Node.js-based , which processes TAP streams into structured data for reporting or aggregation. In build systems, provides native TAP support within tools, allowing seamless integration of TAP tests into Makefile-based workflows without additional scripting. Other consumers include tappy in Python for viewing and summarizing TAP output, and , a for portable parsing in resource-constrained environments. Notable adoptions highlight TAP's practical impact in large-scale systems. PostgreSQL's pgTAP extension embeds TAP assertions directly in SQL for database unit testing, supporting features like subtests and bail-out directives within the database engine. Similarly, utilizes MyTAP, a stored procedure-based that emits TAP for testing server components and user-defined functions. In operating systems, incorporates TAP into its base test suite via the kyua , which replaced earlier TET integrations to provide TAP-compliant reporting for system-level verification. For , the Jenkins TAP Plugin parses TAP output from builds, enabling visual reporting and across mixed-language pipelines. Despite its strengths, implementing TAP in non-English or non-ASCII environments presents challenges, particularly with in diagnostic messages and blocks, where support varies across libraries, sometimes requiring explicit settings to avoid parsing errors. Additionally, while TAP version 14 introduces enhancements like improved subtest nesting, adoption remains partial; for instance, JavaScript's node-tap fully supports subtests, but some C libraries like older libtap variants lag, adhering only to version 13 and necessitating workarounds for newer directives. The official catalog at testanything.org documents over 20 languages with TAP producers as of 2025, spanning from mainstream options like and to niche ones like and , thereby supporting cross-language test aggregation in tools like multi-repo systems.

Examples

Basic Output Format

The Basic Output Format of the Test Anything Protocol () consists of a simple, line-based structure that allows test producers to report results in a parseable manner, primarily through a indicator, a , and individual test result lines. This format ensures that test harnesses can reliably consume and aggregate results without ambiguity, focusing on essential elements like pass/fail status and optional descriptions. Core syntax rules, such as the use of "ok" for passes and "not ok" for failures followed by a test number and description, form the foundation of these streams. A fundamental example is a single passing test, which declares the TAP version, specifies a plan for one test, and reports the result affirmatively. The stream appears as follows:
TAP version 14
1..1
ok 1 - Basic check
Here, "1..1" indicates the plan for exactly one test, and "ok 1 - Basic check" confirms its success with a descriptive . This minimal output demonstrates how TAP separates planning from execution, enabling harnesses to validate completeness. For a failing test, the format introduces a negative result with additional diagnostic information to explain the discrepancy, often using a structured diff-like notation for expected versus actual values. Consider a scenario with two tests where the second fails:
1..2
ok 1 - Setup
not ok 2 - Function call
  +++ Expected
  +++ 'result'
  --- Actual
  +++ 'error'
The "not ok 2" line marks the failure, while the subsequent indented lines provide context through a simple key-value comparison, aiding without complicating the core parseable . This approach keeps diagnostics human-readable yet machine-ignorable, as they follow immediately after the test line. TAP also handles plan mismatches, where the number of reported tests deviates from the declared , triggering harness-level to flag incomplete or extraneous results. For instance, a for two followed by three results might yield:
1..2
ok 1 - First [test](/page/.test)
not ok 2 - Second [test](/page/.test)
ok 3 - Unexpected third [test](/page/.test)
In such cases, the harness would report an like "Looks like you planned 2 tests but ran 3," treating the excess as a in aggregation. This enforces strict counting to prevent silent omissions or additions in test suites. Consumers of TAP streams parse these elements by scanning for lines matching the pattern "^(not )?ok\s+\d+", incrementing an internal for each valid test line to track passes ("ok") and fails ("not ok") against the plan. Unnumbered tests auto-increment the counter, ensuring robustness, while any mismatch in total count results in an overall suite failure. This parsing logic prioritizes the test point ID for alignment, allowing harnesses to summarize results accurately even in edge cases.

Advanced Features

The Test Anything Protocol (TAP) supports several optional directives and structures that enhance test reporting flexibility, allowing producers to indicate exceptional conditions without altering the core pass/fail binary. These advanced features include skips, todos, diagnostics, bailouts, and subtests, each designed to provide context for test harnesses and consumers during and summarization. Skips mark tests that are intentionally not executed, often due to environmental constraints, and are reported as successful in summaries to avoid false failures. For instance, in a plan of three tests where the second is skipped:
1..3
ok 1 - Basic check
ok 2 # SKIP Platform not supported
ok 3 - Final check
Here, the skip directive follows the test line, and consumers treat the skipped test as passing, excluding it from failure counts while noting the reason separately in reports. Todos indicate tests expected to fail temporarily, enabling progress tracking on incomplete features; failing todo tests do not increment the overall failure tally. An example combines a todo with a YAML diagnostic for detailed failure context:
not ok 1 - Calculation error # TODO Fix later
  ---
  actual: 42
  expected: 24
The block, indented by two spaces, provides structured like actual and expected values, which harnesses can parse to enrich output without affecting the todo's non-failure in summaries. Bailouts signal catastrophic errors requiring immediate termination, prompting consumers to halt processing and report the suite as incomplete. A bailout after a partial run appears as:
1..1
ok 1 - Initial test
Bail out! Critical error
Upon encountering this directive, test harnesses cease counting further results and flag the entire output as failed due to the interruption. Introduced in TAP version 14, subtests enable nested test suites for modular organization, where an inner TAP stream is embedded under a parent test line. Consider this hierarchical example:
1..1
# Subtest: Nested suite
    1..2
    ok 1 - Inner pass
    not ok 2 - Inner fail
not ok 1 - Nested suite # Subtest: Nested suite
The subtest is indented by four spaces, and its outcome determines the parent test's result; consumers aggregate passes and failures from the subtest into the overall summary, treating skips or todos within it accordingly to maintain accurate counts.

References

  1. [1]
    Test Anything Protocol: Home
    TAP, the Test Anything Protocol, is a simple text-based interface between testing modules in a test harness. It decouples the reporting of errors from the ...TAP specificationSpecificationTAP ConsumersTAP version 13 specificationTesting with TAP
  2. [2]
    TAP 14 specification - Test Anything Protocol
    TAP14 is a text-based interface between testing modules and test harnesses, documenting observed behavior and providing guidance for new implementations.
  3. [3]
    TAP History - Test Anything Protocol
    TAP History. The protocol has been around since 1988. TAP Namespace Nonproliferation Treaty. TAP has roots from the Perl programming language.
  4. [4]
    The Kernel Test Anything Protocol (KTAP), version 1
    TAP, or the Test Anything Protocol is a format for specifying test results used by a number of projects. It's website and specification are found at this link.<|control11|><|separator|>
  5. [5]
    TAP specification - Test Anything Protocol
    TAP, the Test Anything Protocol, is Perl's simple text-based interface between testing modules such as Test::More and a test harness such as Test::Harness 2.x ...
  6. [6]
    Test::Harness - Run Perl standard test scripts with statistics
    Either Tim Bunce or Andreas Koenig, we don't know. What we know for sure is, that it was inspired by Larry Wall's F<TEST> script that came with perl ...
  7. [7]
    TestAnything/test-anything-protocol: A draft standard for ... - GitHub
    This is an attempt to write an Internet-Draft level document, setting out the Test Anything Protocol (TAP) as a language for storing, recording and ...<|control11|><|separator|>
  8. [8]
    More - yet another framework for writing test scripts - metacpan.org
    Test::More is a framework for writing test scripts, designed to be simple to learn and use, and prints 'ok' or 'not ok' based on test results.
  9. [9]
    TAP::Harness - Run test scripts with statistics - Perldoc Browser
    TAP::Harness is a simple test harness that runs tests, aggregates results, and outputs them to STDOUT. It uses the `runtests` method to run tests.
  10. [10]
    TAP::Parser - Parse TAP output - Perldoc Browser
    TAP::Parser is designed to produce a proper parse of TAP output. For an example of how to run tests through this module, see the simple harnesses examples.
  11. [11]
    prove - Run tests through a TAP harness. - Perldoc Browser
    ... date list of plugins available, please check CPAN: https://metacpan.org/search?q=App%3A%3AProve+Plugin. #Writing Plugins. Please see "PLUGINS" in App::Prove.
  12. [12]
    Devel::Cover - Code coverage metrics for Perl - metacpan.org
    This module provides code coverage metrics for Perl. Code coverage metrics describe how thoroughly tests exercise code.Missing: TAP advanced
  13. [13]
    Modules on CPAN alphabetically
    CPAN's 35102 modules distributions. in alphabetical order by modules contained in the distributions. Mon Nov 10 17:29:08 2025 UTC. The list contains modules ...
  14. [14]
  15. [15]
  16. [16]
  17. [17]
  18. [18]
  19. [19]
  20. [20]
  21. [21]
  22. [22]
    hepabolu/mytap: MySQL Unit Testing Suite - GitHub
    MyTAP is a unit testing framework for MySQL 5.x written using functions and procedures. It includes a collection of Test Anything Protocol (TAP) emitting ...
  23. [23]
    TetIntegration - FreeBSD Wiki
    Mar 30, 2021 · TET makes a set of assumptions about its execution environment that make integrating it in a BSD-compatible way into the base system complex.
  24. [24]
    TAP Producers - Test Anything Protocol
    TAP producers are systems that output TAP, and this page lists software libraries that act as TAP producers, grouped by programming language.
  25. [25]
    TAP 13 specification - Test Anything Protocol
    TAP13 is a text-based interface for testing, using a format with 'ok' or 'not ok' test lines, and a 'plan' to indicate the number of tests.