Web development blog by Philipp Rieber
In our weekly Code Kata at work, we’re exercising TDD using phpspec. TDD means switching between coding and running the tests all the time, may causing cramps by abuse of Cmd+Tab
. So why not automate the test runs whenever a source file changes and show a decent notification about success or failure?
This article shows two different approaches to automatically run phpspec
whenever a source or spec file was changed in your codebase.
Gulp is a Node.js based task runner. It allows you to create and run lightweight customized tasks on the command line and provides tons of plugins, e.g. for desktop notifications or running phpspec
with specific options – exactly what we need for our purposes. After installing Node.js, gulp first needs to be installed globally by using the Node Package Manager npm
:
Gulp also needs to be installed locally for each project that makes use of it – just as well as the desired gulp plugins. To install local Node packages, just type a node install
command right in the project’s root directory:
Packages and their dependencies are installed into the node_modules/
directory by default, which should be ignored by your version control system. If you have a package.json
file in place (which in contrast should be under version control) to describe your Node dependencies, the --save-dev
option appends the installed packages and their respective versions to the development dependencies section:
With package.json
, you or your fellow teammates just need to run npm install
without any argument to get the exact same setup of Node module on their machine. Think of it as Composer for Node.
Gulp tasks are defined in a file called gulpfile.js
in the project’s root directory. First, we import the plugins and assign them to variables:
Then, we create a stub task that will run the phpspec tests later:
You can already try this task on the command line, providing the task name test
to the gulp
command:
Now it’s time to fill the test
task with real code:
In options
, you can specify whatever command line options you want to run phpspec with, e.g. for pretty or verbose output or if you wish to clear the console after every test run. With gulp.src('spec/**/*.php')
, gulp finds all the PHP files in the spec/
directory recursively (using a glob pattern) and then pipes them into the phpspec
command with the options from above using pipe(phpspec('./bin/phpspec run', options))
. You may need to adjust the path to the phpspec
executable. Now, when running gulp test
in your project’s root folder, every phpspec test gets executed. Depending on test success or failure, the appropriate method from the gulp-notify
plugin gets called and shows a nice desktop notification – depending on your operating system.
To implement a watch functionality that is monitoring files for changes and then automatically runs the test
task, we implement another task called watch
, which makes use of a native gulp feature to watch for file changes:
The first parameter of gulp.watch()
indicates the files we wish to watch for changes, i.e. in our case all the PHP source and spec files. The second parameter specifies the task(s) to run when a file change is detected, i.e. in our case only the test
task. Now you may start the file watcher with gulp watch
. But gulp also allows you to specify a default
task that gets executed whenever you do not provide a task name to the gulp
command:
In the second parameter, instead of a callback method, we can also provide an array of existing task names that we wish to run. To run the tests once and then start the file watcher, there’s now nothing more to it than just running:
If we put everything together, we end up with a quite straightforward gulpfile.js
solution, allowing us to watch for file changes and execute the phpspec
tests:
Now just open a console window (e.g. integrated in PhpStorm: Alt+F12
), work on your code and watch the test runs every time you save a file (e.g. in PhpStorm: Cmd+S
).
A successful test run in PhpStorm looks like thi:
A failed test run in PhpStorm looks like this:
Modern IDEs also provide solutions to create file watchers.
In my IDE of choice – PhpStorm – this feature is simply called File Watchers. There’s even built-in support for popular transcompilers like Sass or CoffeeScript that compile to their CSS or JavaScript counterpart on file save, respectively. For our purposes we can easily add a custom file watcher by importing a ready made solution from Github. Save the raw XML file somewhere and import it from Preferences > File Watcher using the Import button.
All the options are quite self-explanatory, but you may adopt some little things like always showing the console, whether it is an erroneous or a successful test run. That way, you may be more confident that the tests ran smoothly.
A successful test run in PhpStorm looks like this:
A failed test run in PhpStorm looks like this:
As you may have have noticed, there is no desktop notifications. Implementing desktop notifications is possible, but requires additional work that I’ll leave as an exercise to the interested reader.
Although gulp requires Node.js, I prefer the gulp solution to the IDE File Watcher because:
gulpfile.js
can be under version control and easily distributed with a project
Philipp Rieber is a passionate and certified PHP and Symfony developer working at Paymill in Munich, Germany. He is also engaged in the frontend, the Cloud, on Mobile, as a DevOp and a technical writer. He is never missing the PHP User Group Munich and he is co-organizing the Symfony User Group Munich.
Liked this post? Follow me on Twitter for updates.