External code coverage with travis / scrutinizer

Warning: This blogpost has been posted over two years ago. That is a long time in development-world! The story here may not be relevant, complete or secure. Code might not be complete or obsoleted, and even my current vision might have (completely) changed on the subject. So please do read further, but use it with caution.
Posted on 20 Nov 2013
Tagged with: [ CI ]  [ clover ]  [ scrutinizer ]  [ travis

I really love the travis-ci and scrutinizer-ci combo. Between them there are not many things missing like you would find in more complex systems like Jenkins for instance. Both travis and scrutinizer are really easy to setup (just click on which github repository you want to test), setup your yaml config files and off you go: instant CI.

So for some projects I have Travis-CI deal with handling different PHP versions. This means auto-testing of your unit-test on backward compatibility breaks, and to make sure your code works on php 5.3 and 5.4, while you are developing on  version 5.5.  But much more than pass/fail of your tests you can’t get from travis.

This is where Scrutinizer comes in. This system allows you to do unit-tests as well - but less advanced as Travis - but it allows you to do much more: running tools like pdepend, phploc, mess detection etc etc. It summarizes your code into different classes, and gives you an instant overview of the actual state of your project. By combining both of these tools, you get the best of both worlds.

And they even come with the same cool tags:

  

Unfortunately you can’t control Scrutinizer they way you Travis when it comes down to setting up your environment: most projects need a composer install and this works, but adding/building php extensions or other things you might need is not really possible, as you aren’t root or don’t have any sudo rights on the Scrutinizer boxes. Travis lets you do most of these things whenever you need them.

For most of the tools running at Scrutinizer this isn’t a problem as they don’t really run your code anyway but merely analyse it. But it does pose problems when it comes to phpunit / codecoverage. And this obviously you need in order for Scrutinizer to figure out the state of your code (because code coverage is a metric for different things).

As an example, one of my projects needs the GMP math extension which isn’t installed by default. A simple “apt-get install php5-gmp” doesn’t help, as I don’t have rights on the Scrutinizer worker box, but there is a better way: since we already doing the phpunit/code-coverage at Travis, we can actually use that data in Scrutinizer as well.

So pretty much every time you want to use code coverage at Scrutinizer, and you are using Travis as well, you can do the following:

1. Setup your .scrutinizer.yml file

Remove the "php_code_coverage: true" line, and add  "external_code_coverage: true" line. Now we’re done at the scrutinizer side of things!

This means you might end up with something like this:

filter:
    paths: [lib/*]
    excluded_paths: [vendor/*, tests/*]
before_commands:
    - 'composer install --dev --prefer-source'
tools:
    external_code_coverage: true
    php_mess_detector: true
    php_code_sniffer: true
    sensiolabs_security_checker: true
    php_code_coverage: true
    php_pdepend: true
    php_loc:
        enabled: true
        excluded_dirs: [vendor, tests]
    php_cpd:
        enabled: true
        excluded_dirs: [vendor, tests]

2. Tweak your .travis.yml file so it generates a clover file

The only thing we need for code coverage is a so-called clover file. A mere data file generated during unit-testing by XDebug that holds all information concerning the code coverage. First, we need to change  phpunit and make sure it will generate such a clover file:

script: phpunit --coverage-clover=coverage.clover

All it does is add an argument to phpunit. Now a coverage.clover file will be generated whenever you run phpunit.

3. Tweak your .travis.yml file so it sends over your clover file

The final step is sending over this clover file to Scrutinizer. Again it’s a very simple change in your .travis.yml file. Just add the following:

after_script:
    - wget https://scrutinizer-ci.com/ocular.phar
    - php ocular.phar code-coverage:upload --format=php-clover coverage.clover

This will download a file from the Scrutinizer website and use that file to send over the clover file to Scrutinizer.

That’s it!

Because you told Scrutinizer you are using external code coverage, it will wait until Travis (or ANY system, as long as you generate a clover and send it over with the ocular.phar file), sends over the data, and it will automatically use this information for processing.

There are some neat tricks here as well, like specifying how long Scrutinizer must wait, adding tokens in order to send over clover files to private accounts etc, but in most cases, this is all you need to do.

Happy CI’ing!