docs/tests.pod - Testing Parrot


This is quick and dirty primer on to how the Parrot test suite is executed and to how new tests for Parrot should be written. The testing system is liable to change in the future, but tests written following the guidelines below should be easy to port into a new test suite.


The easy way to test parrot is running make test. If you have updated your code recently and tests began failing, go for a make realclean and recompile parrot before complaining.

make all_hll_test runs the test suite for all known working HLLs and libraries.

Submitting smolder test results

Parrot has a status page with smoke test results at

You can supply new tests results by just running make smoke. It will run the same tests as make test would, but will upload the test results to the website.


The parrot test files, the *.t files, can be found in the t directory. A quick overview about each test directory in t can be found in t/README.

New tests should be added to an existing *.t file. If a previously untested feature is tested, it might also make sense to create a new *.t file. You may also see tests named like foo-old.t, which are Perl tests that are in the process of being translated to PIR.


Test scripts must emit text that conforms to the Test Anything Protocol. Test scripts are currently usually written in PIR or Perl 5. The Perl 5 module Parrot::Test and the PIR module Test;More help with writing tests. Writing tests in PIR is preferred, but there are some cases where the proper framework is not available. If you can, write your tests in PIR.

The testing framework needs to know how many tests it should expect. So the number of planned tests needs to be incremented when adding a new test. This is done near the top of a test file, in a line that looks like:


in PIR tests and

  use Parrot::Test tests => 8;

for Perl 5 test scripts.

Testing Parrot Assembler

PASM tests are mostly used for testing ops. Appropriate test files for basic ops are t/op/*.t. Polymorphic Containers are tested in t/pmc/*.t. Add the new test like this:

    pasm_output_is(<<'CODE', <<'OUTPUT', "name for test");
        *** a big chunk of assembler, eg:
        print   1
        print   "\n" # you can even comment it if it's obscure
        end          # don't forget this...!
    *** what you expect the output of the chunk to be, eg.

Testing Parrot Intermediate Representation

Writing tests in PIR is more convenient. This is done with pir_output_is and friends.

    pir_output_is(<<'CODE',<<'OUT','nothing useful');
        .sub main :main
            print "hi\n"

Testing C source

C source tests are usually located in t/src/*.t. A simple test looks like:

    c_output_is(<<'CODE', <<'OUTPUT', "name for test");
    #include <stdio.h>
    #include "parrot/parrot.h"

    int main(int argc, char* argv[]) {
        Parrot_Interp interp;
        interpreter = Parrot_new(NULL);

        if (!interpreter)
            return 1;

        /* Your test goes here. */

        return 0;

    # Anything that might be output prior to "done".

Note that it's always a good idea to output "done" to confirm that the compiled code executed completely. When mixing printf and Parrot_io_printf always append a fflush(stdout); after the former.

Testing Perl5 components

At the present time most, if not all, of the programs used to configure, build and install Parrot are written in Perl 5. These programs take the form of program files (*.pl) and Perl modules (*.pm) holding subroutines and other variables imported into the program files. Examples of such program files can be found under tools/; examples of such Perl modules can be found under lib/Parrot/.

All of these Perl 5 components ought to be tested. Fortunately, over the last decade, under the leadership of Michael Schwern, chromatic, Andy Lester and many others, the Perl 5 community has developed a rigorous approach to testing in which:

Subroutines found in *.pl files are extracted and placed in *.pm modules.
Those subroutines are then imported back into the program file.
Those subroutines are also imported into test files (*.t) where are tests are run by Test::Builder-based modules such as Test::Simple and Test::More.
Those test files are run by Test::Harness-based functionality such as ExtUtils::MakeMaker's make test, Module::Build's build test, or Test::Harness's prove.
The extent to which the test files exercise all statements in the Perl modules being tested is measured in coverage analysis using CPAN module Devel::Cover.
The underlying code is refactored and improved on the basis of the results of tests and coverage analysis.

Tests reflecting this approach can be found in t/configure/, t/postconfigure/, t/tools/, and so on.

It is our objective to test all Perl 5 components of the Parrot distribution using the methodology above.

Build Tools Tests

The files in t/postconfigure are tests for build system. The build tools tests are intended to be run after someone has made changes in modules such as lib/Parrot/Pmc2cUtils/. They're set up to be run after has completed but before make has been invoked. (In fact, they will generate errors if make has completed.) You can run them with any of the following:

     perl --test
     perl --test=build
     make buildtools_tests  (following

Testing language implementations

Language implementations are usually tested with language_output_is and friends.



In test driven development, tests are implemented first. So the tests are initially expected to fail. This can be expressed by marking the tests as TODO. See Test::More on how to do that.


TODO test actually executed, so that unexpected success can be detected. In the case of missing requirements and in the case of serious breakdowns the execution of tests can be skipped. See Test::More on how to do that.


Parrot uses several smoker services.

Our own make smoke test results are at

All smoke-me/ and master branch changes are automatically smoked on linux and darwin at

You can trigger manual win32 and win64 smokes with MSVC 10 and 12 for the smoke-me/appveyor branch at