External code coverage with travis / scrutinizer
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!