I have found test-driven development(TDD) a very interesting development methodology. Just recently I have been applying this in the development of a WordPress plugin. One of the issues during the development was wasting time launching tests manually after making changes to the code. You don’t know what you could do and achieve in those few seconds. Running PHPUnit tests automatically became important to save those precious seconds. In this post I want to share how to run tests automatically when a change in code is detected.
There are multiple options that you could use for running phpunit tests automatically. In example, phpunit-watcher is a PHP script that you can install in your project easily through composer. In my case, I created watch-and-do, a bash script and it is now hosted in Github. Honestly I think I didn’t google it well and I didn’t find phpunit-watcher before. But let’s say that I wanted to learn and create a bash script.
A testing environment with WordPress configured and running is required in order to run tests for the WordPress plugin. In the official documentation of WordPress, you can find how to create the testing environment for your WordPress plugin.
The bash script is based on inotifywait to watch and detect changes in the code. This tool can use some filters to notify when a file is created, modified, deleted or moved only:
# listen for changes
inotifywait -m -r -q -e modify -e create -e delete -e move --format "%w%f %e" $WATCHDIR
When a change is detected, then the script waits for a couple of seconds before launching the tests. Sometimes I am editing multiple files and then I save all of them. With a delay in the script, the test are launched after the last saving instead launching the tests after saving each file:
# increase the stock
echo $(( $(cat $STOCK_FILE) + 1 )) > $STOCK_FILE
# sleep for a moment while more changes are detected
sleep $CHANGES_DETECTION_SLEEP
# decrease stock
echo $(( $(cat $STOCK_FILE) - 1 )) > $STOCK_FILE
# if stock is empty (this discard multiple execution)
if [ $(cat $STOCK_FILE) -eq 0 ]
then
# run tests
run_tests $@
fi
It is important to run the tests in a new process and store its PID because it is used to stop the process if required. Before launching the tests, it is possible that the tests are under execution due to a previous modification of a file. In order to not get conflicts and to not get a mess in the console, it is a good idea to stop the current execution of the tests. We stop the tests using the PID of the process and the kill command with signal SIGTERM. The tests are not stopped immediately, so it is important to wait until they have been stopped:
while [ $LASTPID ] && [ $LASTPID -gt 0 ] && (ps -p $LASTPID > /dev/null)
do
# kill previous testing
if [ $KILLING -eq 0 ]
then
KILLING=1
kill -SIGTERM $LASTPID
fi
# wait until previous tests are finished
echo "Wait while current tests are stopped..."
sleep $TESTS_KILLING_SLEEP
done
Finally, when previous tests have been stopped, the new tests are lunched and the PID of its process is stored. The command to run the tests is passed as an argument to the script. In this way the script is not attached to how phpunit is configured in the system:
# execute tests
echo "Running command: $@"
$@ &
# store the pid of the thread running the tests
echo $! > $PID_FILE
Using the script requires as arguments the folder to watch and the command to run the tests:
$ ./watch-and-do my-base-folder phpunit -v
As mentioned before, this script is just an alternative to other tools to watch for changes in your code and run the tests automatically. This bash script is open source and you can find it in Github as watch-and-do.