Running PHPUnit tests on a VM, from NetBeans

2012-03-03

I'd been meaning to figure this out for months now but it finally came to a head recently and I decided I was going to get this done. I knew it had to be possible, it just might involve an awful lot of redirection. It turns out it only involves a moderate amount of redirection.

Disclaimers

  • I'm running NetBeans 7.1 on OS X. Windows users should have similar options but they'd involve different tools.
  • I only run tests in NetBeans by right-clicking a single test file or folder of tests and choosing Run, so I'm limiting this workaround accordingly. It should be adaptable to support other options.
  • My tests on my local machine are in a different location than they are on my VM. I've accounted for that in the code below, you'll likely need to change the script to point to where the tests live on your VM.
  • Executing this workaround exactly as I have it requires only a little shell scripting knowledge but you'll be more comfortable making any modifications to it if you're already familiar with Bash scripting and, to a lesser degree, regular expressions.
  • You must be able to SSH into the VM that runs your tests without using a password.
  • Your tests will be somewhat slower.

Background

When NetBeans sends a request to PHPUnit, it does several things. First, it uses the file path listed in the PHPUnit script section of the NetBeans preferences (for screenshots, see the official tutorial). The important thing here is that there is no checking done to ensure that this is a stock, unmodified PHPUnit script, only that PHPUnit data is returned in its output. This frees us to do several interesting things.

NetBeans sends several parameters to this PHPUnit script when you execute a test. If you'd like to see what they all are on your machine, add something like echo $@ to the top of the script and check your Output pane after running it. In my environment, NetBeans sends seven parameters. Pairs of parameters like --configuration /path/to/phpunit.xml count as two parameters, not one, so keep that in mind when trying to use specific parameters.

Parameters one and two are "--log-junit" and log file path. NetBeans will look for log data at that location in order to populate its Test Results UI. The last line of the script copies the log data from the VM back to your local machine where NetBeans will look for it. If you don't care about that and just want to view the results in the Output pane, you can delete line 5 of the script and the $1 $2 in line 4.

Parameters three and four are "--bootstrap" and the bootstrap.php file path. Make sure this file exists on your VM at the location specified by argument four. If you don't use a bootstrap file, lower all the renaming args by two.

Parameters five and six are "--configuration" and a path to your local PHPUnit XML configuration file. In the steps below I'm changing the folder PHPUnit runs from to the folder that already contains my phpunit.xml file, so you can skip these two parameters and PHPUnit will pick up the XML configuration file automatically. If that isn't an option for you, you can change the file path using a process similar to what I did with parameter seven.

Parameters seven through nine are a custom NetBeans test suite builder that gets passed to PHPUnit, along with its location (inside the NetBeans app, on my machine it's /Applications/NetBeans/NetBeans 7.1.app/Contents/Resources/NetBeans/php/phpunit/NetBeansSuite.php), and a "run=" parameter that the test suite builder uses to determine the actual tests you want ran. It contains a recursive version of PHP's glob function that searches for test files and adds them to PHPUnit's run queue. Since I'm not doing anything fancy when selecting tests to run, I chose to just parse the last parameter (run=/path/to/test) and send that to PHPUnit instead of messing with the custom suite loader, since that file does not exist on my VM. If it does (or can) on your VM you can alter or hard-code that path and continue to use the NetBeans suite loader.

Step by step

  1. Clone the git repo. Make sure the shell script is executable.
  2. Change the user & host sections in line 4 to your credentials
  3. Change the /path/to/tests variable to where the tests live on your your VM
  4. The (slightly) tricky part. Edit the regular expression on line 12 that replaces the full local path to your tests with just test-specific part. For example, if a local path is "/Users/brianfenton/Sites/stuff/things/tests/TestName.php", line 12 will set the TEST variable to just "TestName.php"
  5. Edit your NetBeans Preferences to point your PHPUnit script to the new script you created above. Click OK. NetBeans will attempt to verify that this is a real PHPUnit script by executing it and checking the output. Normally this is fast enough you probably don't notice it, but this time you will.
  6. Test party

The final script

#!/bin/sh
#uncomment to debug
#echo $@
REMOTE_SERVER=user@virtualhost
REMOTE_PATH_TO_TESTS='/path/to/tests'
# The very last argument is the path to the test(s) you want run
export TEST=$9
# Chop off everything up to "tests" in that path. "tests" is just an example path
TEST=${TEST##r*tests}
# Connect to your VM, cd to your test location and run phpunit with most of the args
ssh $REMOTE_SERVER "cd $REMOTE_PATH_TO_TESTS; phpunit $1 $2 $3 $REMOTE_PATH_TO_TESTS/bootstrap.php $REMOTE_PATH_TO_TESTS/$TEST"
# Copy the test output back to your local machine, where NetBeans expects to find it
scp $REMOTE_SERVER:$2 $2

References/Further Reading

Tags: netbeans, phpunit

Comments