Chris Tankersley

· PHP Jack of All Trades ·

Running PHPUnit With the IBM i

PHPUnit is pretty much a staple of PHP development these days. One platform that is gaining traction, thanks to Zend and IBM, is running PHP on the OS/400 operating system and the IBM i servers. You get the power of Apache, PHP, and MySQL (and DB2, if you are so inclined) all for free with your IBM i through the magic of licensing.

One big advantage to running PHP on the IBM i is that you can take utilize these big iron boxes that excel at back-office work while providing rich, dynamic web application front ends instead of old green screens. Zend has bundled in an IBM i extension that allows developers to access DBU and RPG programs with no hassle. The downside? Development moves from being a local code-debug locally-commit process to needing that IBM i to run the RPG applications.

The Problem

This is not a huge disadvantage until you throw PHPUnit into the mix. On one of the projects I'm working on I need to call a multitude of different RPG programs, all with different descriptions. I want to make sure that my interfaces to these RPG programs work and the best way to do that is with unit tests. I can work with my RPG programmer and make sure that nothing breaks throughout the process. This all sounds like normal development until you run PHPUnit on your local machine and the i5 functions don't exist. Why?

All those functions and objects that Zend packaged with Zend Server only work on the IBM i. If you try to call them on your local Windows/Linux/Mac development box they won't be found. Since those functions are designed to specifically work with the IBM i, the best you could do is stub them out as user defined functions. That only masks the problem.

The best solution: put PHPUnit on the IBM i!

Installing PHPUnit

Luckily, PHP on the IBM i is supplied by Zend in an easy to install package via Zend Server. This isn't a post on getting PHP up and going, but suffice to say that it is pretty easy. Once it is installed it works just like any other Zend Server install. Everything is packaged up in /usr/local/zendsvr/. The main PHP binary, a specialized php-cli binary, and pear are sitting in /usr/local/zendsvr/bin/ just waiting to be used.

Installing PHPUnit is pretty easy:

$ cd /usr/local/zendsvr/bin/
$ ./pear channel-discover
$ ./pear channel-discover
$ ./pear install phpunit/PHPUnit

There really isn't anything special here.

Actually Using PHPUnit

One thing that most IBM i machines lack is a good shell. QSH gets the job done but lacks the power and finesse of most mainstream shells like bash or ksh. At least as of V5R4 (which is all I have access to) there isn't any tab completion, no scrolling back through history, not even reliable aliasing. What's a dev to do?

There is another kicker. While you can just call the phpunit script by itself it isn't going to load everything it needs. You need to call it via the php-cli script that Zend Server installs. What's the difference? The php-cli script sets up an environment where PHP will load its modules correctly. You can invoke PHPUnit like this:

/usr/local/zendsvr/bin/php-cli /usr/local/zendsvr/bin/phpunit

That's long and without tab completion, a pain. It works though. I suggest putting that into a .sh script and just invoking the script instead of the long phpunit command. (As a note: I did edit the phpunit script itself to call the php-cli instead of just php, but no dice. QSH seems to ignore the #! at the beginning of the script).

Bear in Mind - Execution is Slow

On our IBM i server executing any PHP script via the command line is incredibly slow. With the application I'm working on, PHPUnit takes approximately 5 seconds to run under Linux Mint, but on the IBM i it takes almost 45 seconds. It seems to take the IBM i a while to get everything going before it fires off. I'm not sure if it is our IBM i (which, is way to small for what we're doing) or V5R4. Web apps work just fine, the command line is just slow.

Skip i5-based Calls

Now that we have PHPUnit running, the only thing we need to do is make life easier on the developers. Any tests that involve the i5 functions or rely on the IBM i I mark as skipped in PHPUnit. This allows me to test some things locally and not have PHPUnit blow up in my face with errors that the functions aren't defined.

Now Go Forth and Develop!

Hopefully this will make your development life easier if you are working on the IBM i. I've thus far enjoyed working with PHP on it, even with various work arounds to get RPG code to talk to PHP code. Having PHPUnit on both my local machine and the IBM i helps speed up development and keep everything running smoothly.


Categories: IBM i, PHP