Testilence

Unit testing library for PHP 5

Author: Roman Neuhauser
Contact: neuhauser@sigpipe.cz
Copyright: This document has been placed in the public domain.
Id:$Id$
HeadURL:$HeadURL$

Contents

1   Introduction

Testilence is an open-source [1] unit testing library for PHP [2] 5. It is published under the MIT license [3] which means you are free and welcome to use it in any way. Like other JUnit [4]-inspired unit testing libraries, Testilence roughly follows the canon [5]. It is however written with emphasis on what's useful, not what's usual, and combines original ideas with the best features found in different unit-testing toolkits into a coherent set.

Testilence differs from the above-mentioned canon in that you only get to have one assertion per test method (this is a Good Thing):

  1. Multi-assertion test methods reduce test coverage, since the first failed assertion will abort the test method, skipping latter assertions in that method.
  2. Single-assertion test methods provide the author with a strong incentive to think about the PUT, because each test method should name a behavior. Thinking of meaningful names for all the tests is sometimes painful, but the reward is a better understanding of the code.
  3. Single-assertion test methods provide clearer picture to the reader.

Testilence features highly isolated tests with deterministic execution [6] and guaranteed cleanup [7].

Testilence is an essential ingredient in BEER [8].

1.1   Development Status

Testilence is in early stages of development, output of the command line tool lacks lots of essential information, and the reporting and presentation circuits [9] of the library need much work. Test isolation is still not perfect: environment, installed functions and classes, error handler, etc. still carry over from previous tests; certain forms of misuse will kill the command line tool with a fatal error.

That said, Testilence is already quite usable, and has gone through lots or realworld use.

2   Client code

2.1   Class structure

The smallest unit of tests is the test case class. It defines any number of test methods, and optionally either of setUp and tearDown methods (or both). Testilence provides an abstract test case base class with a number of assertFoo() methods, and a test suite class which allows arbitrary nesting of cases and suites, thanks to the Composite organization.

2.2   Runtime behavior

Runtime behavior is illustrated with the following simplified snippet of pseudocode.

$suite = new my_suite

for each $case in $suite do:
  for each $test in $case do:
    $o = new $case
    set_up $o
    $test $o
    tear_down $o
  done
done

Note that each test method is run on a separate instance.

3   Prerequisities

Basic guarrantee: Testilence is developed and tested on FreeBSD 6 with PHP 5.1.3 - 5.1.6, and 5.2.0 - 5.2.11. The Makefile is tested (no automation yet) with the system make (should work on any BSD) and GNU make.

Testilence on Microsoft Windows requires either Cygwin [10] or MSYS [11].

3.1   Buildtime requirements

The build and installation mechanism requires a subset of the POSIX shell environment, plus make. On Windows, either Cygwin [10] or MSYS [11] is needed to build Testilence and run its commandline interface.

Repository checkouts require Docutils [12] to build HTML documentation.

3.2   Library runtime requirements

The Testilence library has the following runtime requirements:

  • PHP >= 5.1.3 (with PCRE, Reflection, SPL)

    Testilence works with 5.1.3 or higher. Expect a bump to 5.2.0 (for better __toString() behavior). Expect addition of any of these PHP modules: operator [13], pcntl [14], posix [15], runkit [16], xdebug [17].

  • BSD, Linux, or UNIX

    This is a conservative statement.

    Some features might be missing on non-POSIX systems. Testilence is written with preference for portability, and should work on Microsoft Windows as is. Windows is, however, a second-tier operating system, problems are bound to appear from time to time.

3.3   Command line interface runtime requirements

The Testilence command line interface, tence, requires a subset of the POSIX shell environment. Besides that, its runtime requirements are the same as the library requirements, plus:

Note: the POSIX shell requirement means tence doesn't work in the command line interpreters found in Microsoft Windows (command.com and cmd.exe), and needs to be run from a Cygwin [10] or MSYS [11] shell instead.

4   Downloads

4.1   Repository

The latest source get be checked out from the Mercurial [19] repository [20], which is also available for anonymous browsing [21].

4.2   Official tarballs

Testilence source releases are distributed as bzip2ed tarballs created with either Tim Kientzle's bsdtar [22] or GNU tar, Julian Seward's bzip2 [23] in all cases. Your operating system should include compatible extraction tools.

All Testilence releases can be found in the download directory [24].

5   Build and Installation

5.1   From a package

The most comfortable way to install Testilence is using your operating system's packaging system. Ask your OS vendor for a package of the latest Testilence release.

The source distribution includes a FreeBSD port skeleton.

5.2   From the source

5.2.1   Wash and Go instructions

% url=http://www.testilence.org/dist/testilence-x.y.x.tar.bz2
% fetch -o - $url | tar -xjf -
% cd testilence-x.y.z
% ./configure
% make check
% sudo make install

5.2.2   Detailed description

The build and installation process can be configured using a number of make variables. Defaults should just work on most computers.

configure options:

  • --prefix=path

    Install location prefix. All installation paths are based on this one unless overriden by more specific variables. Substituted into built files.

    Default: /usr/local

  • --bindir=path

    Installation directory for executable programs.

    Default: ${TENCE_PREFIX}/bin

  • --docsdir=path

    Installation directory for reST and HTML documentation.

    Default: ${TENCE_PREFIX}/share/doc/testilence

  • --man1dir=path

    Installation directory for section 1 manual pages.

    Default: ${TENCE_PREFIX}/man/man1

  • --sitepkgdir=path

    Installation directory for the Testilence and tence libraries. configure detects this using include_path of the interpreter selected with --with-php.

    Default: system-specific

  • --testdir=path

    Installation directory for Testilence's test suite.

    Default: ${TENCE_PREFIX}/share/pear/tests/Testilence

  • --with-php=cmd

    Path to the PHP CLI. This value has two uses: it is substituted into tence, and used in the check targets to run the tests.

    Default: /usr/bin/env php

Makefile variables:

TENCE_DESTDIR

Install location prefix. All installation paths are prefixed with this one. This variable is used only during the install step, and is not substituted into any files.

Default: '' (empty string)

Functionality not described above or in the builtin help should be considered implementation details. If the documented features don't support all your configuration needs, please do send a feature request.

5.2.2.1   Installing on Microsoft Windows

Testilence can be built and installed using the MSYS shell.

  1. install MSYS [11]
  2. create an env. variable TMPDIR The value must be an existing directory writable by you (e. g. C:/Temp).
  3. start the MSYS [11] shell
  4. build and install using the general instructions You may need to login using an administrator account to install it.

5.2.2.2   Running the test suite

Testilence's own test suite can be exercised with or without installed Testilence by running make check or make check-all in the source directory. The former target excludes tests that use filesystem or other external resources, because a bug in Testilence might prevent proper cleanup or (although unlikely) delete your files. The tests will be run using src/tence/tence (will be built if necessary).

The test suite is described in more detail in Test Suite.

6   Test suite

The suite is organized around Testilence's classes, meaning there is one or more cases per class under test. These are in turn organized into suites, possibly multiple levels of them. Any part of the resulting tree can be run.

The top level suite is called tencetest_AllTests. This suite contains tencetest_SafeTests and tencetest_DangerousTests.

Source code for the complete suite can be found in the tests [25] subdirectory in the source distribution.

7   Reference

7.1   Overview

Testilence consists of a library and a command line test runner. The library is perfectly usable without the tool.

7.2   Command line interface

tence, the command line frontend, is documented in the accompanying man page.

Source code for the command line tool can be found in the src/tence [26] subdirectory in the source distribution.

7.3   Library

Testilence Library Reference [27] describes public interfaces and behaviors.

Source code for the library can be found in the src/Testilence [28] subdirectory in the source distribution.

8   Examples

Testilence Usage Examples [29] illustrate usage of Tence_TestCase [30] and Tence_TestSuite [31] in writing tests, and tence for their execution.

9   Releases

9.1   Release types

Testilence releases fall into one of the following four categories:

  • snapshots
  • bugfix releases
  • new functionality
  • backward-incompatible change

9.2   Release versioning

Each release is tagged with a version number string with the following structure (ABNF [32]):

version-string = compat-cnt "." newfun-cnt "." bugfix-cnt [rel-candidate]
compat-cnt     = counter
newfun-cnt     = counter
bugfix-cnt     = counter
rel-candidate  = "." snapshot counter
; "snap"
snapshot       = %x73.6e.61.70
; counter is a positive integer (includes 0)
counter        = 1 * DIGIT

For each release of any type the appropriate counter is incremented by at least one and counters to the right of it are reset to 0 (the release-candidate part is removed altogether), while counters to the left of it are left at their current values.

Version string of the first nonsnapshot Testilence release is 0.0.0, while "0.0.0.snap135" is the version string of a pre-0.0.0 snapshot. There may be gaps between.

This handling is consistent with the way FreeBSD's pkg_version -t [33] interprets version strings.

[1]http://opensource.org/docs/definition.php
[2]http://www.php.net/
[3]http://opensource.org/licenses/mit-license.php
[4]http://www.junit.org/
[5]http://www.xprogramming.com/testfram.htm
[6]docs/reference.rest#test-methods
[7]docs/reference.rest#setup-and-teardown
[8]http://beer.sigpipe.cz/
[9]docs/reference.rest#overview
[10](1, 2, 3) http://cygwin.com/
[11](1, 2, 3, 4, 5) http://www.mingw.org/wiki/msys
[12]http://docutils.sourceforge.net/
[13]http://pecl.php.net/package/operator
[14]http://php.net/manual/en/ref.pcntl.php
[15]http://php.net/manual/en/ref.posix.php
[16]http://pecl.php.net/package/runkit
[17]http://www.xdebug.org/
[18]http://pear.php.net/package/Console_Getopt
[19]http://selenic.com/mercurial/
[20]https://hg.sigpipe.cz/
[21]http://hg.sigpipe.cz/
[22]http://people.freebsd.org/~kientzle/libarchive/
[23]http://www.bzip.org/
[24]http://www.testilence.org/dist/
[25]tests/
[26]src/tence/
[27]docs/reference.rest
[28]src/Testilence/
[29]docs/examples.rest
[30]docs/reference.rest#tence-testcase
[31]docs/reference.rest#tence-testsuite
[32]http://tools.ietf.org/html/rfc4234
[33]http://www.freebsd.org/cgi/man.cgi?query=pkg_version