I've been playing around with a Gruntfile that was posted on reddit last week:

https://coderwall.com/p/chdf1w

It automatically runs PHPUnit when you modify a file in your application directory or in your test folder. The only real problems I've run into with it is that because it's using watch it has a tendency to eat up 100% of my VMs CPU and it will occasionally start running all the unit tests or get stuck running the same unit test (a restart of the grunt process always fixes the problem).

module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-shell');
  grunt.initConfig({
    testFilepath: null,
    watch: {
      php: {
        options: {
          event: 'changed',
          spawn: false
        },
        files: ['application/**/*.php', 'tests/**/*Test.php'],
        tasks: 'shell:phpunit'
      }
    },
    shell: {
      phpunit: {
        command: 'echo <%= testFilepath %> && vendor/bin/phpunit -c tests --stop-on-error --stop-on-failure <%= testFilepath %>'
      }
    }
  });

  grunt.registerTask('default', ['watch'])

  return grunt.event.on('watch', function(action, filepath, ext) {
    var regex, testFilepath;
    regex = new RegExp("application/([a-z0-9/]+)\.php", "i");
    if (filepath.match(regex)) {
      if (filepath.indexOf('Test') === -1) {
        testFilepath = filepath.replace(regex, "tests/$1Test.php");
      } else {
        testFilepath = filepath;
      }
      return grunt.config('testFilepath', testFilepath);
    }
  });
};