Saturday, December 8, 2007

Setting Up PHPUnit

I've put off setting up unit tests for my code far too long. I am ashamed. I've set aside this entire month to do all these things that appear like luxuries to non-developers, even though they're really essential.

For those of you who haven't been following, this is a Windows installation. I'm attempting to install the latest and greatest PHPUnit3 (3.2.4 at the time of this writing). It seems that either no one cares about doing this on Windows or only really smart people who find it so simple that they didn't bother to write about it have ever done it. Because half way through writing this (after publishing it half-done), I searched for "installing phpunit on windows" and this very blog article came up on the 2nd page.



Nice going Google, but not very helpful.

Quick Summary


For the impatient, here's a quick summary of what I had to do. Afterwards is the detailed story of how I got to this. I assume you already have PHP installed in C:\php.
  1. C:\php>go-pear.bat
  2. Merge C:\php\PEAR_ENV.reg
  3. C:\php>pear channel-discover pear.phpunit.de
  4. Change memory_limit in php.ini to something high like 64M. (Remember the old setting.)
  5. Save php.ini. Restart Apache.
  6. C:\php>pear install --alldeps phpunit/PHPUnit
  7. Change memory_limit in php.ini back to what it was before. (The default is 8M I think.)
  8. Save php.ini. Restart Apache.

Detailed Story


Now for the detailed story of how I got to the above steps.
  1. Install PEAR
    I currently have PHP 5.2.3 installed, and I installed PEAR on 8 December 2007 getting the following output accepting the default options.
    C:\php>go-pear.bat

    Are you installing a system-wide PEAR or a local copy?
    (system|local) [system] : system

    Below is a suggested file layout for your new PEAR installation. To
    change individual locations, type the number in front of the
    directory. Type 'all' to change all of them or simply press Enter to
    accept these locations.

    1. Installation base ($prefix) : C:\php
    2. Temporary directory for processing : C:\php\tmp
    3. Temporary directory for downloads : C:\php\tmp
    4. Binaries directory : C:\php
    5. PHP code directory ($php_dir) : C:\php\pear
    6. Documentation directory : C:\php\pear\docs
    7. Data directory : C:\php\pear\data
    8. Tests directory : C:\php\pear\tests
    9. Name of configuration file : C:\WINDOWS\pear.ini
    10. Path to CLI php.exe : C:\php\.

    1-10, 'all' or Enter to continue:
    Beginning install...
    Configuration written to C:\WINDOWS\pear.ini...
    Initialized registry...
    Preparing to install...
    installing phar://go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.3.2.tar...
    installing phar://go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.2.2.tar...

    installing phar://go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.5.4.tar...
    installing phar://go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.0.2.tar...
    pear/PEAR can optionally use package "pear/XML_RPC" (version >= 1.4.0)
    install ok: channel://pear.php.net/Archive_Tar-1.3.2
    install ok: channel://pear.php.net/Console_Getopt-1.2.2
    install ok: channel://pear.php.net/Structures_Graph-1.0.2
    install ok: channel://pear.php.net/PEAR-1.5.4
    PEAR: Optional feature webinstaller available (PEAR's web-based installer)
    PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
    PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)

    PEAR: To install optional features use "pear install pear/PEAR#featurename"

    ******************************************************************************
    WARNING! The include_path defined in the currently used php.ini does not
    contain the PEAR PHP directory you just specified:
    <C:\php\pear>
    If the specified directory is also not in the include_path used by
    your scripts, you will have problems getting any PEAR packages working.


    Would you like to alter php.ini <C:\php\php.ini>? [Y/n] : Y

    php.ini <C:\php\php.ini> include_path updated.

    Current include path : .
    Configured directory : C:\php\pear
    Currently used php.ini (guess) : C:\php\php.ini
    Press Enter to continue:

    ** WARNING! Old version found at C:\php, please remove it or be sure to use the
    new c:\php\pear.bat command

    The 'pear' command is now at your service at c:\php\pear.bat


    * WINDOWS ENVIRONMENT VARIABLES *
    For convenience, a REG file is available under C:\php\PEAR_ENV.reg .
    This file creates ENV variables for the current user.

    Double-click this file to add it to the current user registry.

    Press any key to continue . . .

    C:\php>

    I then merged the PEAR_ENV.reg file as specified.

    You should make sure that running pear at the command-line dumps a list of commands.
  2. Install PHPUnit
    C:\php>pear channel-discover pear.phpunit.de
    Adding Channel "pear.phpunit.de" succeeded
    Discovery of channel "pear.phpunit.de" succeeded

    C:\php>pear install phpunit/PHPUnit
    Did not download optional dependencies: pear/Image_GraphViz, pear/Log, use --alldeps to download automatically
    phpunit/PHPUnit can optionally use package "pear/Image_GraphViz" (version >= 1.2.1)
    phpunit/PHPUnit can optionally use package "pear/Log"
    phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite"
    phpunit/PHPUnit can optionally use PHP extension "xdebug" (version >= 2.0.0)
    downloading PHPUnit-3.2.4.tgz ...
    Starting to download PHPUnit-3.2.4.tgz (198,003 bytes)
    .........................................done: 198,003 bytes

    Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 73 bytes) in C:\php\PEAR\PEAR\PackageFile\v2\Validator.php on line 1021

    C:\php>

    Now what?
    Did it seriously run out of memory?
    ...I'll finish this post another day (tomorrow?), and hopefully I'll figure it out.

    ::day passes::

    ...Okay, I'm back. After checking my php.ini file, I found that the memory limit was indeed 8M. So I changed
    memory_limit = 8M
    to
    memory_limit = 64M

    Save, and restart Apache (necessary if you're running PHP as a module).

    This time I decided to use the --alldeps option as indicated by my last run. If PHPUnit can use GraphViz to make pretty output, that would be great. So here goes another shot.
    C:\php>pear install --alldeps phpunit/PHPUnit
    WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"
    phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite"
    phpunit/PHPUnit can optionally use PHP extension "xdebug" (version >= 2.0.0)
    pear/Log can optionally use PHP extension "sqlite"
    downloading PHPUnit-3.2.4.tgz ...
    Starting to download PHPUnit-3.2.4.tgz (198,003 bytes)
    .........................................done: 198,003 bytes
    downloading Image_GraphViz-1.2.1.tgz ...
    Starting to download Image_GraphViz-1.2.1.tgz (4,872 bytes)
    ...done: 4,872 bytes
    downloading Log-1.9.11.tgz ...
    Starting to download Log-1.9.11.tgz (38,479 bytes)
    ...done: 38,479 bytes
    downloading DB-1.7.13.tgz ...
    Starting to download DB-1.7.13.tgz (132,246 bytes)
    ...done: 132,246 bytes
    downloading MDB2-2.4.1.tgz ...
    Starting to download MDB2-2.4.1.tgz (119,790 bytes)
    ...done: 119,790 bytes
    install ok: channel://pear.phpunit.de/PHPUnit-3.2.4
    install ok: channel://pear.php.net/Image_GraphViz-1.2.1
    install ok: channel://pear.php.net/Log-1.9.11
    install ok: channel://pear.php.net/DB-1.7.13
    install ok: channel://pear.php.net/MDB2-2.4.1
    MDB2: Optional feature fbsql available (Frontbase SQL driver for MDB2)
    MDB2: Optional feature ibase available (Interbase/Firebird driver for MDB2)
    MDB2: Optional feature mysql available (MySQL driver for MDB2)
    MDB2: Optional feature mysqli available (MySQLi driver for MDB2)
    MDB2: Optional feature mssql available (MS SQL Server driver for MDB2)
    MDB2: Optional feature oci8 available (Oracle driver for MDB2)
    MDB2: Optional feature pgsql available (PostgreSQL driver for MDB2)
    MDB2: Optional feature querysim available (Querysim driver for MDB2)
    MDB2: Optional feature sqlite available (SQLite2 driver for MDB2)
    To install use "pear install pear/MDB2#featurename"

    C:\php>

    It looks like it worked. :-)

    Run phpunit at the command-line to test that it worked. You should get a version and usage message dumped.

    Change the memory limit back to 8M. Save, restart.
  3. Test the Test Framework
    To further test that my installation was actually working, I made a dummy test that always fails. Like so...
    <?php
    require_once 'PHPUnit/Framework.php';

    class DummyTest extends PHPUnit_Framework_TestCase {

    public function testFail() {
    $this->fail('Your test successfully failed!');
    }

    }

    ...and put it in my C:\ root directory as DummyTest.php. This way I can make sure my path is setup correctly to use PHPUnit from anywhere.

    Sure enough, I get some good test-output.
    C:\>phpunit DummyTest
    PHPUnit 3.2.4 by Sebastian Bergmann.

    F

    Time: 0 seconds

    There was 1 failure:

    1) testFail(DummyTest)
    Your test successfully failed!
    C:\DummyTest.php:7

    FAILURES!
    Tests: 1, Failures: 1.

    C:\>


That's it! I hope this is helpful to someone.

38 comments:

Anonymous said...

Thanks for the tutorial.That was very helpful!

Unknown said...

Great, I hate lenghty explanations, this checklist is enough for pointing me at the right directions.

Btw:
The "Test the Test Framework" example file 'DummyTest.php' needs to be encapsulated with the start and end php tags?

Someone might miss that (I for sure missed that).

bertrod said...

I agree, very helpful but I had the following error:

Starting to download Log-1.9.16.tgz (40,971 bytes)
...done: 40,971 bytes
Could not download from "http://pear.php.net/get/DB-1.7.13.tgz", cannot download
"pear/DB" (Connection to `pear.php.net:80' failed: Se produjo un error durante
el intento de conexi¾n ya que la parte conectada no respondi¾ adecuadamente tras
un periodo de tiempo, o bien se produjo un error en la conexi¾n establecida ya
que el host conectado no ha podido responder.
)
Error: cannot download "pear/DB"
downloading MDB2-2.4.1.tgz ...
Starting to download MDB2-2.4.1.tgz (119,790 bytes)
...done: 119,790 bytes

It is a conection error, may I try to reinstall the package or why can I try to install just this module?

However, I have been able to run C:\php\phpunit

Thanksss

Anonymous said...

Yeah, thank-you greatly for putting this tutorial together, it's greatly appreciated! :)

DAN GUINN said...
This comment has been removed by the author.
DAN GUINN said...
This comment has been removed by the author.
DAN GUINN said...
This comment has been removed by the author.
DAN GUINN said...

This was a great help! This gave me all the right hints even though my situation was a little different.

For those using xammp on XP pro here's what I did to get it going.

1) Connect to pear channel-discover pear.phpunit.de

2)Edit pear.bat in your php folder to allow upgrades
See this link: Read section "Installing & upgrading PEAR packages"
http://data-based-systems.com/
articles/papers/PearNotes.html
(Also Note: xampp does not require running go-pear)


3) Upgrade Image_GraphViz - This gave me some problems. It said that it required Image_GraphViz but it was already there so I upgraded it and it worked. Do this by typing "pear upgrade pear/Image_GraphViz"

4) Then create the test example shown here!

Anonymous said...

Thanks!!!

Johan said...

Hi,

Your tutorial was very helpfull thnx! Only one problem with your dummytest.php. I have done exactly what you described but got the following error:


C:\>phpunit dummytest
PHP Warning: PHPUnit_Util_Fileloader::include_once(dummytest.php): failed to op
en stream: No such file or directory in C:\Program Files\PHP\PEAR\PHPUnit\Util\F
ileloader.php on line 120
PHP Warning: PHPUnit_Util_Fileloader::include_once(): Failed opening 'dummytest
.php' for inclusion (include_path='C:\Program Files\PHP\PEAR;C:\Alfresco\alfresc
o-php-library') in C:\Program Files\PHP\PEAR\PHPUnit\Util\Fileloader.php on line
120
PHPUnit 3.2.18 by Sebastian Bergmann.

Class dummytest could not be found in dummytest.php.


What have i done wrong?

Thnx!

Jon T said...

Johan,

Sorry for not replying sooner. I forgot to turn on comment notifications, and I've been neglecting this blog for a while.

hmm... My first thought was that your dummytest.php file wasn't in the same directory that you were running phpunit from, i.e. it wasn't in C:\ in the example you gave. But I tried doing exactly that and I got a different error message than the one you did, so it's probably something else.

Any luck fixing this in the past few weeks since you posted?

Jon T said...

Thanks everyone for pointing out the missing <?php from the DummyTest.php file. It's fixed now. I simply forgot to escape the "<" so it wasn't showing up.

As for omitting the closing ?> tag, it's actually a trick us advanced PHP hackers ;-) use to prevent extra whitespace at the end of files from accidentally getting output. This is especially important for files that are included by other files. PHP knows to close the tag at the end of a file as expected.

Johan said...

I did not continue with this any further because i got no response anymore, but i still would like to know if it can be solved and give it an other go! :)

Anonymous said...

I've discovered that the most problems involving phpunit is caused by faulty include paths, either in php.ini or other ways.

On eg. Ubuntu there is different php.ini for apache and the shell.

Another thing that should be tried is to invoke the test like this:

phpunit DummyTest DummyTest.php

Johan: are you sure that DummyTest.php is located in the root as c:/DummyTest.php ?

Unknown said...

Hi.

Thanks for your tutorial, everything went well, except the part where the .reg file added the environment vars.

The vars are there, but I can't use them system wide...

Don't know what the problem is, but I can only run php.exe and phpunit.bat from within the php bin dir...

Help?

Unknown said...

No need to reply to that...

I've added the php bin dir to the path env var and evrything is working now...

;)

Anonymous said...

Hi Jonathan,
Your article was very much helpful for me :) I tried searching on Zend Website, but was not so successful.

With your help,I was able to successfully load PHP Unit in my PC and now I am also able to test my code with the same :)

Thanks again !!!!

-Himanshu Sheth
[http://thoughtsprevail.blogspot.com]

Anonymous said...

very cool, thx a lot

Anonymous said...

Every time i try installing PHPunit on windows

on giving this command

pear install phpunit/PHPUnit

it gives me this error and some how i am not able to figure it out

No release available for package "pear.phpunit.de/PHPUnit"
Cannnot initialize 'channel:/pear.phpunit.de/PHPunit', invalide or missing package file
Package "channel://pear.phpunit.de/PHPUnit" is not valid.
install failed.

I have carried out the same steps listed but still the problem exists.

Anonymous said...

Hi,

Thank you for the article. I'm a website developer. I used to do .NET but switched to PHP just recently. So I'm new to the environment.

I was looking for a testing tool that has the same capabilities as NUnit and I found PHPunit.

Thanks a lot.

Anonymous said...

Thanks very much man you saved my time for searching things on google :)

Anonymous said...

Hi, I do not understand where I should put this DummyTest.php file, cause if I put it to the C:\ dir phpunit says:
C:\>phpunit DumyTest.php
PHPUnit 3.3.5 by Sebastian Bergmann.

File "DumyTest.php" could not be found or is not readable.

Jon T said...

C:\DummyTest.php should be fine. Did you try executing it without the ".php", as in...

C:\>phpunit DummyTest

... or maybe as stojg suggests ...

C:\>phpunit DummyTest DummyTest.php

Anonymous said...

thank you for posting this. it was very helpful.

Prema said...

Hi,

When i run phpunit.bat i get following error.

Warning: require_once(PHPUnit/Util/Filter.php): failed to open stream: No such f
ile or directory in C:\wamp\php\phpunit on line 44

Fatal error: require_once(): Failed opening required 'PHPUnit/Util/Filter.php' (
include_path='.;C:\php5\pear') in C:\wamp\php\phpunit on line 44

Can anyone please help me out to solve this.

Thanks
Prema

Thomas' Blog said...

Nice - thx for you explanations. I really needed it 10 hours ago ;)
It was a nightmare to set up PHPUnit - and when I was up and running. Phpunit couldn't find my test file. I searched goole and found your blog. This comment here:
phpunit DummyTest DummyTest.php

Then I tried:
phpunit ArrayTest \wamp\www\test\ArrayTest.php

And it worked - thank you very much ; )

Jason Welch said...

Pretty decent article. I already had everything else taken care of though so really I just had to reference to he "c:\php\pear install --alldeps" command. Now, to install it on my linux box...

Unknown said...

Thanks! This is exactly what I was looking for. Bookmarked for sure.

Anonymous said...

Your guide is the best on the Internet, thanks!


[ Problem: ]

$ pear install --alldeps phpunit/PHPUnit

WARNING:
phpunit/PHPUnit require PEAR Installer (version >= 1.8.1), installed version is 1.7.2



[ Solution: ]

The latest PEAR version isn't included in the latest PHP/5.2.10 .exe file.
Update PEAR Installer through cmd instead!

$ pear upgrade --force PEAR
$ pear channel-discover pear.phpunit.de
$ pear install --alldeps phpunit/PHPUnit


/Witch

Joaquin 'Joaco' Senosiain said...

If you are getting these errors, here is the solution:

Warning: require_once(PHPUnit/Util/Filter.php): failed to open stream: No such f
ile or directory in C:\wamp\php\phpunit on line 44

Fatal error: require_once(): Failed opening required 'PHPUnit/Util/Filter.php' (
include_path='.;C:\php5\pear') in C:\wamp\php\phpunit on line 44

1. Rename the phpunit file to something like phpunittest.

2. Change the reference in phpunit.bat to reflect the previous change.

3. If it isn't there, copy the PHPUnit folder under the root php folder (ie c:\php)

You should now be able to execute the phpunit command on the commandline and get the version info.

Brady Vitrano said...

Your test has successfully failed.

Awesome!

Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

Anonymous said...

Great post including the troubleshooting. PEAR and PHPUnit is definitely a challenge on Windows.

Since it looks like PHPUnit has moved, you can get it directly at

http://pear.phpunit.de/get/PHPUnit-3.4.9.tgz (or whatever version you have.

You can:

pear install http://pear.phpunit.de/get/PHPUnit-3.4.9.tgz

or download the tarball, unzip it, and include it in your PHP include path. Add the base directory with phpunit.bat and phpunit.php in your PATH (you could just copy it to c:\php for example) and then edit phpunit.bat to look something like this:

C:\PHP\php.exe C:\PHP\phpunit.php %*

Anonymous said...

Warning: require_once(PHPUnit/Util/Filter.php): failed to open stream: No such f
ile or directory in C:\wamp\php\phpunit on line 44

Fatal error: require_once(): Failed opening required 'PHPUnit/Util/Filter.php' (
include_path='.;C:\php5\pear') in C:\wamp\php\phpunit on line 44

It happens because when php.exe is called in command line mode, it doesn't find the php.ini file. You have to add the option -c"c:\wamp\Apache2\bin\php.ini" in your command line.

Anonymous said...

If you get this error :

Fatal error: require_once(): Failed opening required 'PHPUnit/Util/Filter.php' (
include_path='.;C:\php5\pear') in C:\wamp\php\phpunit on line 44

Solution :
Check the path Environmental variables. I got the same error because i dint put a "\" at the end of my environmental variable "c:\wamp\php\php5.3.0\" i initially had "c:\wamp\php\php5.3.0"

aboynejames said...

a helpful tutorial, if PEAR installer is out of date then pear upgrade-all will get the latest version. I had to do that before installing the phpUnit.

Pradeep.V.G said...

Thank you...

After trying soo many times..

It worked for me..

Thanks for all...

Jarek said...

Thanks for this! Very helpful! I've got small problem:

Unknown remote channel: pear.symfony-project.com
Unknown remote channel: pear.symfony-project.com
Unknown remote channel: components.ez.no
Unknown remote channel: components.ez.no
phpunit/PHPUnit requires package "channel://pear.symfony-project.com/YAML" (version >= 1.0.2)
phpunit/PHPUnit can optionally use PHP extension "dbus"
phpunit/DbUnit requires package "channel://pear.symfony-project.com/YAML" (version >= 1.0.2)
phpunit/PHP_CodeCoverage requires package "channel://components.ez.no/ConsoleTools" (version >= 1.6)
phpunit/PHP_CodeCoverage can optionally use PHP extension "xdebug" (version >= 2.0.5)
phpunit/PHP_TokenStream requires package "channel://components.ez.no/ConsoleTools" (version >= 1.6)
No valid packages found
install failed


I had to add 2 channels:

pear channel-discover pear.symfony-project.com
pear channel-discover components.ez.no


...and run again:


pear install --alldeps phpunit/PHPUnit


and everything worked fine!