Did you know ... Search Documentation:
Packs (add-ons) for SWI-Prolog

Package "tap"

Title:Automated tests via Test Anything Protocol
Rating:Not rated. Create the first rating!
Latest version:1.0.3
SHA1 sum:b970bdd7d445ee0026e191368eb4915594ee5561
Author:Falco Nogatz <fnogatz@gmail.com>
Michael Hendricks <michael@ndrix.org>
Maintainer:Falco Nogatz <fnogatz@gmail.com>
Packager:Falco Nogatz <fnogatz@gmail.com>
Home page:https://github.com/fnogatz/tap
Download URL:https://github.com/fnogatz/tap/archive/v1.0.3.zip

Reviews

No reviews. Create the first review!.

Details by download location

VersionSHA1#DownloadsURL
1.0.3b970bdd7d445ee0026e191368eb4915594ee556131https://github.com/fnogatz/tap.git
624550c42e6dca3dbd38a4b6ed9ee387f852b536914https://github.com/fnogatz/tap.git
849f859421153b4dc57ed764a67db0774c4a4a176https://github.com/fnogatz/tap.git
1a2cc1bbd0579ec5d25a0358ec2e20c68aec1aa84686https://github.com/fnogatz/tap.git
1.0.25ad72531d3d81a68071186821dc6814d7faee00812https://github.com/fnogatz/tap.git
1.0.1483e785f3a417b151331641bc34d7d776d18bcf510https://github.com/fnogatz/tap.git
0f9c1d51a51d0e28324438608c91c2afe641a57132https://github.com/fnogatz/tap.git
76b0080a7e2f4a887a9783da80b9baf440fcf9843https://github.com/fnogatz/tap.git
d5ac051a1eeaed6b51c74a9ceddf21cae71fc6dd2https://github.com/fnogatz/tap.git
6a297acc8f7ae06687ca2a7e54d6dd1932256bfa10https://github.com/fnogatz/tap.git
1.0.06e05ed5dbf0593be4dfe5d7e596a50958b7ca8a81https://github.com/fnogatz/tap.git
0.5.20fb7bfa82745a2fcccd9229da4d845dac02db6701https://github.com/fnogatz/tap.git
0.4.2a4386fe8282a5df9f60e46acaf7403f05fc6daa21https://github.com/fnogatz/tap.git
deb58a46c3b27499f736750d08eb39162cb182a939https://github.com/fnogatz/tap.git
0.4.1b0e5f6030e780fccef80254ae1ecafa80496b9422https://github.com/fnogatz/tap.git
0.4.030a54dee1032cf4880ec95d6c3037726f1be2c7c119https://github.com/mndrix/tap/archive/v0.4.0.zip
0.3.1aa1d51dc560aea6cf424ec8aafa090e362870e0738https://github.com/mndrix/tap/archive/v0.3.1.zip
375fe8e5786df8dea715a09a19643bf082c48a062https://github.com/fnogatz/tap.git
0.3.0a7df1eeb094415112484c47eb17170e7d1fef3222https://github.com/mndrix/tap/archive/v0.3.0.zip
0.2.48619414b212748df645b88f122bd51809be96ed69http://packs.ndrix.com/tap/tap-0.2.4.tgz
0.2.3dc6b18227092c3bd5fd909c47ea08098a51f403d12http://packs.ndrix.com/tap/tap-0.2.3.tgz
0.2.238bedd090013639dcd50e9905428c1cbcc5dd4911http://packs.ndrix.com/tap/tap-0.2.2.tgz
0.2.161d05dfccdce3c4237dce669b14bc0735ad74ad11http://packs.ndrix.com/tap/tap-0.2.1.tgz
0.2.05de160dcb470f5c810b7e7d3aa51a96ff8bb300c2http://packs.ndrix.com/tap/tap-0.2.0.tgz
0.1.2dbd5b55c8abfb7b798f78130c5c2a3cf90a8f0332http://packs.ndrix.com/tap/tap-0.1.2.tgz
0.1.037e8086312349162a5f5d67fbbd2975d41345f663http://packs.ndrix.com/tap/tap-0.1.0.tgz
0.0.189f410ae8ec511e24eeead0226a44b252b892c511http://packs.ndrix.com/tap/tap-0.0.1.tgz

Synopsis

:- use_module(to_be_tested).
% define helper predicates here

:- use_module(library(tap)).
% define test predicates here

'two plus two is four' :-
    4 is 2+2.

'zero not equal to one'(fail) :-
    0 =:= 1.

6 is 3*2.

Run tests with standard TAP tools like prove:

$ prove -v -e 'swipl -q -t main -s' test/examples.pl
TAP version 13
1..4
ok 1 - simplest possible test case
ok 2 - simplest failing test case
ok 3 - generates a diagnostic message
# I'm a diagnostic message
ok 4 - long-running test case

# time=1.0ms
# tests 4
# pass  4

Description

The Test Anything Protocol is a text-based interface between test scripts and a test harness. A wide range of tools exist for running, rendering and analyzing test results. By writing your Prolog tests with TAP, you get access to all this testing infrastructure. For example, interactive HTML output.

TAP tests traditionally reside in a t/ directory in your project's root. Each file beneath t/ encapsulates a collection of tests related to a specific topic. During development, one can run all test files or just an interesting subset. In its most basic form, a test file is a script which generates TAP output. library(tap) helps you write these scripts.

To write a test file with library(tap), load all code that you'll need for testing. Define any helper predicates. Then load library(tap). All predicates defined after loading library(tap) are considered test cases. The predicate's name is the test name. By default, a predicate must succeed without leaving any choicepoints for the test to pass. See Arguments section below to change that behavior.

For small tests (see 6 is 3*2 above), the name can be omitted. The test body is then used as the test name.

library(tap) does not yet support the entire TAP specification and is missing many features found in PlUnit. Both are temporary shortcomings. I expect the library to fill these gaps eventually.

<a name="arguments"></a>Arguments

A test predicate can optionally include arguments to change TAP's expectations about the test. Arguments look like this:

'test with arguments'(Arg1, Arg2, ...) :-
    ...

Acceptable arguments are:

  • error(E) - same as throws(E). Supported for symmetry with PlUnit.
  • fail - test is expected to fail
  • fixme(Reason) - same as todo(Reason). Supported for symmetry with PlUnit.
  • todo(Reason) - test is known to fail but report it in TAP output as "TODO Reason". TAP tools treat these tests differently.
  • todo - same as todo('')
  • throws(E) - throws exception E

<a name="macros"></a>Macros that write tests

It's common for each test case in a test file to follow a similar pattern. For example, we might have tests for the length/2 predicate:

:- use_module(library(tap)).
'length([a,b,c],3)' :-
    length([a,b,c], N),
    N = 3.
'length([a,b],2)' :-
    length([a,b], N),
    N = 2.
...

Because of all the similarity, that's tedious to write and tedious to read. We can factor out the redundancy by creating a macro:

% ... macro definition goes here ...

:- use_module(library(tap)).
[a,b,c] -> 3.
[a,b] -> 2.

That's much better. A regular term_expansion/2 macro that calls register_test/1 does the job:

term_expansion(List -> Length, (Head :- Test)) :-
    format(atom(Head), 'length(~w, ~w)', [List, Length]),
    Test = (
        length(List, Len),
        Len = Length
    ),
    tap:register_test(Head).

Without registering, our nicely constructed test case won't run. Macros are especially convenient when testing multiple modes of a single predicate. You can decribe the relationship once and have the macro write a separate test case for each mode.

Installation

Using SWI-Prolog 7.1 or later:

?- pack_install(tap).

Source code available and pull requests accepted at https://github.com/fnogatz/tap

This module uses semantic versioning.

Projects using library(tap)

Here is a non-exhaustive list of projects that use library(tap). Most of them use the macro approach, so they can be a good inspiration on how to define tests in Prolog:

Contents of pack "tap"

Pack contains 19 files holding a total of 17.9K bytes.