Grunt and Codeception

  • Reading time: 3 min
  • Published 4 years ago

Codeception is a great tool for testing PHP Applications in a variety of different ways. Grunt is a great tool for managing all kinds of deployment tasks from minifying CSS and JavaScript to moving compiled assets around. In terms of continuous integration and quick development cycles, I like to get the amount of commands I have to run to test any change in an application as close to zero as possible. Since this is not exactly a tutorial, I am going to assume that you know the basics of using the above tools, if not, I recommend you consult this Laracast for Codeception and Grunt's very own getting started page on \drumroll\ Grunt. And yes, I know that this Laracast is not free but trust me: Laracasts really are like Netflix for developers.

So far, I already had a Gruntfile and a Codeception configuration that reduced everything to:

$ grunt                   # run client side integration
$ vendor/bin/codecept run # run server side integration

This is not ideal though. Especially not for active development when I want this stuff to run after every relevant edit. Also, 2 is greater than 0. I figured that ideally, two things needed to happen:

  1. grunt starts codeception
  2. grunt tasks run automagically after file changes

The first requirement was easily achieved with grunt-run:

run: {
// Gruntfile.js
...
    codeception: {
        cmd: 'vendor/bin/codecept',
        args: ['run'],
      }
    }
...
grunt.registerTask('default', ['run:codeception', ...]);

The second requirement can be solved using grunt-contrib-watch (Hint: I use Sass):

// Gruntfile.js
...

watch: {
      js: {
        files: 'client/js/**/*.js',
        tasks: ['concat']
      },

      css: {
        files: 'client/sass/**/*.scss',
        tasks: ['sass', 'autoprefixer']
      },

      php: {
        files: [
          'app/**/*.php', 
          'tests/**/*.php'
        ],
        tasks: ['run:codeception']
      }
    },

Obviously, your watched directories might look a little bit different. This one here is for this website which currently is a strange hybrid between Laravel 4.2 and 5.

After these changes, for local development, I can just run grunt watch in a Terminal tab and leave that open, while on the CI server, I have the build script simply start grunt to have everything done for me.

Bonus: Desktop notifications

Desktop notifications are cool, right? I mean, at least when they actually contain useful information. Like for instance telling you that one of your tests failed. That would save you the time and effort to open up that grunt-watch terminal window after every change. So, the question is, can that be done?

While I did not stumble upon a perfect solution yet, I managed to at least get something that kind of tells me 'Yay' or 'Nay' with grunt-notify.

Setting up the notify plugin is ridiculously easy. The only thing I added in addition to enabling the plugin, is the option to extend the notification display duration and bam!, notifications appeared:

// Gruntfile.js
...
    notify_hooks: {
      options: {
        duration: 5
      }
    }