CINXE.COM

Test::Harness - run perl standard test scripts with statistics - Perldoc Browser

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Test::Harness - run perl standard test scripts with statistics - Perldoc Browser</title> <link rel="search" href="/opensearch.xml" type="application/opensearchdescription+xml" title="Perldoc Browser"> <link rel="canonical" href="https://perldoc.perl.org/Test::Harness"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/stackoverflow-light.min.css" integrity="sha512-cG1IdFxqipi3gqLmksLtuk13C+hBa57a6zpWxMeoY3Q9O6ooFxq50DayCdm0QrDgZjMUn23z/0PMZlgft7Yp5Q==" crossorigin="anonymous" /> <style> body { background: #f4f4f5; color: #020202; } .navbar-dark { background-image: -webkit-linear-gradient(top, #005f85 0, #002e49 100%); background-image: -o-linear-gradient(top, #005f85 0, #002e49 100%); background-image: linear-gradient(to bottom, #005f85 0, #002e49 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff005f85', endColorstr='#ff002e49', GradientType=0); background-repeat: repeat-x; } .navbar-dark .navbar-nav .nav-link, .navbar-dark .navbar-nav .nav-link:focus { color: #fff } .navbar-dark .navbar-nav .nav-link:hover { color: #ffef68 } #wrapperlicious { margin: 0 auto; font: 0.9em 'Helvetica Neue', Helvetica, sans-serif; font-weight: normal; line-height: 1.5em; margin: 0; padding: 0; } #wrapperlicious h1 { font-size: 1.5em } #wrapperlicious h2 { font-size: 1.3em } #wrapperlicious h3 { font-size: 1.1em } #wrapperlicious h4 { font-size: 0.9em } #wrapperlicious h1, #wrapperlicious h2, #wrapperlicious h3, #wrapperlicious h4, #wrapperlicious dt { color: #020202; margin-top: 1em; margin-bottom: 1em; position: relative; font-weight: bold; } #wrapperlicious a { color: inherit; text-decoration: underline } #wrapperlicious #toc { text-decoration: none } #wrapperlicious a:hover { color: #2a2a2a } #wrapperlicious a img { border: 0 } #wrapperlicious :not(pre) > code { color: inherit; background-color: rgba(0, 0, 0, 0.04); border-radius: 3px; font: 0.9em Consolas, Menlo, Monaco, monospace; padding: 0.3em; } #wrapperlicious dd { margin: 0; margin-left: 2em; } #wrapperlicious dt { color: #2a2a2a; font-weight: bold; margin-left: 0.9em; } #wrapperlicious p { margin-bottom: 1em; margin-top: 1em; } #wrapperlicious li > p { margin-bottom: 0; margin-top: 0; } #wrapperlicious pre { border: 1px solid #c1c1c1; border-radius: 3px; font: 100% Consolas, Menlo, Monaco, monospace; margin-bottom: 1em; margin-top: 1em; } #wrapperlicious pre > code { display: block; background-color: #f6f6f6; font: 0.9em Consolas, Menlo, Monaco, monospace; line-height: 1.5em; text-align: left; white-space: pre; padding: 1em; } #wrapperlicious dl, #wrapperlicious ol, #wrapperlicious ul { margin-bottom: 1em; margin-top: 1em; } #wrapperlicious ul { list-style-type: square; } #wrapperlicious ul ul { margin-bottom: 0px; margin-top: 0px; } #footer { font-size: 0.8em; padding-top: 0.5em; text-align: center; } #more { display: inline; font-size: 0.8em; } #perldocdiv { background-color: #fff; border: 1px solid #c1c1c1; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; margin-left: auto; margin-right: auto; padding: 3em; padding-top: 1em; max-width: 960px; } #moduleversion { float: right } #wrapperlicious .leading-notice { font-style: italic; padding-left: 1em; margin-top: 1em; margin-bottom: 1em; } #wrapperlicious .permalink { display: none; left: -0.75em; position: absolute; padding-right: 0.25em; text-decoration: none; } #wrapperlicious h1:hover .permalink, #wrapperlicious h2:hover .permalink, #wrapperlicious h3:hover .permalink, #wrapperlicious h4:hover .permalink, #wrapperlicious dt:hover .permalink { display: block; } </style> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-KVNWBNT5FB"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-KVNWBNT5FB'); gtag('config', 'UA-50555-3'); </script> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark justify-content-between"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="/"><img src="/images/perl_camel_30.png" width="30" height="30" class="d-inline-block align-top" alt="Perl Camel Logo"> Perldoc Browser</a> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav mr-auto"> <li class="nav-item dropdown text-nowrap"> <a class="nav-link dropdown-toggle" href="#" id="dropdownlink-stable" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">5.8.0</a> <div class="dropdown-menu" aria-labelledby="dropdownlink-stable"> <a class="dropdown-item" href="/Test::Harness">Latest</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.40.1/Test::Harness">5.40.1</a> <a class="dropdown-item" href="/5.40.0/Test::Harness">5.40.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.38.3/Test::Harness">5.38.3</a> <a class="dropdown-item" href="/5.38.2/Test::Harness">5.38.2</a> <a class="dropdown-item" href="/5.38.1/Test::Harness">5.38.1</a> <a class="dropdown-item" href="/5.38.0/Test::Harness">5.38.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.36.3/Test::Harness">5.36.3</a> <a class="dropdown-item" href="/5.36.2/Test::Harness">5.36.2</a> <a class="dropdown-item" href="/5.36.1/Test::Harness">5.36.1</a> <a class="dropdown-item" href="/5.36.0/Test::Harness">5.36.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.34.3/Test::Harness">5.34.3</a> <a class="dropdown-item" href="/5.34.2/Test::Harness">5.34.2</a> <a class="dropdown-item" href="/5.34.1/Test::Harness">5.34.1</a> <a class="dropdown-item" href="/5.34.0/Test::Harness">5.34.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.32.1/Test::Harness">5.32.1</a> <a class="dropdown-item" href="/5.32.0/Test::Harness">5.32.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.30.3/Test::Harness">5.30.3</a> <a class="dropdown-item" href="/5.30.2/Test::Harness">5.30.2</a> <a class="dropdown-item" href="/5.30.1/Test::Harness">5.30.1</a> <a class="dropdown-item" href="/5.30.0/Test::Harness">5.30.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.28.3/Test::Harness">5.28.3</a> <a class="dropdown-item" href="/5.28.2/Test::Harness">5.28.2</a> <a class="dropdown-item" href="/5.28.1/Test::Harness">5.28.1</a> <a class="dropdown-item" href="/5.28.0/Test::Harness">5.28.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.26.3/Test::Harness">5.26.3</a> <a class="dropdown-item" href="/5.26.2/Test::Harness">5.26.2</a> <a class="dropdown-item" href="/5.26.1/Test::Harness">5.26.1</a> <a class="dropdown-item" href="/5.26.0/Test::Harness">5.26.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.24.4/Test::Harness">5.24.4</a> <a class="dropdown-item" href="/5.24.3/Test::Harness">5.24.3</a> <a class="dropdown-item" href="/5.24.2/Test::Harness">5.24.2</a> <a class="dropdown-item" href="/5.24.1/Test::Harness">5.24.1</a> <a class="dropdown-item" href="/5.24.0/Test::Harness">5.24.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.22.4/Test::Harness">5.22.4</a> <a class="dropdown-item" href="/5.22.3/Test::Harness">5.22.3</a> <a class="dropdown-item" href="/5.22.2/Test::Harness">5.22.2</a> <a class="dropdown-item" href="/5.22.1/Test::Harness">5.22.1</a> <a class="dropdown-item" href="/5.22.0/Test::Harness">5.22.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.20.3/Test::Harness">5.20.3</a> <a class="dropdown-item" href="/5.20.2/Test::Harness">5.20.2</a> <a class="dropdown-item" href="/5.20.1/Test::Harness">5.20.1</a> <a class="dropdown-item" href="/5.20.0/Test::Harness">5.20.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.18.4/Test::Harness">5.18.4</a> <a class="dropdown-item" href="/5.18.3/Test::Harness">5.18.3</a> <a class="dropdown-item" href="/5.18.2/Test::Harness">5.18.2</a> <a class="dropdown-item" href="/5.18.1/Test::Harness">5.18.1</a> <a class="dropdown-item" href="/5.18.0/Test::Harness">5.18.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.16.3/Test::Harness">5.16.3</a> <a class="dropdown-item" href="/5.16.2/Test::Harness">5.16.2</a> <a class="dropdown-item" href="/5.16.1/Test::Harness">5.16.1</a> <a class="dropdown-item" href="/5.16.0/Test::Harness">5.16.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.14.4/Test::Harness">5.14.4</a> <a class="dropdown-item" href="/5.14.3/Test::Harness">5.14.3</a> <a class="dropdown-item" href="/5.14.2/Test::Harness">5.14.2</a> <a class="dropdown-item" href="/5.14.1/Test::Harness">5.14.1</a> <a class="dropdown-item" href="/5.14.0/Test::Harness">5.14.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.12.5/Test::Harness">5.12.5</a> <a class="dropdown-item" href="/5.12.4/Test::Harness">5.12.4</a> <a class="dropdown-item" href="/5.12.3/Test::Harness">5.12.3</a> <a class="dropdown-item" href="/5.12.2/Test::Harness">5.12.2</a> <a class="dropdown-item" href="/5.12.1/Test::Harness">5.12.1</a> <a class="dropdown-item" href="/5.12.0/Test::Harness">5.12.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.10.1/Test::Harness">5.10.1</a> <a class="dropdown-item" href="/5.10.0/Test::Harness">5.10.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.8.9/Test::Harness">5.8.9</a> <a class="dropdown-item" href="/5.8.8/Test::Harness">5.8.8</a> <a class="dropdown-item" href="/5.8.7/Test::Harness">5.8.7</a> <a class="dropdown-item" href="/5.8.6/Test::Harness">5.8.6</a> <a class="dropdown-item" href="/5.8.5/Test::Harness">5.8.5</a> <a class="dropdown-item" href="/5.8.4/Test::Harness">5.8.4</a> <a class="dropdown-item" href="/5.8.3/Test::Harness">5.8.3</a> <a class="dropdown-item" href="/5.8.2/Test::Harness">5.8.2</a> <a class="dropdown-item" href="/5.8.1/Test::Harness">5.8.1</a> <a class="dropdown-item active" href="/5.8.0/Test::Harness">5.8.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.6.2/Test::Harness">5.6.2</a> <a class="dropdown-item" href="/5.6.1/Test::Harness">5.6.1</a> <a class="dropdown-item" href="/5.6.0/Test::Harness">5.6.0</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.005_04/Test::Harness">5.005_04</a> <a class="dropdown-item" href="/5.005_03/Test::Harness">5.005_03</a> <a class="dropdown-item" href="/5.005_02/Test::Harness">5.005_02</a> <a class="dropdown-item" href="/5.005_01/Test::Harness">5.005_01</a> <a class="dropdown-item" href="/5.005/Test::Harness">5.005</a> </div> </li> <li class="nav-item dropdown text-nowrap"> <a class="nav-link dropdown-toggle" href="#" id="dropdownlink-dev" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dev</a> <div class="dropdown-menu" aria-labelledby="dropdownlink-dev"> <a class="dropdown-item" href="/blead/Test::Harness">blead</a> <a class="dropdown-item" href="/5.41.10/Test::Harness">5.41.10</a> <a class="dropdown-item" href="/5.41.9/Test::Harness">5.41.9</a> <a class="dropdown-item" href="/5.41.8/Test::Harness">5.41.8</a> <a class="dropdown-item" href="/5.41.7/Test::Harness">5.41.7</a> <a class="dropdown-item" href="/5.41.6/Test::Harness">5.41.6</a> <a class="dropdown-item" href="/5.41.5/Test::Harness">5.41.5</a> <a class="dropdown-item" href="/5.41.4/Test::Harness">5.41.4</a> <a class="dropdown-item" href="/5.41.3/Test::Harness">5.41.3</a> <a class="dropdown-item" href="/5.41.2/Test::Harness">5.41.2</a> <a class="dropdown-item" href="/5.41.1/Test::Harness">5.41.1</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.40.1-RC1/Test::Harness">5.40.1-RC1</a> <a class="dropdown-item" href="/5.40.0-RC2/Test::Harness">5.40.0-RC2</a> <a class="dropdown-item" href="/5.40.0-RC1/Test::Harness">5.40.0-RC1</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.39.10/Test::Harness">5.39.10</a> <a class="dropdown-item" href="/5.39.9/Test::Harness">5.39.9</a> <a class="dropdown-item" href="/5.39.8/Test::Harness">5.39.8</a> <a class="dropdown-item" href="/5.39.7/Test::Harness">5.39.7</a> <a class="dropdown-item" href="/5.39.6/Test::Harness">5.39.6</a> <a class="dropdown-item" href="/5.39.5/Test::Harness">5.39.5</a> <a class="dropdown-item" href="/5.39.4/Test::Harness">5.39.4</a> <a class="dropdown-item" href="/5.39.3/Test::Harness">5.39.3</a> <a class="dropdown-item" href="/5.39.2/Test::Harness">5.39.2</a> <a class="dropdown-item" href="/5.39.1/Test::Harness">5.39.1</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.38.3-RC1/Test::Harness">5.38.3-RC1</a> </div> </li> <li class="nav-item dropdown text-nowrap"> <a class="nav-link dropdown-toggle" href="#" id="dropdownlink-nav" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Documentation</a> <div class="dropdown-menu" aria-labelledby="dropdownlink-nav"> <a class="dropdown-item" href="/5.8.0/perl">Perl</a> <a class="dropdown-item" href="/5.8.0/perlintro">Intro</a> <a class="dropdown-item" href="/5.8.0/perl#Tutorials">Tutorials</a> <a class="dropdown-item" href="/5.8.0/perlfaq">FAQs</a> <a class="dropdown-item" href="/5.8.0/perl#Reference-Manual">Reference</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.8.0/perlop">Operators</a> <a class="dropdown-item" href="/5.8.0/functions">Functions</a> <a class="dropdown-item" href="/5.8.0/variables">Variables</a> <a class="dropdown-item" href="/5.8.0/modules">Modules</a> <a class="dropdown-item" href="/5.8.0/perlutil">Utilities</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="/5.8.0/perldelta">Release Notes</a> <a class="dropdown-item" href="/5.8.0/perlcommunity">Community</a> <a class="dropdown-item" href="/5.8.0/perlhist">History</a> </div> </li> </ul> <ul class="navbar-nav"> <script> function set_expand (expand) { var perldocdiv = document.getElementById('perldocdiv'); var width = window.getComputedStyle(perldocdiv).getPropertyValue('max-width'); var expanded = (width == '' || width == 'none') ? true : false; if (expand === null) { expand = !expanded; } if ((expand && !expanded) || (!expand && expanded)) { perldocdiv.style.setProperty('max-width', expand ? 'none' : '960px'); var button_classlist = document.getElementById('content-expand-button').classList; if (expand) { button_classlist.add('btn-light'); button_classlist.remove('btn-outline-light'); } else { button_classlist.add('btn-outline-light'); button_classlist.remove('btn-light'); } } return expand; } function toggle_expand () { var expand = set_expand(null); document.cookie = 'perldoc_expand=' + (expand ? 1 : 0) + '; path=/; expires=Tue, 19 Jan 2038 03:14:07 UTC'; } function read_expand () { return document.cookie.split(';').some(function (item) { return item.indexOf('perldoc_expand=1') >= 0 }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function () { if (read_expand()) { set_expand(true); } }); } else if (read_expand()) { set_expand(true); } </script> <button id="content-expand-button" type="button" class="btn btn-outline-light d-none d-lg-inline-block mr-4" onclick="toggle_expand()">Expand</button> </ul> <form class="form-inline" method="get" action="/5.8.0/search"> <input class="form-control mr-3" type="search" name="q" placeholder="Search" aria-label="Search" value=""> </form> </div> </nav> <div id="wrapperlicious" class="container-fluid"> <div id="perldocdiv"> <div id="links"> <a href="/5.8.0/Test::Harness">Test::Harness</a> <div id="more"> (<a href="/5.8.0/Test::Harness.txt">source</a>, <a href="https://metacpan.org/pod/Test::Harness">CPAN</a>) </div> <div id="moduleversion">version 2.26</div> </div> <div class="leading-notice"> You are viewing the version of this documentation from Perl 5.8.0. <a href="/Test::Harness">View the latest version</a> </div> <h1><a id="toc">CONTENTS</a></h1> <ul> <li> <a class="text-decoration-none" href="#NAME">NAME</a> </li> <li> <a class="text-decoration-none" href="#SYNOPSIS">SYNOPSIS</a> </li> <li> <a class="text-decoration-none" href="#DESCRIPTION">DESCRIPTION</a> <ul> <li> <a class="text-decoration-none" href="#The-test-script-output">The test script output</a> </li> <li> <a class="text-decoration-none" href="#Taint-mode">Taint mode</a> </li> <li> <a class="text-decoration-none" href="#Configuration-variables.">Configuration variables.</a> </li> <li> <a class="text-decoration-none" href="#Failure">Failure</a> </li> <li> <a class="text-decoration-none" href="#Functions">Functions</a> </li> </ul> </li> <li> <a class="text-decoration-none" href="#EXPORT">EXPORT</a> </li> <li> <a class="text-decoration-none" href="#DIAGNOSTICS">DIAGNOSTICS</a> </li> <li> <a class="text-decoration-none" href="#ENVIRONMENT">ENVIRONMENT</a> </li> <li> <a class="text-decoration-none" href="#EXAMPLE">EXAMPLE</a> </li> <li> <a class="text-decoration-none" href="#SEE-ALSO">SEE ALSO</a> </li> <li> <a class="text-decoration-none" href="#AUTHORS">AUTHORS</a> </li> <li> <a class="text-decoration-none" href="#TODO">TODO</a> </li> <li> <a class="text-decoration-none" href="#BUGS">BUGS</a> </li> </ul> <h1 id="NAME"><a class="permalink" href="#NAME">#</a>NAME</h1> <p>Test::Harness - run perl standard test scripts with statistics</p> <h1 id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">#</a>SYNOPSIS</h1> <pre><code>use Test::Harness; runtests(@test_files);</code></pre> <h1 id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">#</a>DESCRIPTION</h1> <p><b>STOP!</b> If all you want to do is write a test script, consider using Test::Simple. Otherwise, read on.</p> <p>(By using the Test module, you can write test scripts without knowing the exact output this module expects. However, if you need to know the specifics, read on!)</p> <p>Perl test scripts print to standard output <code>&quot;ok N&quot;</code> for each single test, where <code>N</code> is an increasing sequence of integers. The first line output by a standard test script is <code>&quot;1..M&quot;</code> with <code>M</code> being the number of tests that should be run within the test script. Test::Harness::runtests(@tests) runs all the testscripts named as arguments and checks standard output for the expected <code>&quot;ok N&quot;</code> strings.</p> <p>After all tests have been performed, runtests() prints some performance statistics that are computed by the Benchmark module.</p> <h2 id="The-test-script-output"><a class="permalink" href="#The-test-script-output">#</a><a id="The"></a>The test script output</h2> <p>The following explains how Test::Harness interprets the output of your test program.</p> <dl> <dt id="&#39;1..M&#39;"><a class="permalink" href="#&#39;1..M&#39;">#</a><a id="M"></a><b>&#39;1..M&#39;</b></dt> <dd> <p>This header tells how many tests there will be. For example, <code>1..10</code> means you plan on running 10 tests. This is a safeguard in case your test dies quietly in the middle of its run.</p> <p>It should be the first non-comment line output by your test program.</p> <p>In certain instances, you may not know how many tests you will ultimately be running. In this case, it is permitted for the 1..M header to appear as the <b>last</b> line output by your test (again, it can be followed by further comments).</p> <p>Under <b>no</b> circumstances should 1..M appear in the middle of your output or more than once.</p> </dd> <dt id="&#39;ok&#39;,-&#39;not-ok&#39;.-Ok?"><a class="permalink" href="#&#39;ok&#39;,-&#39;not-ok&#39;.-Ok?">#</a><a id="ok-not-ok.-Ok"></a><b>&#39;ok&#39;, &#39;not ok&#39;. Ok?</b></dt> <dd> <p>Any output from the testscript to standard error is ignored and bypassed, thus will be seen by the user. Lines written to standard output containing <code>/^(not\s+)?ok\b/</code> are interpreted as feedback for runtests(). All other lines are discarded.</p> <p><code>/^not ok/</code> indicates a failed test. <code>/^ok/</code> is a successful test.</p> </dd> <dt id="test-numbers"><a class="permalink" href="#test-numbers">#</a><a id="test"></a><b>test numbers</b></dt> <dd> <p>Perl normally expects the &#39;ok&#39; or &#39;not ok&#39; to be followed by a test number. It is tolerated if the test numbers after &#39;ok&#39; are omitted. In this case Test::Harness maintains temporarily its own counter until the script supplies test numbers again. So the following test script</p> <pre><code>print &lt;&lt;END; 1..6 not ok ok not ok ok ok END</code></pre> <p>will generate</p> <pre><code class="plaintext">FAILED tests 1, 3, 6 Failed 3/6 tests, 50.00% okay</code></pre> </dd> <dt id="test-names"><a class="permalink" href="#test-names">#</a><a id="test1"></a><b>test names</b></dt> <dd> <p>Anything after the test number but before the # is considered to be the name of the test.</p> <pre><code class="plaintext">ok 42 this is the name of the test</code></pre> <p>Currently, Test::Harness does nothing with this information.</p> </dd> <dt id="Skipping-tests"><a class="permalink" href="#Skipping-tests">#</a><a id="Skipping"></a><b>Skipping tests</b></dt> <dd> <p>If the standard output line contains the substring <code> # Skip</code> (with variations in spacing and case) after <code>ok</code> or <code>ok NUMBER</code>, it is counted as a skipped test. If the whole testscript succeeds, the count of skipped tests is included in the generated output. <code>Test::Harness</code> reports the text after <code> # Skip\S*\s+</code> as a reason for skipping.</p> <pre><code class="plaintext">ok 23 # skip Insufficient flogiston pressure.</code></pre> <p>Similarly, one can include a similar explanation in a <code>1..0</code> line emitted if the test script is skipped completely:</p> <pre><code class="plaintext">1..0 # Skipped: no leverage found</code></pre> </dd> <dt id="Todo-tests"><a class="permalink" href="#Todo-tests">#</a><a id="Todo"></a><b>Todo tests</b></dt> <dd> <p>If the standard output line contains the substring <code> # TODO</code> after <code>not ok</code> or <code>not ok NUMBER</code>, it is counted as a todo test. The text afterwards is the thing that has to be done before this test will succeed.</p> <pre><code class="plaintext">not ok 13 # TODO harness the power of the atom</code></pre> <p>These tests represent a feature to be implemented or a bug to be fixed and act as something of an executable &quot;thing to do&quot; list. They are <b>not</b> expected to succeed. Should a todo test begin succeeding, Test::Harness will report it as a bonus. This indicates that whatever you were supposed to do has been done and you should promote this to a normal test.</p> </dd> <dt id="Bail-out!"><a class="permalink" href="#Bail-out!">#</a><a id="Bail"></a><a id="Bail-out"></a><b>Bail out!</b></dt> <dd> <p>As an emergency measure, a test script can decide that further tests are useless (e.g. missing dependencies) and testing should stop immediately. In that case the test script prints the magic words</p> <pre><code class="plaintext">Bail out!</code></pre> <p>to standard output. Any message after these words will be displayed by <code>Test::Harness</code> as the reason why testing is stopped.</p> </dd> <dt id="Comments"><a class="permalink" href="#Comments">#</a><b>Comments</b></dt> <dd> <p>Additional comments may be put into the testing output on their own lines. Comment lines should begin with a &#39;#&#39;, Test::Harness will ignore them.</p> <pre><code class="plaintext">ok 1 # Life is good, the sun is shining, RAM is cheap. not ok 2 # got &#39;Bush&#39; expected &#39;Gore&#39;</code></pre> </dd> <dt id="Anything-else"><a class="permalink" href="#Anything-else">#</a><a id="Anything"></a><b>Anything else</b></dt> <dd> <p>Any other output Test::Harness sees it will silently ignore <b>BUT WE PLAN TO CHANGE THIS!</b> If you wish to place additional output in your test script, please use a comment.</p> </dd> </dl> <h2 id="Taint-mode"><a class="permalink" href="#Taint-mode">#</a><a id="Taint"></a>Taint mode</h2> <p>Test::Harness will honor the <code>-T</code> in the #! line on your test files. So if you begin a test with:</p> <pre><code class="plaintext">#!perl -T</code></pre> <p>the test will be run with taint mode on.</p> <h2 id="Configuration-variables."><a class="permalink" href="#Configuration-variables.">#</a><a id="Configuration"></a><a id="Configuration-variables"></a>Configuration variables.</h2> <p>These variables can be used to configure the behavior of Test::Harness. They are exported on request.</p> <dl> <dt id="$Test::Harness::verbose"><a class="permalink" href="#$Test::Harness::verbose">#</a><a id="Test::Harness::verbose"></a><b>$Test::Harness::verbose</b></dt> <dd> <p>The global variable $Test::Harness::verbose is exportable and can be used to let runtests() display the standard output of the script without altering the behavior otherwise.</p> </dd> <dt id="$Test::Harness::switches"><a class="permalink" href="#$Test::Harness::switches">#</a><a id="Test::Harness::switches"></a><b>$Test::Harness::switches</b></dt> <dd> <p>The global variable $Test::Harness::switches is exportable and can be used to set perl command line options used for running the test script(s). The default value is <code>-w</code>.</p> </dd> </dl> <h2 id="Failure"><a class="permalink" href="#Failure">#</a>Failure</h2> <p>It will happen, your tests will fail. After you mop up your ego, you can begin examining the summary report:</p> <pre><code class="plaintext">t/base..............ok t/nonumbers.........ok t/ok................ok t/test-harness......ok t/waterloo..........dubious Test returned status 3 (wstat 768, 0x300) DIED. FAILED tests 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 Failed 10/20 tests, 50.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ----------------------------------------------------------------------- t/waterloo.t 3 768 20 10 50.00% 1 3 5 7 9 11 13 15 17 19 Failed 1/5 test scripts, 80.00% okay. 10/44 subtests failed, 77.27% okay.</code></pre> <p>Everything passed but t/waterloo.t. It failed 10 of 20 tests and exited with non-zero status indicating something dubious happened.</p> <p>The columns in the summary report mean:</p> <dl> <dt id="Failed-Test"><a class="permalink" href="#Failed-Test">#</a><a id="Failed1"></a><b>Failed Test</b></dt> <dd> <p>The test file which failed.</p> </dd> <dt id="Stat"><a class="permalink" href="#Stat">#</a><b>Stat</b></dt> <dd> <p>If the test exited with non-zero, this is its exit status.</p> </dd> <dt id="Wstat"><a class="permalink" href="#Wstat">#</a><b>Wstat</b></dt> <dd> <p>The wait status of the test <i>umm, I need a better explanation here</i>.</p> </dd> <dt id="Total"><a class="permalink" href="#Total">#</a><b>Total</b></dt> <dd> <p>Total number of tests expected to run.</p> </dd> <dt id="Fail"><a class="permalink" href="#Fail">#</a><b>Fail</b></dt> <dd> <p>Number which failed, either from &quot;not ok&quot; or because they never ran.</p> </dd> <dt id="Failed"><a class="permalink" href="#Failed">#</a><b>Failed</b></dt> <dd> <p>Percentage of the total tests which failed.</p> </dd> <dt id="List-of-Failed"><a class="permalink" href="#List-of-Failed">#</a><a id="List"></a><b>List of Failed</b></dt> <dd> <p>A list of the tests which failed. Successive failures may be abbreviated (ie. 15-20 to indicate that tests 15, 16, 17, 18, 19 and 20 failed).</p> </dd> </dl> <h2 id="Functions"><a class="permalink" href="#Functions">#</a>Functions</h2> <p>Test::Harness currently only has one function, here it is.</p> <dl> <dt id="runtests"><a class="permalink" href="#runtests">#</a><b>runtests</b></dt> <dd> <pre><code>my $allok = runtests(@test_files);</code></pre> <p>This runs all the given @test_files and divines whether they passed or failed based on their output to STDOUT (details above). It prints out each individual test which failed along with a summary report and a how long it all took.</p> <p>It returns true if everything was ok. Otherwise it will die() with one of the messages in the DIAGNOSTICS section.</p> </dd> </dl> <h1 id="EXPORT"><a class="permalink" href="#EXPORT">#</a>EXPORT</h1> <p><code>&amp;runtests</code> is exported by Test::Harness per default.</p> <p><code>$verbose</code> and <code>$switches</code> are exported upon request.</p> <h1 id="DIAGNOSTICS"><a class="permalink" href="#DIAGNOSTICS">#</a>DIAGNOSTICS</h1> <dl> <dt id="All-tests-successful.\nFiles=%d,-Tests=%d,-%s"><a class="permalink" href="#All-tests-successful.%5CnFiles=%25d,-Tests=%25d,-%25s">#</a><a id="All"></a><a id="All-tests-successful.-nFiles-d-Tests-d-s"></a><code>All tests successful.\nFiles=%d, Tests=%d, %s</code></dt> <dd> <p>If all tests are successful some statistics about the performance are printed.</p> </dd> <dt id="FAILED-tests-%s\n\tFailed-%d/%d-tests,-%.2f%%-okay."><a class="permalink" href="#FAILED-tests-%25s%5Cn%5CtFailed-%25d/%25d-tests,-%25.2f%25%25-okay.">#</a><a id="FAILED"></a><a id="FAILED-tests-s-n-tFailed-d-d-tests-.2f-okay"></a><code>FAILED tests %s\n\tFailed %d/%d tests, %.2f%% okay.</code></dt> <dd> <p>For any single script that has failing subtests statistics like the above are printed.</p> </dd> <dt id="Test-returned-status-%d-(wstat-%d)"><a class="permalink" href="#Test-returned-status-%25d-(wstat-%25d)">#</a><a id="Test"></a><a id="Test-returned-status-d-wstat-d"></a><code>Test returned status %d (wstat %d)</code></dt> <dd> <p>Scripts that return a non-zero exit status, both <code>$? &gt;&gt; 8</code> and <code>$?</code> are printed in a message similar to the above.</p> </dd> <dt id="Failed-1-test,-%.2f%%-okay.-%s"><a class="permalink" href="#Failed-1-test,-%25.2f%25%25-okay.-%25s">#</a><a id="Failed2"></a><a id="Failed-1-test-.2f-okay.-s"></a><code>Failed 1 test, %.2f%% okay. %s</code></dt> <dd> </dd> <dt id="Failed-%d/%d-tests,-%.2f%%-okay.-%s"><a class="permalink" href="#Failed-%25d/%25d-tests,-%25.2f%25%25-okay.-%25s">#</a><a id="Failed3"></a><a id="Failed-d-d-tests-.2f-okay.-s"></a><code>Failed %d/%d tests, %.2f%% okay. %s</code></dt> <dd> <p>If not all tests were successful, the script dies with one of the above messages.</p> </dd> <dt id="FAILED-Further-testing-stopped:-%s"><a class="permalink" href="#FAILED-Further-testing-stopped:-%25s">#</a><a id="FAILED1"></a><a id="FAILED--Further-testing-stopped:-s"></a><code>FAILED--Further testing stopped: %s</code></dt> <dd> <p>If a single subtest decides that further testing will not make sense, the script dies with this message.</p> </dd> </dl> <h1 id="ENVIRONMENT"><a class="permalink" href="#ENVIRONMENT">#</a>ENVIRONMENT</h1> <dl> <dt id="HARNESS_ACTIVE"><a class="permalink" href="#HARNESS_ACTIVE">#</a><code>HARNESS_ACTIVE</code></dt> <dd> <p>Harness sets this before executing the individual tests. This allows the tests to determine if they are being executed through the harness or by any other means.</p> </dd> <dt id="HARNESS_COLUMNS"><a class="permalink" href="#HARNESS_COLUMNS">#</a><code>HARNESS_COLUMNS</code></dt> <dd> <p>This value will be used for the width of the terminal. If it is not set then it will default to <code>COLUMNS</code>. If this is not set, it will default to 80. Note that users of Bourne-sh based shells will need to <code>export COLUMNS</code> for this module to use that variable.</p> </dd> <dt id="HARNESS_COMPILE_TEST"><a class="permalink" href="#HARNESS_COMPILE_TEST">#</a><code>HARNESS_COMPILE_TEST</code></dt> <dd> <p>When true it will make harness attempt to compile the test using <code>perlcc</code> before running it.</p> <p><b>NOTE</b> This currently only works when sitting in the perl source directory!</p> </dd> <dt id="HARNESS_FILELEAK_IN_DIR"><a class="permalink" href="#HARNESS_FILELEAK_IN_DIR">#</a><code>HARNESS_FILELEAK_IN_DIR</code></dt> <dd> <p>When set to the name of a directory, harness will check after each test whether new files appeared in that directory, and report them as</p> <pre><code class="plaintext">LEAKED FILES: scr.tmp 0 my.db</code></pre> <p>If relative, directory name is with respect to the current directory at the moment runtests() was called. Putting absolute path into <code>HARNESS_FILELEAK_IN_DIR</code> may give more predictable results.</p> </dd> <dt id="HARNESS_IGNORE_EXITCODE"><a class="permalink" href="#HARNESS_IGNORE_EXITCODE">#</a><code>HARNESS_IGNORE_EXITCODE</code></dt> <dd> <p>Makes harness ignore the exit status of child processes when defined.</p> </dd> <dt id="HARNESS_NOTTY"><a class="permalink" href="#HARNESS_NOTTY">#</a><code>HARNESS_NOTTY</code></dt> <dd> <p>When set to a true value, forces it to behave as though STDOUT were not a console. You may need to set this if you don&#39;t want harness to output more frequent progress messages using carriage returns. Some consoles may not handle carriage returns properly (which results in a somewhat messy output).</p> </dd> <dt id="HARNESS_PERL_SWITCHES"><a class="permalink" href="#HARNESS_PERL_SWITCHES">#</a><code>HARNESS_PERL_SWITCHES</code></dt> <dd> <p>Its value will be prepended to the switches used to invoke perl on each test. For example, setting <code>HARNESS_PERL_SWITCHES</code> to <code>-W</code> will run all tests with all warnings enabled.</p> </dd> <dt id="HARNESS_VERBOSE"><a class="permalink" href="#HARNESS_VERBOSE">#</a><code>HARNESS_VERBOSE</code></dt> <dd> <p>If true, Test::Harness will output the verbose results of running its tests. Setting $Test::Harness::verbose will override this.</p> </dd> </dl> <h1 id="EXAMPLE"><a class="permalink" href="#EXAMPLE">#</a>EXAMPLE</h1> <p>Here&#39;s how Test::Harness tests itself</p> <pre><code>$ cd ~/src/devel/Test-Harness $ perl -Mblib -e &#39;use Test::Harness qw(&amp;runtests $verbose); $verbose=0; runtests @ARGV;&#39; t/*.t Using /home/schwern/src/devel/Test-Harness/blib t/base..............ok t/nonumbers.........ok t/ok................ok t/test-harness......ok All tests successful. Files=4, Tests=24, 2 wallclock secs ( 0.61 cusr + 0.41 csys = 1.02 CPU)</code></pre> <h1 id="SEE-ALSO"><a class="permalink" href="#SEE-ALSO">#</a><a id="SEE"></a>SEE ALSO</h1> <p><a href="/5.8.0/Test">Test</a> and <a href="/5.8.0/Test::Simple">Test::Simple</a> for writing test scripts, <a href="/5.8.0/Benchmark">Benchmark</a> for the underlying timing routines, <a href="/5.8.0/Devel::CoreStack">Devel::CoreStack</a> to generate core dumps from failed tests and <a href="/5.8.0/Devel::Cover">Devel::Cover</a> for test coverage analysis.</p> <h1 id="AUTHORS"><a class="permalink" href="#AUTHORS">#</a>AUTHORS</h1> <p>Either Tim Bunce or Andreas Koenig, we don&#39;t know. What we know for sure is, that it was inspired by Larry Wall&#39;s TEST script that came with perl distributions for ages. Numerous anonymous contributors exist. Andreas Koenig held the torch for many years.</p> <p>Current maintainer is Michael G Schwern &lt;schwern@pobox.com&gt;</p> <h1 id="TODO"><a class="permalink" href="#TODO">#</a>TODO</h1> <p>Provide a way of running tests quietly (ie. no printing) for automated validation of tests. This will probably take the form of a version of runtests() which rather than printing its output returns raw data on the state of the tests. (Partially done in Test::Harness::Straps)</p> <p>Fix HARNESS_COMPILE_TEST without breaking its core usage.</p> <p>Figure a way to report test names in the failure summary.</p> <p>Rework the test summary so long test names are not truncated as badly. (Partially done with new skip test styles)</p> <p>Deal with VMS&#39;s &quot;not \nok 4\n&quot; mistake.</p> <p>Add option for coverage analysis.</p> <h1 id="BUGS"><a class="permalink" href="#BUGS">#</a>BUGS</h1> <p>HARNESS_COMPILE_TEST currently assumes it&#39;s run from the Perl source directory.</p> </div> <div id="footer"> <p>Perldoc Browser is maintained by Dan Book (<a href="https://metacpan.org/author/DBOOK">DBOOK</a>). Please contact him via the <a href="https://github.com/Grinnz/perldoc-browser/issues">GitHub issue tracker</a> or <a href="mailto:dbook@cpan.org">email</a> regarding any issues with the site itself, search, or rendering of documentation.</p> <p>The Perl documentation is maintained by the Perl 5 Porters in the development of Perl. Please contact them via the <a href="https://github.com/Perl/perl5/issues">Perl issue tracker</a>, the <a href="https://lists.perl.org/list/perl5-porters.html">mailing list</a>, or <a href="https://kiwiirc.com/client/irc.perl.org/p5p">IRC</a> to report any issues with the contents or format of the documentation.</p> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.slim.min.js" integrity="sha512-/DXTXr6nQodMUiq+IUJYCt2PPOUjrHJ9wFrqpJ3XkgPNOZVfMok7cRw6CSxyCQxXn6ozlESsSh1/sMCTF1rL/g==" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js" integrity="sha512-ubuT8Z88WxezgSqf3RLuNi5lmjstiJcyezx34yIU2gAHonIi27Na7atqzUZCOoY4CExaoFumzOsFQ2Ch+I/HCw==" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script> <script src="/js/highlight.pack.js"></script> <script>hljs.highlightAll();</script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10