\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
This is old documentation. Current Horde 5+ applications and libraries use PHPUnit wrapped in Horde\_Test.

\part{Writing PHP Tests}
.phpt stands for "php test" and is a specialized file format that consists of 4 standard sections, and two optional sections (marked by *).  They are as follows:

\begin{itemize}
\item TEST - the name of the test file (informational)


\item SKIPIF - PHP code that determines whether this test should be run, and echoes "skip reason", more at (a)


\item ARGS - pass in command-line arguments to php pear run-tests does not yet implement GET, POST, or INI


\item FILE - the actual test file, this is standard PHP


\item EXPECT/EXPECTF/EXPECTREGEX - plain test, the expected output of the file.  EXPECTF and EXPECTREGEX are used to allow looser validation.


\end{itemize}
a simple test is:

<pre><code>
--TEST--
simple test
--SKIPIF--
<?php
if (substr(PHP\_OS, 0, 3) == "WIN") \{
    echo "skip cannot run on windows";
\}
echo "warn you might have left the iron plugged in";
?>
--FILE--
<?php
echo "tests done";
?>
--EXPECT--
tests done
</code></pre>
If you run this command on windows

<pre><code>
C:\textbackslash\{\}> pear run-tests simpletest.phpt
SKIP (reason: cannot run on windows)
</code></pre>
if you run it on any other OS

<pre><code>
\textasciitilde{} pear run-tests simpletest.phpt
PASS simple test [simpletest.phpt] (warn: you might have left the iron plugged in)
</code></pre>
This test fails:

<pre><code>
--TEST--
fail test
--SKIPIF--
--FILE--
<?php
echo "wrong";
?>
--EXPECT--
tests done
</code></pre>
<pre><code>
C:\textbackslash\{\}> pear run-tests failtest.phpt
FAIL fail test [failtest.phpt]
</code></pre>
and creates 3 files:

<pre><code>
failtest.php:
<?php
echo "wrong";
?>

failtest.exp:
tests done

failtest.out:
wrong

failtest.diff:
001- tests done
001+ wrong
</code></pre>
Most tests rely upon var\_dump(), echo, and other display methods to validate the test like so:

<pre><code>
--TEST--
old way
--SKIPIF--
--FILE--
<?php
var\_dump(array(2, 'hi'));
?>
--EXPECT--
array(2) \{
  [0]=>
  int(3)
  [1]=>
  string(2) "hi"
\}
</code></pre>
The method I have been using for testing PEAR is more familiar to users of phpunit.

<pre><code>
--TEST--
new way
--SKIPIF--
--FILE--
<?php
require\_once dirname(\_\_FILE\_\_) . '/phpt\_test.php.inc';
\$phpunit = new PEAR\_PHPTest;
\$a = array(2, 'hi');
\$phpunit->assertEquals(array(2, 'hi'), \$a, 'first array');
echo 'tests done';
?>
--EXPECT--
tests done
</code></pre>
When a test succeeds, there is no output, but in this test:

<pre><code>
--TEST--
new way
--SKIPIF--
--FILE--
<?php
require\_once dirname(\_\_FILE\_\_) . '/phpt\_test.php.inc';
\$phpunit = new PEAR\_PHPTest;
\$a = array(3, 'hi');
\$phpunit->assertEquals(array(2, 'hi'), \$a, 'first array');
echo 'tests done';
?>
--EXPECT--
tests done
</code></pre>
if you have Text\_Diff installed, the .out file would contain:

<pre><code>
Test Failure: "first array"
 in C:\textbackslash\{\}devel\textbackslash\{\}newtest.php line 4
Diff of expecting/received:
@@ -1,4 +1,4 @@
 array (
-  0 => 2,
+  0 => 3,
   1 => 'hi',
 )
</code></pre>
otherwise, it would contain:

<pre><code>
Test Failure: "first array"
 in C:\textbackslash\{\}devel\textbackslash\{\}newtest.php line 4
Expecting:
array (
  0 => 2,
  1 => 'hi',
)
Received:
array (
  0 => 3,
  1 => 'hi',
)
</code></pre>
This makes it really easy to both debug and create new tests/modify old ones.  If array(3, 'hi') is correct, all you have to do is cut and paste the output into your test. An extreme example of where I have done this is in pear-core/tests/PEAR\_DependencyDB/test\_rebuildDB.phpt

An example of how this flexibility is better than a simple EXPECTF is in pear-core/tests/PEAR\_Downloader\_Package/test\_initialize\_abstractpackage.phpt in this section:

<pre><code>
\$phpunit->assertEquals(array (
  0 =>
  array (
    0 => 3,
    1 => '+ tmp dir created at ' . \$dp->\_downloader->getDownloadDir(),
  ),
), \$fakelog->getLog(), 'log messages');
</code></pre>
here, I wanted to make sure that not only was this + tmp dir message logged, but that the directory created was in fact the one from our instance of PEAR\_Downloader.

\end{document}
